《Linux内核设计与实现》读书总结
Linux内核设计与实现
进程管理
进程:处于执行器的程序,包含代码段,打开的文件,信号,内核内部数据,内存地址空间,多个线程,存放全局变量的数据段
线程:进程中活动的对象队列,每次选择最左叶子。
调度器入口:选择优先级最高的调度类,进行调度。
睡眠与唤醒:运行队列,等待队列之间的相互转换。
用户抢占:发生条件,从系统调用返回用户空间时,从中断处理程序返回用户空间时。
内核抢占:中断程序正在执行,内核代码再一次具有可抢占型,内核显式调用schedule(),内核任务阻塞。
实时任务策略
SCHED_FIFO:先入先出算法,不使用时间片,可以一直执行。
SCHED_RR:带有时间片的SCHED_FIFO算法。
系统调用
内核通信
除了异常和中断外,用户进程通过系统调用与内核通信。
系统调用的优点:,无需知道磁盘以及文件系统类型;;,提供公共接口用以进程调用
调用关系:调用printf() -> c库中printf() -> c库中write() -> write()系统调用。
用户进程只需了解系统调用API功能,无需关心如何实现。
系统调用介绍
系统调用号:每个系统调用都需要一个系统调用号,通过指明调用号来执行系统调用。
应用程序通过软中断来通知内核执行系统调用:通过引发异常切换到内核态处理异常。
进入内核态后通过eax寄存器传递给内核调用号,通过其他寄存器传递参数。
系统调用实现
原则:接口简洁,参数少,越通用越好。
参数验证:检查用户指针是否有效,是否在合法用户区,是否可读可写。
权限验证:capable()检查是否可以对指定资源操作。
将系统调用函数添加到系统调用表,赋予系统调用号。
在c库中定义宏,完成设计寄存器并进入内核的操作。
用户态程序调用函数,从而产生系统调用。
中断与中断处理
中断概念
设备向内核发送信号,处理器便中断自己当前的工作转而处理中断
异常与中断不同,需要与处理器时钟同步,称之为同步中断;而硬件产生的为异步中断。
中断处理程序
在响应中断时,内核会执行特定函数,该函数为中断处理程序,是设备驱动的一部分。
中断可能随时发生,要求中断服务程序简短快速。
中断处理程序分为上下半部,上半部运行时间短,不允许被抢占。主要完成对中断的应答和复位操作;下半部分执行具体工作,可以被抢占,主要完成拷贝等耗时操作。
注册编写中断处理程序
通过request_irq()注册,通过free_irq()注销
每个中断服务程序需要占有一个中断线,可以共享也可以独占,同一个中断线的程序不能被抢占。
中断处理过程
产生中断->中断控制器->处理器->中断内核->do_IRQ()->是否有中断处理程序->运行中断服务程序->返回中断代码
中断服务程序过程:禁止中断->遍历中断线上的每一个程序,看是哪一个设备产生的中断->执行中断服务->返回
中断的下半部工作
中断的下半部概念
中断分为两个部分,一部分为上半部中断处理程序,一部分为下半部处理程序
中断处理程序不能阻塞,对时间要求高,因此有些中断操作不能全部在中断处理程序中运行,需要推迟到下半部执行
原始下半部解决方案
BH接口:静态创建的链表,只包含32个节点,执行时全局同步
任务队列:设置多个队列,根据某些情况选择某个队列执行
新的解决方案:软中断与tasklet,工作队列
软中断
软中断是下半部运行时刻的机制,是一组静态定义的下半部接口,可以在所有处理器上同时执行,即使两个类型相同也可以。
一个软中断不会抢占另一个软中断,唯一可以抢占软中断的是中断处理程序
软中断最多有32个,编译时被确定,保留给对时间要求最严格的下半部使用,例如网络和SCSI.
软中断执行时,允许相应中断,但自己不能休眠,每个处理器可以执行相同程序,数据全局共享,因此需要锁保护。
tasklet
tasklet是利用软中断实现的一种机制,与软中断几乎相同,但是可以动态创建,不允许相同的tasklet同时运行
当前的软中断被触发即被运行,但是运行过程中再被触发的软中断,则由内核进程组ksoftirqd运行。
工作队列
工作队列可以完全被推迟,交给内核线程运行,并且允许睡眠或阻塞。
工作队列通过创建工作者线程(worker thread),来完成队列中的下半部任务;默认的工作者线程为events/n,可也动态创建,接受内核调度。
应该选择哪一种机制
选择软中断:需要速度最快,而且对共享数据不敏感,只用到单处理器变量
选择tasklet:需要速度,可以多处理器并发
《Linux内核设计与实现》读书总结 来自淘豆网m.daumloan.com转载请标明出处.