前置:这里使用的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结构。高位是栈。
<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,如需转载请自行联系原作者