此笔记来源于赵炯先生编著的《Linux内核注释》一书
*注:
早期的内核0.11版本,包括以下几个文件:
bootimage.Z -具有美国键盘代码的压缩启动映像文件
rootimage.Z -以1200kb压缩的根文件系统映像文件
linux-0.11.tar.Z -内核源代码文件
as86.tar.Z -linux bruce evans 二进制执行文件,是16位的汇编程序和装入程序
ISTALL-0.11 -更新过的安装信息文件*
Linux内核模式和体系结构
一个完整可用的操作系统主要由四个部分组成:硬件、操作系统内核、操作系统服务和用户应用程序。
目前操作系统内核的结构模式分为整体式的单内核和层次式的微内核,0.11采用了单内核。单内核代码结构紧凑、执行速度快但是层次结构性不强。
单内核模式的内核粗略的分为三层:
1)调用服务的主程序层
2)执行系统调用的服务层
3)支持系统调用的底层函数
在单内核模式中操作系统提供服务的流程为:应用主程序调用指定参数,使cpu从用户态(user mode)切换到核心态(kernal mode);然后系统根据参数调用不同的服务程序;服务程序再调用底层函数完成特定功能;服务结束后,cpu从核心态转化为用户态。
Linux内核主要由五个模块组成:
进程调度
进程间通信
内存管理
文件系统
网络接口
值得注意的是所有模块都与进程调度模块有关,因为它们都需要依靠进程调度程序来挂起或是重启它们的进程。各个模块之间的依赖关系是未来对于内核代码阅读的重要理论依据。
Linux中断机制
对于Linux内核来说,中断分为两种:硬件中断和软件中断(异常)
每个中断都是由0-255之间的一个数字来标示。Int32~int255(0x20~0xff)可由用户自己定义;而int0~int31(0x00~0x1f)则是由Intel公司已经定义好或是预留使用的,一般情况下cpu在检测到异常的时候会使用这些中断,所以这些软件中断又被称之为异常。
Linux系统将int32~int47(0x20~0x2f)对应于8259A发出的中断请求信号IRQ0~IRQ15
Linux系统将程序编程发出的系统调用(system_call)中断设置为int128(0x80)。
Linux系统定时
在Linux0.11中,8253芯片被设置为每隔10ms就发出一个时钟中断(IRQ0)信号,这个时间节拍被称之为系统滴答
每经过一个系统滴答就会调用一次时钟中断处理函数(time_interrupt),该函数主要用来累计自系统启动以来的滴答数,每发生一次时钟中断,jiffies变量+1。然后从被中断程序的段选择符中选择当前特权级CPL作为参数调用do_timer函数。do_timer函数会对当前进程运行时间作累计,并且确保运行在内核态的程序(CPL=0)不会被抢占,用户态运行的程序可以被抢占。
补充:
Linux系统的特权级有三种:CPL、DPL、RPL总的来说,CPL代表当前代码段的权限,如果它想要去访问一个段或门,首先要看看对方的权限如何,也就是检查对方的DPL,如果满足当前的权限比要访问的权限高,则有可能允许去访问,有些情况我们还要检查选择子的权限,即RPL,因为我们通过选择子偏移量的方式去访问一个段,这算是一个访问请求动作,因此称为请求访问权限RPL(Requst Privilege Level)。当请求权限也满足条件,那么访问就被允许了。
CPL是当前执行的任务的特权等级。通常情况下,CPL等于代码所在段的特权等级,当程序转移到不同的代码段时,处理器将改变CPL。
DPL(Descriptor Privilege Level)表示门或者段的特权级
RPL(Rquest Privilege Level)是通过选择子的低两位来表现出来的(这么说来,CS和SS也是存放选择子的,同时CPL存放在CS和SS的低两位上,那么对CS和SS来说,选择子的RPL=当前段的CPL)。
处理器通过检查RPL和CPL来确认一个访问是否合法。即提出访问的段除了有足够的特权级CPL,如果RPL不够也是不行的(有些情况会忽略RPL检查)