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


1.阅读学习教材「庖丁解牛Linux 分析 」第4章
2.教材深入学习关注豆列「Linux内核及安全」。
3.学习蓝墨云班课中第四周视频「构造一个简单的Linux系统MenuOS?」,并完成实验楼上配套实验三。


一、实验楼配套实验三

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

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

输入以下代码,实现构造内核:

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

在这里插入图片描述

2、使用 gdb 跟踪调试内核

输入以下命令,得到冻结的内核。其中,-S是指得到冻结的内核,-s是指在1234这个端口上创建gdb server用于建立连接。如果不想使用1234端口,可以使用-gdb tcp:xxxx来取代-s选项。

cd ~/LinuxKernel/
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选项

在这里插入图片描述

3、另外打开一个shell窗口

根据以下代码的指引,重新打开一个shell窗口,重新进入~/LinuxKernel/路径后,进行GDB调试,建立GDB和gdbserver之间的连接。此后,设置断点start_kernel,并按c让qemu上的冻结的Linux内核继续运行。

# 打开 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附近的代码:
在这里插入图片描述

4、再多次设置断点并进行查看

根据实验,使用 gdb 跟踪调试内核从 start_kernel 到 init 进程启动,接下来再次设置断点,并在QEMU中进行查看:
设置rest_init、kernel_init断点。
在这里插入图片描述
在这里插入图片描述

5、详细分析以上过程

内核从 start_kernel 到 init 进程启动期间,主要由 init/main.c 下的 start_kernel 函数完成。start_kernel 函数完成了设置 init_task(0 号进程)栈底、初始化处理器 ID、初始化追踪对象、初始化内存分页、初始化中断向量表、初始化内存分配器、初始化进程调度器、系统时钟设置、vfs 初始化等操作,最后执行arch_call_rest_init() 调用 rest_init(),即进入1号进程init。除此之外,idle进程是一个特殊的内核线程,通常由内核启动时的start_kernel()函数初始化。其主要任务是在系统没有其他可运行进程时,保持CPU处于空闲状态,它是一个轻量级的内核线程,用于消耗CPU空闲时间,以防止CPU无用地闲置。

此外,特别需要注意的是,0号进程就是整个系统的第一个进程,它负责确保系统的正常初始化和终止。而1号进程就是init进程,是用户态的第一个进程。

start_kernel():
start_kernel()函数是Linux内核的主要入口点,它负责完成内核的初始化和启动过程。主要任务包括:
初始化内核的数据结构,如页表、中断向量表、进程管理等。设置处理器ID。初始化内存管理子系统,允许内核使用虚拟内存。初始化进程调度器。设置系统时钟。初始化文件系统。
最终,start_kernel()函数通过调用rest_init()函数,将控制权转交给用户空间的初始化进程(即init 1号进程)。

rest_init():
rest_init()函数是start_kernel()的最后一步。它的主要任务是启动用户态的初始化进程,即1号进程init进程。这个过程包括:创建init进程的内核描述符和数据结构。调用kernel_execve()函数,加载用户空间的init程序,这将切换内核的执行上下文到用户态。一旦init进程开始运行,它负责执行系统初始化、加载用户空间的系统服务、网络配置等。

二、Chatgpt帮助

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

三、小结

通过本次实验,我了解了Linux内核的启动过程,包括从内核的起始点(0号进程)到用户态的第一个进程init(1号进程)的演变。这使我们对Linux内核的初始化、硬件初始化、内存管理、中断处理以及用户态进程的启动有了更全面的认识更深入地理解了Linux内核。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值