2020-2021-1 20209301《Linux内核原理与分析》第四周作业

实验三

一、实验步骤

  1. 使用实验楼的虚拟机打开shell,内核启动完成后进入menu程序

2.用qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 先把内核启动一下,然后可以看到它被冻结起来了

3.另开一个shell窗口,使用gdb跟踪调试内核

4.用1234这个端口进行连接,这里出现了连接超时的错误,是由于qemu窗口关闭导致没连接上冻结的系统。经过改正之后连接成功,再设置start_kernel断点。

按"c"继续执行,系统开始执行,启动到start_kernel函数的位置停在断点处,"list"可以查看代码

5.单步调试
start_kernel()相当于C语言中的main函数,start_kernel是一切的起点,且不管哪一部分都会涉及到start_kernel,就从该函数进行单步调试

init_task变量相当于第一个进程的PCB

二、代码分析


rest_init()这个函数中产生了第一个用户态进程,kernel_thread(kernel_init, NULL, CLONE_FS)产生了用户态进程,此进程也是linux启动以后的第一个用户态进程。
Linux一开始启动就通过start_kernel进行初始化,然后再到其最后一个函数调用rest_init()。在rest_init中,通过init_task产生pid=0的进程,即0号进程,它是内核状态下的进程,接着调用系统函数 kernel_thread 创建 1 号进程,即 init 进程,它是第一个用户态进程用户态进程运行成功后再通过 cpu_startup_entry 函数启动 0 号进程。

三、总结

Linux下有3个特殊的进程,idle进程(PID=0), init进程(PID=1)和kthreadd(PID=2)。idle进程由系统自动创建, 运行在内核态;init进程由idle通过kernel_thread创建,在内核空间完成初始化后, 加载init程序,; kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理。

问题及解决

Q:gdb调试中命令"n"和"s"的区别
A:s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
n: 执行一行源程序代码,此行代码中的函数调用也一并执行。
s 相当于其它调试器中的“Step Into (单步跟踪进入)”;
n 相当于其它调试器中的“Step Over (单步跟踪)”。
https://zhidao.baidu.com/question/2118220379855064947.html

posted @ 2020-10-31 21:15  20209301黄宇欣  阅读(94)  评论(0编辑  收藏  举报