读阿里-操作系统内核开发实战总结
Fri ,Jun 26 ,2020资料来源是之前北邮人论坛下载的ppt.
是由伯松(阿里集团)和王智通(阿里云)做的整理的内部分享。
如作者所言,学习者需要关注的是概念,具体的实现有很多种。因此整理这篇博客,在ppt的基础上再做一些个人层面的总结。
1.内核加载
在一台已经关机的电脑前,我们拥有什么?
a.硬盘,存储着操作系统的内核程序。
b.cpu及寄存器。
c.内存。
概念1:去哪里找内核程序。
bootloader如linux grub去硬盘约定好的地方去读(印象里是第一个分区的第一个扇区?)。
#问题1.去哪里找第一个内核函数?
linux boot protocol. 提前约定好格式或者说是协议。
概念2:内核的第一个c函数调用前的必要条件。
cpu与寄存器的状态,基本内存布局。满足c语言条件即可。
一旦进入c语言,则整个进入了代码可视可控阶段。
2.保护模式基础
内核设计中需要考虑的几个概念:
1.权限控制。2.寻址方式。3.中断处理。4.进程调度。
概念1:权限控制主要是在寻址的时候做。
页表的bit2 U/S标志位。1是user. 0是sup.
一个程序的地址空间分为两个部分:用户态与内核态。
概念2:页表的生成:
内核的页表在加载内核时已经完成。
用户态的程序在启动时,依赖一些系统调用构建自己的页表。
概念3:线性地址,物理地址。
依靠cr3寄存器,保留着页表自身的位置。
假设一个线性地址:
31--------22 21------12 11-------0
pde pte offset
概念4:中断/异常。
中断:外部硬件或者软件INT n(软中断?)。
异常:执行过程中探测到错误的指令。
概念5: 中断响应的流程。
“好好的吃着火锅,唱着歌,夯的来了一个中断!”
主要是上下文切换。一部分是cpu在中断时存储/恢复,一部分是中断程序来存储恢复。
两种情况:
1.中断时处于用户态:代码段寄存器,栈指针得留着(SS,ESP)。
另外要进入内核态,用户栈的地址与状态也得留着(EFLAGS/CS/EIP/error Code)。
2.中断时处于内核态:只需要栈切换(EFLAGS/CS/EIP/error Code)
因为中断时,已经保存好了前一个程序的状态,所以中断回来之后,可以发生进程调度。
概念6:进程调度。
1.地址空间:基于页表的寻址保护方式,所以要切回自己的页表。
2.栈:当时执行到哪里停了,接下来继续执行,当时的状态是什么。寄存器+栈就ok了。
问题:内核栈能否单个核只有一个?
挂在单个程序上的话,就意味着在内核态,这个程序的事情也可以被抢占。
可以参考golang单个p的g0栈。
3.系统调用
概念1:消息传递机制
linux:EAX寄存器为系统调用号
MLXOS: 整个封装成消息体,包含:系统调用号,参数格式,接收者。
概念2:系统调用的过程梳理:
1.按照接口定义将参数准备好。寄存器/栈的分布等
2.调用中断命令。
3.代码段由中断门转换。数据段:先是把当前程序的寄存器等数据入栈,然后切换数据段为内核数据段。
4.内核执行操作。
5.反馈执行的结果。
6.返给用户层。
用户的上下文到底存在哪里: 该程序的内核栈中。
是不是可以这样理解:除了正在用户态运行的程序,
其他的进程都是处在内核的空间内,且内核栈上有自己的上下文。
golang的goroutie我理解状态是存储在本身的栈上,切换时确实时用的g0栈。
用户态调用某一个func:
function(para1) {
准备好系统调用的参数
保留现场(各种入栈)
执行内核的systemcall
解析内核的返回值,如果需要的话。
恢复现场
调用调度程序。(有可能继续执行该程序,也有可能不再执行)
}
4.进程调度
概念1:程序链接与地址分布
形同内核的形式,本质上就是一个定义/协议。ELF。
概念2:进程加载与创建。
硬盘上的代码与内核中的进程数据结构的区别。
解析elf文件:
进程管理数据结构:task_struct.
地址空间管理数据结构 mm_struct.
初始化用户态栈空间。-> 创建一段合法的虚拟地址空间(4KB)+页表注册。
根据程序中每一个程序段,初始化mm_struct。
准备启动的数据结构。
注册到内核进程表。
概念3:进程退出
从内核中创建,从内核中消亡。
概念4:进程切换
重要是两个部分:地址空间切换与栈的切换。
不同程序内核的地址空间是相同的,所以放心的切用户态cr3页目录表。
TLB中非全局项被刷新。
概念5:休眠与唤醒
从执行队列中将这个进程拿出来,就是休眠。放回去就是唤醒。
依赖数据本身做传递。
1.比如等待某信号为空,让它休眠。之后把信号置位,再让它恢复,它得类似for循环这种。
2.类似函数调用一样。调用了某个函数,需要一个返回值位置,执行的下一条语句地址。把返回值放回去,继续执行就好了。
5.物理内存管理
buddy算法与slab算法。
6.虚拟内存管理
概念1:虚拟内存是在做什么?
内存映射 (mmap)
堆管理 (heap)
栈管理 (stack)
按需分配内存 (pagefault)
地址空间保护(#PF/#GP)
页交换 (swapping)
页缓存 (paging)
概念2: 文件映射与匿名映射
文件映射:磁盘文件–pagecache –进程地址空间 匿名映射:page frame–进程地址空间。
概念3: TLB
转换旁视缓冲。(Translate Lookaside Buffer)