Linux内核及分析 第三周 Linux内核的启动过程

实验过程:

打开shell终端,执行以下命令:

cd LinuxKernel/

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage-initrd rootfs.img


执行完毕后会弹出QEMU窗口,输出Linux内核启动信息,启动成功后显示Menuos

输入help,提示该精简的系统支持三个命令:help、version、quit

使用gdb跟踪调试内核

打开shell终端,执行以下命令:

cd LinuxKernel/

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage-initrd rootfs.img -s -S

关于-s和-S选项的说明:

-S freeze CPU at startup (use ’c’ to start execution) 在系统启动的时候冻结CPU,使用c键继续执行后续操作

-s shorthand for -gdb tcp::1234 打开远程调试端口,默认使用tcp协议1234端口,若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

打开另一个shell终端,执行以下命令:

(gdb) file home/shiyanlou/LinuxKernel/vmlinux

(gdb) target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行

(gdb) breakstart_kernel # 断点的设置可以在target remote之前,按c键继续执行到start_kernel()函数

 


输入list命令查看start_kernel()函数代码

输入以下指令:

(gdb) break rest_init   设置一个断点  

输入list命令查看rest_init()函数代码

 

分析:

Linux内核启动代码大致分2部分:

一部分是硬件平台相关的,存放在./arch/目录下,以平台区分不同目录,比如x86平台就在./arch/x86/目录下,由汇编语言编写而成。

另一部分是硬件平台无关的,由C语言编写而成。

./init/main.c中的start_kernel()函数即是Linux内核启动过程由平台相关转为平台无关代码后第一个执行的函数,在这个函数中,Linux内核开始真正进入初始化阶段。

 

实验总结:

当计算机系统加电后,BIOS代码被调用执行,然后开始调用执行Linux内核初始化代码,在平台相关的汇编代码执行完毕后会跳转到start_kernel()函数,开始真正的内核初始化,其中init_task创建了0号进程,即最终的idle进程,随后rest_init()函数创建了init进程,即1号进程,以及kthreadd进程,即2号进程,系统开始正式工作了。

 

0号进程->1号内核进程->1号用户进程(init进程)->getty进程->shell进程

注意,上述过程描述中提到:1号内核进程调用执行init并演变成1号用户态进程(init进程),这里前者是init是函数,后者是进程。

 

作者: 王雪铖

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

 

posted on 2016-03-13 15:06  20135105  阅读(312)  评论(0编辑  收藏  举报