Linux内核分析 第三周 构造一个简单的Linux系统MenuOS
张嘉琪 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、Linux内核源代码简介
-
计算机工作的三个法宝
1.存储程序计算机
2.中断机制
3.堆栈
-
操作系统的两把宝剑
1.中断上下文的切换——保存现场&恢复现场
2.进程上下文的切换
-
内核源代码页面
arch/x86
init
kernel
README
start_kernel (类似于main)
二、构造一个简单的Linux系统
实验指导
- 使用实验楼的虚拟机打开shell
cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img'\
- 内核启动完成后进入menu程序
- qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明: # -S freeze CPU at startup (use ’c’ to start execution) # -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项`
- 使用gdb跟踪调试内核
- 另开一个shell窗口
-
使用gdb跟踪调试内核从start_kernel到init进程启动
gdb (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表 (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 (gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
三、总结
“Linux系统启动过程”的理解,尤其是idle进程、1号进程是怎么来的。
start_kernel是内核启动的起点,存在于init目录下main.c文件中。init_kernel即手工创建的PCB,0号进程即最终的idle.不论分析内核的哪一部分都会涉及start_kernel,模块初始化时需要调用start_kernel。在start_kernel中最后一句rest_init是start_kernel从内核启动时就一直存在的0号进程,0号进程创建了1号进程和其他的内核服务线程。
在kernel_init中有一句run_init_process,init_process是1号进程,也就是第一个用户进程,它还创建了kthreadd用一个线程管理系统资源。当系统中没有进程序需要执行时就调度idle进程
也就是说一个内核启动时就存在一个0号进程,0号进程创建了1号进程,一个进程创建另一个进程和线程,一生二,二生三,三生万物,系统内核就启动了