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

一. 跟踪Linux内核的启动过程

使用实验楼的虚拟机打开shell

    cd ~/LinuxKernel/

 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

 使用gdb跟踪调试内核

关于-s和-S选项的说明:

1.-S # -S freeze CPU at startup (use'c' to start execution)

2. -s # -s shorthand for -gdb tcp::1234, 若不想直接使用234端口,则可以使用-gdb tcp:xxxx来取代-s选项

使用qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -inittrd rootfs.img -s -S指令打开内核窗口

打开新的终端通过gdb调试内核

通过gdb指令打开gdb调试器

在gdb中输入以下指令:

  file linux-3.18.6/vmlinux    #在gdb界面中targe remote之前加载符号表

  target remote:1234     #建立gdb和gdbserver之间的连接,连接到内核的1234端口,按c 让qemu上的Linux继续运行

  break start_kernel     #在start_kernel处设置断点(断点的设置可以在target remote之前,也可以在之后)

 按c让程序继续执行后停在断点处。

 

 start_kernel()函数代码如下:

 在rest_init处设置断点并查看代码:

二. 分析Linux内核的启动过程 

start_kernel()函数在main.c中起着main函数的作用,打开系统以后,首先对硬件系统进行初始化,给C代码的运行配置好环境,start_kernel函数被调用,在start_kernel函数在开始运行后,它会调用各个内核模块的初始化函数,主要包括:trap_init()中断向量初始化,mm_init()内存管理初始化,sched_init()调度模块初始化等,在整个的初始化过程中有一个init_task,它是一个进程描述符,负责内核模块的初始化,也就是0号进程,0号进程会新建kernel_init线程(1号内核线程)和kthreadd线程(2号内核线程),初始化工作完成后,init_task()调用cpu_idle()转化为ideal空进程。

原文地址:https://www.cnblogs.com/lmmn/p/13887227.html