Linux内核分析期末总结

pianogirl 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

总博客列表:pianogirl123

一、引子

1、Linux操作系统的缩影————mykernel

mykernel这样一个短小精悍的模拟内核,时常给我提供了看问题的角度和思路。当被庞杂的Linux内核代码弄得一头雾水时,我就去看看mykernel,很多复杂的问题就可以用简单的机制解释。

2、从mykernel出发纵观全课程

mykernel几乎串起了整个课程:
- 汇编————x86汇编基础
- 内核启动my_start_kernel()————MenuOS的启动
- fork more process————进程的创建与描述
- 如果使用fork()创建进程的话————系统调用(上)、系统调用(下)
- my_time_handler()————进程的切换与调度机制
- task[pid].thread.ip————可执行程序的装载

课本博客链接:
《Linux内核设计与实现》——第1、2章(内核简介)
《Linux内核设计与实现》——第3章(进程管理)
《Linux内核设计与实现》——第4章(进程调度)
《Linux内核设计与实现》——第5章(系统调用)
《Linux内核设计与实现》——第18章(调试)

二、要点梳理

1、函数调用框架

总结:

进入另一个函数之前,总是保存当前栈的基地址,开始一个新的栈,使每个函数有独立的栈空间,当函数返回时,能恢复到之前函数的栈空间。
结构清晰,层次鲜明,使人不得不佩服机器处理数据的严谨与清晰。

2、内核的启动

一句话启动Linux内核:
qemu -kernel (该版本的Kernel所在路径) -initrd (rootfs.img)

qemu :相当于打开一个虚拟机
kernel:启动一个内核,位置由其后的文件名指定。
initrd指令:挂了一个ramdisk虚拟硬盘,是内核的重要补充,rootfs.img就是这个虚拟硬盘,内有分区,然后启动其中的init.init是由之前编译而成,gcc -o命名为init。

道生一,一生二,二生三,三生万物:

rest_init()这个函数调用系统函数 kernel_thread() 创建 1 号进程,即 init 进程,是用户态所有进程的祖先。然后,新建 kthreadd 进程,2号进程,是内核态所有进程的祖先。最后,通过 cpu_startup_entry 函数启动 0 号进程。

3、进程的描述、创建,上下文切换,调度策略

(1)进程的描述、创建
下图为个人理解,如有不当请老师指正!
【我画的图是一般的两个进程在内存中的情况,包括各自的堆栈空间、PCB板(保存了各个进程自己的sp、ip)、数据、以及切换时SAVE_ALL保存当时寄存器所有数值的情形。】
Linux内核分析期末总结_第1张图片
上面那张我画的图是一般的两个进程在内存中的情况,但是也可以帮助我们理解系统是怎样fork一个子进程并返回到用户态的。
博客链接

(2)进程上下文切换
参照上图,可以帮助理解两个进程间是怎么切换的
博客链接

(3)调度策略
Linux针对实时进程、非实时进程采取不同的调度策略,见:
《Linux内核设计与实现》————第4章(进程调度)

4、系统调用

这张图非常清晰地描述了系统调用的层次和原理。
Linux内核分析期末总结_第2张图片
系统调用总控程序(system_call)是操作系统提供给应用程序的一个特殊接口,特殊之处在于是利用软中断陷入内核。对i386的CPU,就是执行INT 0x80中断(“系统调用”),同时将CPU切换到核心态。
进程在执行陷入前把系统调用号装入eax,接着系统调用总控程序负责将系统调用号派发到各自的服务例程,然后调用它执行。
Linux内核分析期末总结_第3张图片

三、思考与总结

1、思考

理解操作系统原理的形象化方法:和日常生活联系起来。操作系统办事情很多出发点和我们是一样的。

怎么理解中断上下文和进程上下文切换?

可以想象个场景,例如,我们工作时突然来了一个打扰(如电话),需要把手头工作进行到哪里了保存在大脑里,方便接完电话后继续回到工作状态。不论是中断上下文还是进程上下文的切换,都是基于这个原理。

怎么理解内核态和用户态?

打个比方,图书馆中,读者可以自由地检索目录、阅读书籍,却无权直接去书库取书,也无权修改图书馆的数据库。而工作人员就在特权状态,可以访问任意资源。这样的划分是为了系统的稳定和安全,也是免去了用户和系统底层打交道的麻烦。

怎么理解系统调用?

图书馆中,读者想要借书时,只能填写借书单,由工作人员完成登记和取书工作。“借书单”起到了一个“接口”的作用。在系统中运行的应用程序通过系统调用与内核通信,也是通过系统调用界面陷入内核。而“接口”是实现的关键。

2、收获

弥补了汇编和操作系统的知识盲区,加深对计算机底层的理解,见识了很多C语言中不曾接触过的高级内容(如宏、条件编译),理解了linux的思想——“提供机制,instead of策略”。

3、遗憾

只能做到宏观上理解,然而很多问题都是不求甚解的状态,尤其涉及到内核C代码,很多没见过的语法和数据结构让我很迷糊。

你可能感兴趣的:(Linux)