天天看点

linux源码分析(三)-start_kernelset_task_stack_end_magic(&init_task);smp_setup_processor_id();debug_objects_early_init();boot_init_stack_canary();

前置:这里使用的linux版本是4.8,x86体系。

start_kernel是过了引导阶段,进入到了内核启动阶段的入口。函数在init/main.c中。

这个函数是设置操作系统的第一个进程init。

这个init_task变量是怎么来的呢?从init/init_task.c中初始化的。

struct task_struct init_task = INIT_TASK(init_task);

EXPORT_SYMBOL(init_task);

而这个INIT_TASK的初始化在init/init_task.h:

再回到set_task_stack_end_magic

这个end_of_stack 在include/linux/sched.h中。它的意思是获取栈边界地址。然后把栈底地址设置为STACK_END_MAGIC。这个作为栈溢出的标记。

每个进程创建的时候,系统会为这个进程创建2个页大小的内核栈。这个内核栈底下是thread_info结构。高位是栈。

linux源码分析(三)-start_kernelset_task_stack_end_magic(&init_task);smp_setup_processor_id();debug_objects_early_init();boot_init_stack_canary();

<a href="http://blog.chinaunix.net/uid-20543672-id-2996319.html">http://blog.chinaunix.net/uid-20543672-id-2996319.html</a>

这里的STACK_END_MAGIC就是设置在thread_info结构的上面。比如如果你写了一个无限循环,导致栈使用不断增长了,那么,一旦把这个标记未修改了,就导致了栈溢出的错误。

下面是这个

smp模型指的是对称多处理模型(Symmetric Multi-Processor),与它对应的是NUMA非一致存储访问结构(Non-Uniform Memory Access)和MPP 海量并行处理结构(Massive Parallel Processing)。它们的区别分别在于,SMP指的是多个CPU之间是平等关系,共享全部总线,内存和I/O等。但是这个结构扩展性不好,往往CPU数量多了之后,很容易遇到抢占资源的问题。NUMA结构则是把CPU分模块,每个模块具有独立的内存,I/O插槽等。各个模块之间通过互联模块进行数据交互。但是这样,就表示了有的内存数据在这个CPU模块中,那么处理这个数据当然最好是选择当前的CPU模块,这样每个CPU实际上地位就不一致了。所以叫做非一致的存储访问结构。而MPP呢,则是由多个SMP服务器通过互联网方式连接起来。

支持SMP模型的CPU有AMD/AMD64。而支持NUMA的有X86等。而这里的代码,smp_setup_process_id在普通情况下是空实现,在不同的体系,比如arch/arm/kernel/setup.c, line 586

就有对应的逻辑了。

这个函数的实际代码在lib/debugobject.c

可以看到,它主要是用来对obj_hash,obj_static_pool这两个全局变量进行初始化设置。这两个全局变量在进行调试的时候会使用到。

<a href="http://m.blog.chinaunix.net/uid-27717694-id-4425488.html">http://m.blog.chinaunix.net/uid-27717694-id-4425488.html</a>

那么,和前面的end_magic逻辑一样,我们在堆和栈的中介处设置一个标记位(叫做canary word)。当这个位被修改的时候,我们就知道了,这个时候存在堆栈溢出,就进行错误处理。

本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/p/5999532.html,如需转载请自行联系原作者

继续阅读