要跟踪调试内核,首先需要对内核架构有一个基本的了解,以linux-3.18.6为例:
- arch文件夹:Linux需要兼容不同的架构,因此该文件夹下面包含arm、x86、alpha等支持各种机构的源码。
- init文件夹:包含mian.c ,程序入口:start_kernel,任何模块的初始化都需要在strart_kernel中调用。
- 还有ipc,kernel,security.sound等比较重要的文件夹
- readme文件包含内核详细的安装过程
start_kernel分析:
- trap_init();//涉及中断的内容,设置了很多硬件中断门,其中有一个系统中断门: set_system_trap_gate(SYSCALL_VECTOR, &system_call);//系统调用
- mm_init()://内存管理模块
- sched_init();//调度模块
- rest_init();//内核进程,里面有kernel_thread(kernel_init, NULL, CLONE_FS);
kernel_init函数中有run_init_process,init_process为linux系统中的第1号进程。
system_idle(0号进程)系统进程中一直存在。0号进程创建了1号进程。同时创建了其它一些内核服务线程。
GDB调试过程:
- 冻结MENUOS
输入:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
-S 冻结munuos的 CPU,“c(continue)”继续运行
-s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项 - 横向分割shell窗口,进入GDB,导入镜像文件 vmlinux
输入:
gdb
file linux-3.18.6/ vmlinux - 建立gdb和gdbserver之间的连接
输入:target remote :1234 - 设置断点
输入:break start_kernel - 开始调试
输入:c
实验截图如下:
冻结menuos
GDB调试
断点设置