2020-2021-1 20209328 《Linux内核原理与分析》第四周作业
1.实验目的
围绕Linux内核的启动过程,即从start_kernel到init进程启动。
仔细分析start_kernel函数的执行过程。
阐明自己对“Linux系统启动过程”的理解,尤其是idle进程、1号进程是怎么来的。
2.实验内容
$跟踪分析Linux内核的启动过程
先构造一个简单的Linux内核:
cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
使用gdb跟踪调试内核:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
-S CPU初始化之前冻结起来
-s 在1234端口上创建一个gdb-server
在另一个shell窗口中进行调试:
打开 GDB 调试器
# 在 GDB 中输入以下命令:
# 在gdb界面中targe remote之前加载符号表
(gdb)file linux-3.18.6/vmlinux
# 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)target remote:1234
# 断点的设置可以在target remote之前,也可以在之后
(gdb)break start_kernel
逐条分析star_kernel函数
最后实际进入reset_init()函数,包括所有剩下的硬件驱动,线程初始化等过程…这也最终完成start_kernel的启动过程。
接下来在rest_init处设置断点
b rest_init
1:rest_init()函数分析
(1)rest_init中调用kernel_thread函数启动了2个内核线程,分别是:kernel_init和kthreadd
(2)调用schedule函数开启了内核的调度系统,从此linux系统开始转起来了。
(3)rest_init最终调用cpu_idle函数结束了整个内核的启动。也就是说linux内核最终结束了一个函数cpu_idle。这个函数里面肯定是死循环。
(4)简单来说,linux内核最终的状态是:有事干的时候去执行有意义的工作(执行各个进程任务),实在没活干的时候就去死循环(实际上死循环也可以看成是一个任务)。
(5)之前已经启动了内核调度系统,调度系统会负责考评系统中所有的进程,这些进程里面只有有哪个需要被运行,调度系统就会终止cpu_idle死循环进程(空闲进程)转而去执行有意义的干活的进程。这样操作系统就转起来了。
3.实验总结
1)操作系统是用一个数字来表示/记录一个进程/线程的,这个数字就被称为这个进程的进程号。这个号码是从0开始分配的。因此这里涉及到的三个进程分别是linux系统的进程0、进程1、进程2.
进程0:进程0其实就是刚才讲过的idle进程,叫空闲进程,也就是死循环。
进程1:kernel_init函数就是进程1,这个进程被称为init进程。
进程2:kthreadd函数就是进程2,这个进程是linux内核的守护进程。它的作用是管理调度其他内核进程这个进程是用来保证linux内核自己本身能正常工作的。