STEP1:在自己的linux系统中搭建实验环境。
1.下载linux-3.18.6的内核源码,并且编译
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> cd ~/LinuxKernel/ wget https://www<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.kernel</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.org</span>/pub/linux/kernel/v3<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.x</span>/linux-<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span><span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">.6</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.tar</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.xz</span> xz -d linux-<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span><span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">.6</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.tar</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.xz</span> tar -xvf linux-<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span><span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">.6</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.tar</span> cd linux-<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span><span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">.6</span> make i386_defconfig make <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;"># 一般要编译很长时间,少则20分钟多则数小时</span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li></ul>
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> cd ~/LinuxKernel/ mkdir rootfs git clone https://github<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.com</span>/mengning/menu<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.git</span> cd menu gcc -o init linktable<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.c</span> menu<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.c</span> test<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.c</span> -m32 -static –lpthread cd ../rootfs <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">cp</span> ../menu/init ./ find . | cpio -o -Hnewc |gzip -<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">9</span> > ../rootfs<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.img</span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li></ul>
3.启动MenuOS
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> cd ~/LinuxKernel<span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">/</span> qemu <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">-kernel</span> linux<span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">-</span><span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span><span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">.6</span>/arch/x86/boot/bzImage <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">-initrd</span> rootfs<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>img</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li></ul>
然后就启动了MenuOS。
STEP2:使用GDB调试内核跟踪启动过程。
在使用gdb跟踪调试内核之前需要先重新配置编译Linux使其携带调试信息。
由于make menuconfig需要ncurses-dev和tk4-dev库。
所以我们先输入命令sudo apt-get install ncurses-dev
和sudo apt-get install tk4-dev
然后输入make menuconfig进入Kernel Configuration界面
选择Kernel hacking进入
选择Compile-time checks and compilr options —>进入
按Y选择Compile the kernel with debug info
然后执行make重新编译内核。
编译完成之后输入以下的命令,让CPU冻结在开始的时候。
<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">qemu -kernel linux-<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span>.<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">6</span>/arch/x86/boot/bzImage -initrd rootfs.img <span class="hljs-operator" style="margin: 0px; padding: 0px; box-sizing: border-box;">-s</span> -S <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"># 关于-s和-S选项的说明:</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"># -S freeze CPU at startup (use ’c’ to start execution)</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"># -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项</span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li></ul>
然后打开GDB远程调试,另外开启一个终端
输入gdb
<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">(gdb)file linux-<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3.18</span>.<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">6</span>/vmlinux <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"># 在gdb界面中targe remote之前加载符号表</span> (gdb)target remote:<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1234</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"># 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行</span> (gdb)<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">break</span> start_kernel <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"># 断点的设置可以在target remote之前,也可以在之后</span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li></ul>
在start_kernel设上断点然后
(gdb)c 继续执行到达断点处
输出(gdb)list显示出上下文
我们继续设置断点, break rest_init()
然后输入c执行到断点处
然后输入list显示出上下文。
STEP3:分析start_kernel的代码
内核几乎所有模块的初始化都会经过start_kernel来进行,
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">asmlinkage __visible <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">void</span> __init start_kernel(<span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">void</span>) { <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">...</span><span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">...</span><span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/*init_task即手工创建的PCB,0号进程就是最终的idle进程*/</span> set_task_stack_end_magic(<span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">&</span>init_task); <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">...</span><span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">...</span><span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">..</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/*初始化中断向量*/</span> trap_init(); <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/*内存管理模块初始化*/</span> mm_init(); <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/*调度模块初始化*/</span> sched_init(); <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box;">...</span><span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/*其他初始化*/</span> rest_init() }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li></ul>
我们再来看下最后的rest_init()
<code class="hljs applescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">/*rest_init()会一直存在,是<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>号进程,并且创建了<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1</span>号进程,并创建了一些其他的服务进程*/ static noinline void __init_refok rest_init(void) { int pid; rcu_scheduler_starting(); /* * We need <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">to</span> spawn init <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">first</span> so <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">that</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">it</span> obtains pid <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, however * <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">the</span> init task will <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">end</span> up wanting <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">to</span> create kthreads, which, <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> * we schedule <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">it</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">before</span> we create kthreadd, will OOPS. */ /*初始化了第一个用户态的进程<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1</span>号进程*/ kernel_thread(kernel_init, NULL, CLONE_FS); numa_default_policy(); /*创建内核线程管理系统资源*/ pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); rcu_read_lock(); kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); rcu_read_unlock(); complete(&kthreadd_done); /* * The boot idle thread must execute schedule() * <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">at</span> least once <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">to</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">get</span> things moving: */ init_idle_bootup_task(current); schedule_preempt_disabled(); /* Call <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">into</span> cpu_idle <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">with</span> preempt disabled */ /*执行cpu_idle_loop, cpu_idle_loop是一个<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)循环,当系统没有任何需要执行的进程的时候就调度到idle进程*/ cpu_startup_entry(CPUHP_ONLINE); }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">27</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">28</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">29</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">30</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">31</li></ul>
由此可见,rest_init()最后执行cpu_startup_entry();cpu_startup_entry会调用cpu_idle_loop(), 在cpu_idle_loop()里面有个while(1)的循环一直执行,作为idle进程,pid是0号,此进程会一直执行下去,并且在系统没有任何需要执行的进程时,调度到此进程。
Linux内核的启动在宏观上来看,就是start_kernel()来进行各种初始化工作,最终执行到rest_init()来初始化0号进程和1号用户态的进程。然后操作系统就运行起来了。