Linux内核源码阅读--开始之前
在开始阅读系统引导启动部分的内核代码之前,需要对以下内容进行了解:
- Linux 中断机制
- Linux 内核源码目录结构
- 磁盘结构及 INT 0x13
PS. 这个系列的文章将会对 Linux 0.11 版本的源码进行分析,资源在文末
中断机制
硬件原理
微型计算机通常包括 I/O(输入输出) 设备,处理器向设备提供服务的方式有两种
- 主动:处理器挨个地去询问系统中的设备是否需要服务,这种方式称为 轮询,缺点是太耗费系统资源
- 被动:当设备需要服务时,向处理器提出请求,处理器响应提出的请求为其提供服务
当设备向处理器提出请求,处理器在执行完当前的一条指令后立刻响应设备请求,并转到相应的服务程序去执行。执行完服务程序后,又返回到之前被打断的位置继续执行,这就是 中断(Interrupt),设备向处理器发出的服务请求称为 中断请求(IRQ)
处理器有一个 INT 引脚专门用来接收中断请求,但设备繁多,如果每个设备的中断请求直接给到处理器,当有多个请求同时到达时,处理器不知道该优先为谁提供服务
因此,需要有个大哥来管理这些设备的中断请求,这个大哥名叫 可编程中断控制器(PIC),PIC 会连接到处理器的 INT 引脚。设备的中断请求都会先给到 PIC,由 PIC 来筛选优先级高的中断请求递交给 CPU,如果 CPU 正在为一个设备提供中断服务,PIC 还会将选出的请求与正在执行的服务程序的优先级进行比较,以确定是否嵌套中断
当 PIC 向 INT 引脚发出中断信号后,处理器立即停下手头的工作,询问需要执行什么中断服务,PIC 通过数据总线发送与中断请求对应的 中断号,处理器拿着中断号去中断向量表(或 32 位保护模式下的中断描述符表)中查询服务程序的入口,进而跳去执行服务程序
中断同样可以由软件通过使用 int 指令来调用中断服务程序,PC/AT 系列微机提供 256 个中断的支持,大部分为软件中断或异常,异常 是处理器在处理过程中检测到错误而产生的中断
中断子系统
80X86 组成的微机系统中采用编号为 8259A 的 PIC 芯片,每个芯片可以管理 8 个中断源,通过多片级联的方式可以最多管理 64(8*8) 个中断向量的系统
PC/AT 系列兼容机中使用了两片 8259A 级联,管理 15 级中断向量,结构如图:
左边两片分别为 8259A 的主片和从片,从片通过自己的 INT 引脚连接到主片的 IR2 引脚。使用 IRQ2 引脚的设备又作为从片 IR1 引脚的输入,表示将使用 IRQ2 的设备的 IRQ2 引脚重定向到 IRQ9 引脚上。同时,主片的端口基址在 0x20,从片在 0xA0
8259A 芯片可分为编程状态和操作状态
- 编程状态下,由处理器使用 IN 或 OUT 指令对其进行初始化编程
- 操作状态下,响应设备中断请求,选出最高优先级中断,并通知处理器外中断的到来,处理器响应后,中断号由数据总线 D7-D0 送出,处理器由此获取中断向量值,执行中断服务程序
中断向量表
当 80X86 微机启动时,BIOS 中的程序会在物理内存起始处(0)初始化中断向量表,该表包含两个 8259A 芯片支持的 16 个硬件中断向量和 BIOS 提供的中断号为 0x10 ~ 0x1F 的中断调用功能向量,每个表项占 4 字节。对于没有使用的向量则填入临时的哑中断服务程序的地址
对于 Linux 而言,除了在开机时加载引导扇区(bootsect.s)及保存重要信息(setup.s)所用到的 BIOS 中断功能,之后 Linux 会在 setup.s 程序中重新初始化 8259A 芯片,并在 head.s 中重新构建一张中断描述符表,将 BIOS 提供的中断向量表覆盖
内核源码目录结构
一切尽在图中:
磁盘结构
关于磁盘,主要弄清楚几个概念:
- 磁头(head)
- 磁道(track)
- 扇区(sector)
- 柱面(cylinder)
如图,这是一个容量为 1.44 MB 的软盘:
一个磁盘面分正反两面,所以读取用的 磁头 也需要两个。从图中可以看到,盘面中一圈圈灰色同心圆为一条条 磁道,从圆心向外画射线,可以将磁道划分为若干个弧段,每个磁道上一个弧段称为一个 扇区。一个 柱面 包含了所有具有相同编号的磁道(从外向内编号,起始为 0)
一张这样的软盘有 2 个磁头,80 个柱面,每个柱面包含18 个扇区(每个扇区 512 字节),所以它的容量为:
2 * 80 * 18 * 512 = 1, 474, 560 Bytes = 1, 440 KB = 1.44 MB
系统启动时的引导扇区就位于 C0-H0-S1(柱面 0,磁头 0,扇区 1)
若想读写相邻两个磁道的数据,顺序为先读写第一个磁道磁头为 0(正面) 的所有扇区,再读写第一个磁道磁头为 1(反面) 的所有扇区,接着转去第二个磁道按照同样的顺序读写
INT 0X13 指令
该指令使用 BIOS 提供的磁盘操作功能,通过几个通用寄存器来传递参数
功能号:
- AH = 0x02:读盘
- AH = 0x03:写盘
- AH = 0x04:校验
- AH = 0x08:取磁盘参数
- AH = 0x0c:寻道
- AH = 0x15:取磁盘类型
AH 为 2 时:
参数:
- AL = 读出的扇区数(只能同时处理连续的扇区)
- CH = 磁道号低八位
- CL = 起始扇区号(0 ~ 5 位),磁道号高两位(6 ~ 7 位)
- DH = 磁头号
- DL = 驱动器号
- ES:BX = 缓冲地址(校验及寻道时不使用)
返回值:
- FLAGS.CF = 0:处理时没有发生错误,AH = 0
- FLAGS.CF = 1:发生了错误,错误号存在 AH 中
AH 为 8 时:
- 参数:
- DL = 驱动器号
- 返回值:
- FLAGS.CF = 0:处理时没有发生错误,AH = 0
- FLAGS.CF = 1:发生了错误,错误号存在 AH 中
- AL = 0
- BL = 驱动器类型(AT / PS2)
- CH = 最大磁道号的低8位
- CL = 每磁道最大扇区数(0-5bit),最大磁道号高2位(6-7bit)
- DH = 最大磁头数
- DL = 驱动器数量
- ES:DI:软驱磁盘参数表
AH 为 0x15 时:
- 参数:
- DL = 驱动器号
- 0x80 指第一个硬盘
- 0x81 指第二个硬盘
- DL = 驱动器号
- 返回值:
- AH = 类型码
- 0:没有这个盘,CF 置位
- 1:软驱,没有 change-line 支持
- 2:软驱(或其他可移动设备),有 change-line 支持
- 3:硬盘
- AH = 类型码
资源
提取码:sgd1