2023-2024-1 20232816《Linux内核原理与分析》第四周作业


跟踪分析 Linux 内核的启动过程

一.实验步骤

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

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

在这里插入图片描述
2.使用 gdb 跟踪调试内核
使用以下命令启动调试内核,结果如下图所示,内核运行被冻结。

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

# 关于-s和-S选项的说明:
# 1. -S
#   -S freeze CPU at startup (use ’c’ to start execution)
# 2. -s
#   -s shorthand for -gdb tcp::1234
# 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

在这里插入图片描述
在另一个shell中启动gdb,把内核加载进来,建立连接,并在内核开始函数start_kernel处设置断点,之后按下c继续执行程序,结果如下图所示:

# 打开 GDB 调试器
$ 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

在这里插入图片描述
进行断点实现,并进行调试分析,对start_kernel中的诸多函数进行调试
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、实验细节

1.start_kernel()

main.c 中没有 main 函数,start_kernel() 相当于是C中的main函数。start_kernel是一切的起点,在此函数被调用之前内核代码是用汇编语言写的,完成系统的初始化工作,为c代码的运行设置环境。

2.init_task()
start_kernel() 函数几乎涉及到了内核的所有模块,如:trap_init()(中断向量的初始化)、mm_init()(内存管理的初始化)sched_init()(调度模块的初始化)等,首先是510行的init_task():

struct task_struct init_task = INIT_TASK(init_task);

3.rest_init()
通过rest_init()新建kernel_init、kthreadd内核线程:
在这里插入图片描述kernel_thread()是 fork 出了一个新进程来执行kernel_init 函数,而 init_task 是使用宏进行初始化的。也就是说0进程不是系统通过 kernel_thread 的方式(也就是 fork)创建的(init_task 是唯一一个没有通过 fork()产生的进程)。

三.实验总结

通过实验,我发现 Linux 的灵活性和可定制性是其强大之处。我可以根据需要选择适合的发行版和软件包,自定义内核配置,以及使用各种工具和脚本来满足特定的需求。Linux 实验使我对操作系统的工作原理和管理技巧有了更深入的理解,同时也培养了我的问题解决和学习能力,学会了利用开源资源解决问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值