【Linux 0.12】Linux内核体系结构——Linux的内核管理

Linux内核体系结构

中断机制

中断操作原理

外设向处理器提出服务请求时,处理器会在执行完一条指令后立刻应答设备请求,转而执行该设备的相关服务程序。服务程序执行完成后,处理器会接着做之前被中断的请求。

设备向处理器发出的服务请求称为 中断请求 IRQ,处理器相应请求而执行的设备相关程序则被称为中断服务程序,或者终端服务过程 ISR(Interrupt Service Routine)。

可编程中断控制器(Programmable Interrrupt COntroller, PIC)时微机系统中管理设备中断请求的管理者。它通过连接到设备的中断请求引脚接受设备发出的中断服务请求信号。

以上是硬件中断,但终端方法并非必须和硬件相关。软件使用 int 指令,也可以让处理器执行相应的中断处理过程。

中断向量表

CPU 根据中断号获取中断向量值(即中断服务程序的入口地址)。为了让 CPU 由中断号找到对应的中断向量,就需要在内存中建立一张查询表,即中断向量表。

在实模式下,每个中断向量 4Byte,指明中断服务程序的段值,以及段内偏移。由于共 256 个向量,所以中断向量表位 1KB。x86机器启动时,ROM BIOS 中的程序会在物理内存的起始地址初始化并设置中断向量表,而各中断的默认中断服务程序则在 BIOS 中给出。由于中断向量表中的向量是按照中断号顺序排列,因此给定一个中断号 N ,他对应的中断向量在内存的位置就是 0x0000:N*4。

在保护模式下,需要使用中段描述符表 IDT 来管理中断或异常。每个中断描述符项保存了中断服务程序的地址,还有特权级和描述符类别等信息。

Linux 内核的中断处理过程

每个中断由 0255 之间的一个数字标识。对于中断 int00x1f ,Intel公司固定或保留用,属于软件中断,但 Intel 称之为异常。(通常还可以分为故障和陷阱)

中断 int0x20~0xff 可以由用户自行设定。

在 Linux 中,int0x20~0x2f 用于 8259A 终端控制芯片发出的硬件中断。程序编程发出的系统调用中断设置为 int0x80。 系统调用中断是用户使用操作系统资源的唯一界面接口。

在系统初始化时,内核在 head.s 程序中首先使用一个哑中断向量/中断描述符 对中断描述符表的 256 项进行默认设置。这个哑中断向量指向一个默认的“无中断”处理过程。

Linux 的系统调用

系统调用接口

系统调用(syscall)接口是 Linux 内核与上层应用程序进行交互通信的唯一接口。通过在 EAX 寄存器指定系统调用功能号,可以使用内核资源,包括系统硬件资源。

系统调用执行的返回值,一般 0 表示成功,出错的情况下错误类型码存放在全局变量 errno 中。

系统调用处理过程

32 位架构下,系统调用的参数保存在 EBX,ECX,EDX 中。

处理系统调用的过程是程序 kernel/system_call.s 中的 system_call 。

内核代码 include/unistd.h 中定义了宏函数 _syscalln() ,其中 n 代表了参数的个数。由于只实现了 0~3,所以最多直接传递 3 个参数。

1
2
3
4
#define __library
#include <unistd.h>

_syscall3(int, read, int, fd, char*, buf, int, n)

上述代码即可用 _syscall3 执行系统调用 read。