第一部分
使用自己的Linux系统环境搭建MenuOS,启动MenuOS
cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
图1 搭建好的MenuOs
第二部分
使用GDB调试内核跟踪启动过程
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)
# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
图2 dgb跟踪调试1
图3 dgb跟踪调试2
图4 dgb跟踪调试3
第三部分
asmlinkage __visible void __init start_kernel(void)
{
.......
set_task_stack_end_magic(&init_task);
/*init_task即手工创建的PCB,0号进程就是最终的idle进程*/
........
trap_init();
/*初始化各种中断*/
mm_init();
/*内存管理模块初始化*/
sched_init();
/*调度模块初始化*/
rest_init()
/*其他初始化*/
}
总结:不管分析内核的哪一部分都会涉及到start_kernel,许多模块的初始化都要调用其中的init。当系统没有进程需要执行时就调用idle进程。简单来看,内核一启动,rest_init是一直存在的0号进程,0号进程又创建了1号进程kernel_init,后面再启动其他服务进程,整个系统就启动来了。
小市民 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000