总结下读过的有关Kernel的书籍,主要是<Understanding the Linux Kernel>>、<Linux Kernel Development>、<Linux Device Drivers>
终极目标
完整的回答以下问题:
- 从开机上电到进入命令提示行,Linux完整的启动过程
- Linux终端下敲入
ls
的完整过程。(从接收键盘设备中断到显示到结果显示到屏幕) - Linux终端下输入
cat foo.txt
的完整过程。(同上,其中包含了读写磁盘的操作) - to be continued…
内核态/用户态
Intel x86有4种不同的状态,Unix内核只使用内核态和用户态。
内核线程:
- 内核态在内核地址空间执行
- 不与用户直接交互,无须终端设备
- 通常在系统启动时创建,一直活跃直到系统关闭
陷入内核态的几种方式:
- 用户态进程调用
syscall
系统调用 - 遇到
Exception
(无效指令、越界访问、除数为0等):内核会代表进程处理异常 - 外设向CPU发出
interrupt
- 执行内核线程
进程实现
当进程暂停时,将表征进程状态的寄存器保存到进程描述符中,其中包括:程序计数器、栈指针寄存器、通用寄存器、CPU状态信息的控制寄存器(处理器状态字)以及内存管理寄存器。当需要恢复进程执行时,再将保存的字段恢复即可。
可重入内核
可重入内核可以包含非可重入代码,需要利用锁机制。
Kernel Control Path 内核控制路径表示内核态中内核进行的任务类型:处理syscall、异常、中断处理程序。
内核控制路径可以交错执行。
进程地址空间
每个进程有“私有”的地址空间,用户态下:私有栈、数据区、代码区;内核态:内核的数据区和代码区、进程内核栈
在进程的角度上每个进程都是独立的地址空间,但是内核管理上未必是独立的,有可能是共享。
同步和临界区
利用同步机制防止多个内核控制路径破坏全局的内核数据结构。
- 非抢占式内核
- 禁止中断
- 信号量
- 自旋锁
- 避免死锁:Linux通过按规定的顺序请求信号量避免死锁。
信号和IPC
信号机制将系统事件报告给进程的机制。系统事件分为两种:异步通告(SIGINT),同步错误或异常。
进程间通信的机制:信号量、信息队列、共享内存;标准有两种:System V IPC和POSIX
进程管理
fork
exec
_exit
wait4
- zombie进程
- process group
- login session
内存管理
虚拟内存
虚拟内存(virtual memory) 作为一种逻辑层,处于应用程序的内存请求与MMU(Memory Management Unit,硬件内存管理单元)之间。
RAM的使用
RAM中有一部分存放内核映像部分(内核代码和内核数据结构)。其余部分有三种不同的作用:
- 内核使用
- 进程使用
- 磁盘和其他设备的高速缓存
KMA: Kernel Memory Allocator
KMA内核内存分配器子系统用来处理所有的内存请求,其中包括内核内其他子系统、用户进程通过syscall请求增加内存使用的请求。
KMA的特点:
- 快
- 省,浪费最少
- 尽量无碎片
- 可以同其他内存管理子系统合作
进程虚拟地址空间处理
尽可能的“懒”的做法 :必要时才做耗时的工作(COW和demand paging策略),如果必须要做耗时的工作就多做些(预读取机制)
- demand paging内存分配策略:进程可在页没有载入主存下执行,当访问到不存在的页时,发生缺页中断,之后中断处理程序将页载入到内存。
- COW写时复制策略
高速缓存
- 推迟写回磁盘的操作
sync
调用