跟踪分析 Linux 内核的启动过程
一、构造一个简单的Linux系统MenuOS
使用实验楼的虚拟机打开 shell,执行该命令 执行后如图所示
二、使用gdb跟踪调试Linux内核的方法
1、使用 gdb 跟踪调试内核
执行以下指令
$ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
关于-s和-S选项的说明:
- -S
-S freeze CPU at startup (use ’c’ to start execution) - -s
-s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
执行后结果如上图所示
2、另开一个 shell 窗口,设置断点
另开一个shell窗口,执行以下指令:
打开 GDB 调试器
$ gdb
(gdb)file linux-3.18.6/vmlinux
(gdb)target remote:1234
(gdb)break start_kernel
按c系统开始执行到断点处暂停,如图所示: 此时执行到start_kernel的位置。 使用list命令,可以看到start_kernel上下的代码: 在rest_init处设置断点,如图所示: 用list来看代码:
三、简单分析 start_kernel 函数的执行过程
start_kernel里的main.c :内核启动的起点 start_kernel里的init_task变量:在这进行初始 init_task():几乎涵盖了内核的所有主要模块 sched_init():初始化调度模块 build_all_zonelists():初始化内存管理 page_alloc_init():初始化伙伴系统分配程序 trap_init():初始化中断向量 mm_init():初始化内存管理模块 rest_init():启动1号进程 call_cpu_idle:当系统没有进程需要执行的时候就调用idle进程
四、总结和问题
mian.c中没有main函数,start_kernel()相当于c语言中的main函数,start_kernel是一切的起点,在此函数被调用前,内核代码主要是用汇编语言写的,用于完成硬件系统的初始化工作,为c代码的运行设置环境。 start_kernel几乎涉及了内核的所有主要模块,如trap_init(),mm_init()等。
|