跟踪分析内核的启动过程实验
张潇月《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
这周主要学习的是对内核启动的跟踪和分析。本次实验先是构建了一个简单的Linux系统——MenuOS。
启动内核:
其中用到的代码是
cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
进入一开始设置好的环境LinuxKernel,输入命令如同qemu -kernel文件名 -initrd rootfs.img
跟踪部分:
进入了MenuOS后,在上一条命令的基础上添加-S -s启动内核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
其中-s是在gdb窗口上创建端口1234;-S是frezze CPU at startup。
另外打开一个窗口
cd LinuxKernel
gdb
(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之前,也可以在之后 (gdb)list # 可以看到start_kernel上下的代码 (gdb)break rest_init (gdb)c # 当前系统执行到rest_init (gdb)list # 可以看到rest_init是在start_kernel的尾部调用的。
两把宝剑:中断和进程的上下文切换;
arch/x86目录下的代码是我们重点关注的;
内核启动相关的代码基本都在init目录下;
start_kernel函数相当于普通c程序中的main函数;
ipc是进程间通信的一些东西;
Linux内核的核心代码在kernel目录中。
内核启动的起点init/start_kernel;
全局变量init_task即手工创建的PCB,0号进程就是最终的idle进程;
不管内核分析的哪一部分都会涉及到start_kernel;
所有模块初始化都是通过调用init/start_kernel里的进程模块;
trap_init()是中断模块;mm_init()是内存管理模块;sched_init()是调度模块;
init process是1进程;一直存在的进程是0号进程。