2019-2020-1 20199318《Linux内核原理与分析》第四周作业
第3章 MenuOS的构造
一、学习笔记
1. 操作系统的“两把宝剑”:中断上下文、进程上下文。
2. 自2003年12月,Linux内核的版本号按照A.B.C.D的方式命名。
A和B变得无关紧要,C是内核的真是版本。D是安全补丁和bug修复。
3. Linux内核源码的关键目录:
arch:arch目录中的代码可以使Linux内核支持不同的CPU和体系结构。
block:存放Linux存储体系中关于块设备管理的代码。
crypto:存放常见的加密算法的C语言代码,譬如crc32、md5、sha1等。
Documentation:存放一些文档。
drivers:驱动目录,里面分门类地存放了Linux支持内核的所有硬件设备的驱动源代码。
firmware:固件
fs:文件系统,里面列出了Linux支持的各种文件系统的实现。
include:头文件目录,存放公共的(各种CPU体系结构公用的)头文件。比如ARM架构特有的一些头文件在arch/arm/include目录及其子目录下。
init:init是初始化的意思,存放Linux内核启动时的初始化代码。
其中一个关键目录是init目录,内核启动相关的代码都在这个目录下。在init目录下有main.c源文件。
二、试验记录
1.构造一个简单的Linux内核
- 注意:qemu需要创建窗口,他在纯命令系统下无法工作,需要使用图形化界面的虚拟机。
- qemu仿真kernel;bzImage是vmLinux经过gzip压缩后的文件,是压缩的内核映像,“b”代表的是“big”(bzImage适用于大内核,zImage适用于小内核)。vmLinux是编译出来的最原始的内核ELF文件。intrid是“initial ramdisk”的简写。
2.跟踪调试Linux内核的启动过程
- 在start_kernel处设置断点,刚才是stop状态,如果按“c“继续执行,那么系统开始启动执行,启动到start_kernel函数的位置停在断点处。
- 再设置一个断点rest_init,继续执行,停在断点处。可以看到rest_init是在start_kernel的尾部进行调用的。
3.分析一些关键函数。
- start_kernel()
main.c中没有main函数,start_kernel()相当于C语言中的main函数。start_kernel是一切的起点,在此函数被调用之前,内核代码主要是用汇编语言编写的,用于完成硬件系统的初始化工作,为C代码的运行设置环境。
总结
- init_task()在创建了init进程后,调用cpu_idle()演变成了idle进程,执行一次调度后,init进程运行。1号内核线程负责执行内核的部分初始化工作及运行系统配置,最后调用do_execve加载init程序,演变成init进程,init进程是内核启动的第一个用户态进程。kthreadd进程由0号进程创建,始终运行在内核空间,负责所有内核线程的调度和管理。