Linux内核体系结构--Linux内核完全注释读书笔记

Linux中断机制

8259A可编程中断控制芯片可以通过级联方式,能构成最多管理64个中断向量的系统。但我们一般的就只需要两片级联起来就可以了,那也就是可管理15级的中断向量。但中断向量表可以有256个中断向量。两者不是一回事,要分清

1.        8259A的主片端口基地址是OX20,范围是0x 20~~0x 3F,从片是0xAO,范围是0x A0~~0x BF

2.        中断信号分两类:硬件中断和软件中断。其中软件中断也称为异常。因为这些软件中断是在CPU执行指令时候探测到异常情况而引起的。软件中断还可分为故障(fault)和陷阱(traps)两类.

3.        中断向量表中断分布:

Int0~~int31:软件中断,由intel公司设定和保留

Int32~~int255:可由用户自己设定。其中,在linux系统中,则将Int32~~int47对应于8259A中断控制芯片发生的硬件中断请求信号IRQ0~~IRQ15,并把程序发生的系统调用(system_call)中断设置为int128。这些最好记住了。

Linux系统定时

1.        Intel8253被设置成每隔10ms就发出以个时钟中断信号,这就有如我们系统运行得脉搏,我们称它为一个系统嘀嗒。再形象点说,就是每10ms我们的心脏就跳动一下,脉搏当然是跟着心脏同步的了。因此,我们的系统就每经过一个嘀嗒就会调用一次系统时钟中断处理程序。

2.        do_timer()函数。

第一,此函数会根据特权级对当前进程运行时间(不是指进程分到的时间片)累加统计。作累加的时候它也会分内核态和用户态,有区别的。

第二,除了做累加操作外,系统还会处理定时的问题。若程序曾经添加过定时器,那么do_timer()就会对定时器链表进行处理。如果某个定时器时间到(递减后等于0),则调用该定时器的处理函数。

第三,对当前进程运行时间片进行处理,把当前进程的运行时间片1。如果当前时间片还大于0,表示该进程时间片还没用完,于是就退出do_timer()继续运行原来的当前进程。如果该时间片已经经过刚才的递减变为0了的话,表示该进程已经用完了此次使用CPU的时间片了,于是进程就会根据被中断进程的级别(是否是特权级别?)来确定进一步处理的方法。若被中断的当前进程是工作在用户态的(特权级别大于0),则do_timer()就会调用调度程序schedule()切换到其它进程去运行。如果被中断的当前进程工作在内核态,也即在内核程序中运行时被中断,则do_timer()会立刻退出。因此这样的处理方式决定了Linux系统在内核态运行时不会被调度程序切换。内核态程序是不可抢占的,但当处于用户态程序中运行时则是可以被抢占的。

3.        引申问题:

1)        2中的第二中有一句:如果程序添加过定时器,则对定时器链表进行处理。达人回答:这里的定时器不是用户的定时器,如编程用了函数alarm() & setitimer()等,它是很特别的。“这个定时器链表时内核专用的,主要供软盘操作定时关闭马达或启动马达使用,因此所调用的函数在内核中并且控制编制的很短”。否则你想想,要是你自己设定的定时器处理函数很久,那下面的检查时间片有没有用完操作不是有有很大毛病了嘛!这个问题在http://oldlinux.org问有人已经提过,新版本的书应该已经更正

2)        听说linux的调度机制是non-preemptive的。我也看到在您的书中第22页提到“在内核态下运行的进程不能被其它进程抢占。”因此我觉得很迷惑,难道一个低优先级的进程不能被高优先级的进程剥夺么?并且在第79页看到您写道“当时钟中断过程判断出它运行的时间片已被用完时,就会在do_timer()中执行进程切换操作,该进程的CPU 使用权就会被不情愿地剥夺,让给别的进程使用。”我理解这里的别的进程应该就是高优先级并且就绪的进程。那么可以认为在时间片到达的时候高优先级的进程就会剥夺低优先级的进程。(页数在第一版中不同)。另外中断处理结束的时候好象也进行了一次调度,这时候如果有高优先级的任务就绪,那么被中断的低优先级任务不是就被剥夺了么。

答:在内核态执行时不会被时钟中断过程强制切换掉,因为在时钟中断过程中有对是否运行在核心态的判断语句。至于在一个进程时间片用完后切换到什么进程,这完全由调度程序的算法设定。在本内核的调度程序中,schedule()会比较每个处于就绪状态任务的counter(时间片值)值,哪一个大,运行时间还不长,就基本选定切换到哪个任务。若所有时间片都为0(或相等?)就根据每个任务的优先权值更新每个任务的counter值,然后对所有任务重新比较。

可以看出这个内核中选择切换目标是首先根据时间片值,再根据优先权值。因此只是在大家都处于同一起跑线上时才根据优先权值选择下一个将要执行的任务,不存在高优先级进程剥夺低优先级任务运行的情况。

在中断处理结束时也是调用这个schedule(),因此处理过程完全一样。

上面的总结我还认为是有些错误的,代码具体没去看,代码看起来会比较花时间。快考试,等考试后,会吧代码看得比较系统,毕竟喜欢这个。

你可能感兴趣的:(Linux内核体系结构--Linux内核完全注释读书笔记)