------------------------------------------------------------------------
head.asm 模块文档说明
By 姜江 <Jiang Jiang>
E-mail:jznsmail@tom.com
http://blog.youkuaiyun.com/jznsmail
1.模块介绍
==========
该模块是进入保护模式执行的第一段代码,在段代码里将会对中断控制器系
统各段寄存器初始化,并且检查A20门是否开启然后跳转到Main函数继续执行.
2.模块功能
==========
1.从新设置各个段寄存器
2.设置堆栈
3.检查A20 Gate是否开启
4.从新设置全局描述符
5.设置中断描述符
6.设置分页机制
7.跳转到Main函数执行
3.相关概念
==========
1>8259A中断控制器
一个8259A 芯片共有中断请求(IRQ)信号线:IRQ0~IRQ7,共8 根.在PC机中,
共有两片8259A芯片,通过把它们联结起来使用,就有IRQ0~IRQ15,共16根中断信号
线,每个外部设备使用一根或多个外部设备共用一根中断信号线,它们通过IRQ 发
送中断请求,8259A芯片接到中断请求后就对中断进行优先级选定,然后对多个中
断中具有最高优先级的中断进行处理,将其所对应的中断向量送上通往CPU的数据
线,并通知CPU有中断到来.
CPU总共可以处理256种中断,CPU对于其它的模块只提供了一种接口这就是
256个中断处理向量,也称为中断号.由这些中断控制器自行去使用这256个中断号
中的一个与CPU进行交互,当你需要处理的时候,只需告诉CPU 你用的是哪个中断
号就行,而不需告诉CPU 你是来自哪儿的中断.
PC机器中有2片8259A芯片,两片芯片是级联工作的,一个为主片,一个为从片,
从片的INT端口与主片的IRQ2相连.主片通过0x20及0x21 两个端口访问,而从片通
过0xA0及0xA1这两个端口访问.
在BIOS初始化PIC的时候,IRQ0~IRQ7被分配了0x8~0xF的中断号,然而当CPU
转到保护模式下工作的时候,0x8~0xF的中断号却被CPU用来处理错误.对8259A的编
程是通过向其相应的端口发送一系列的ICW(初始化命令字)完成的.总共需要发送
四个ICW,它们都分别有自己独特的格式,而且必须按次序发送,并且必须发送到相
应的端口.
ICW1: 发送到0x20(主片) 0xA0(从片)端口
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 | M | 0 | C | I |
+---+---+---+---+---+---+---+---+
I位: 置0表示ICW4会被发送
C位: 清0表示工作在级联环境下
M位: 指出中断请求的电平触发方式,在PC机中应当置0,表示"边沿触发方式"
ICW2: 发送到0x21(主片) 0xA1(从片)端口
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| A7| A6| A5| A4| A3| 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
ICW2用来指出IRQ0使用的中断是什么,因为最后3位均为0,因此要求IRQ0的
中断号必须是8的倍数.
ICW3: 发送到0x21(主片) 0xA1(从片)端口
ICW3只有在级联工作的时候才会被发送,它主要用来建立两处PIC之间的连接,对
于主片与从片,它结构是不一样的.
主片结构:
7 6 5 4 3 2 1 0
+----+----+----+----+----+----+----+----+
|IRQ7|IRQ6|IRQ5|IRQ4|IRQ3|IRQ2|IRQ1|IRQ0|
+----+----+----+----+----+----+----+----+
上面,如果相应的位被置1,则相应的IRQ线就被用于与从片连接,若清零则表
示被连接到外围设备.
从片结构:
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | IRQ |
+---+---+---+---+---+---+---+---+
IRQ位指出了是主片的哪一个IRQ连到了从片,这需要同主片上发送的上面的
主片结构字一致.
ICW4: 发送到0x21(主片) 0xA1(从片)端口
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 |EOI|x86|
+---+---+---+---+---+---+---+---+
x86位: 置位表示工作在80x86构架下
EOI位: 若置位表示自动结束,在PC上这位需要被清零.
注:
如果EOI被置位表示自动结束,则芯片会自动将ISR中的相应位清零.如果EOI没
有被置位,则需要中断处理程序向芯片发送EOI消息,芯片收到EOI消息后才会将
ISR中的相应位清零.
OCW操作命令字
他们用来操作8259A的优先级,中断屏蔽以及中断结束等控制
OCW1: 中断屏蔽,发送到0x21(主片) 0xA1(从片)端口
7 6 5 4 3 2 1 0
+----+----+----+----+----+----+----+----+
|IRQ7|IRQ6|IRQ5|IRQ4|IRQ3|IRQ2|IRQ1|IRQ0|
+----+----+----+----+----+----+----+----+
如果相应位被置1,表示屏蔽相应的IRQ请求
OCW2: 优先权控制及中断结束命令,发送到0x20(主片) 0xA0(从片)端口
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| R | SL|EOI| 0 | 0 | L2| L1| L0|
+---+---+---+---+---+---+---+---+
EOI也是OCW2型命令中的一种,当EOI位被置1,这就是一个EOI消息.SL是指定
级别位,如果SL被置位,则表明这是一个指定级别的EOI消息,这个消息可以指定
将ISR中的哪一位清零,即结束哪一个IRQ的中断处理.L2、L1、L0 就用来指定
IRQ的编号.而在实际运用中我们却将SL及L2,L1,L0全置零.
SL置零表示这是一个不指定级别的EOI消息,则8259A 芯片自动将ISR中所有
被置位的IRQ里优先级最高的清零,因为它是正在被处理及等待处理的中断中优
先级最高的,也就一定是CPU正在处理的中断.
当R为0时,表明这是一个固定优先权方式,IRQ0最高,IRQ7最低.当R为1时,表
明这是一个循环优先权,比如,如指定IR2最低,则优先级顺序就为:IRQ2<IRQ3<
IRQ4<...<IRQ7<IRQ0<IRQ1也即,如果IRQ(i)最低,那么IRQ(i+1)就最高.
OCW3:
7 6 5 4 3 2 1 0
+----+----+----+----+----+----+----+----+
| 0 |ESMM| SMM| 0 | 1 | P | AR | RIS|
+----+----+----+----+----+----+----+----+
2>IA-32体系结构下的8259A编程
CPU是通过给不同中断分配不同的中断号来识别各个中断的,一种中断对应
一个中断号,一个中断号就对应一个中断服务程序.当有中断到来,处理器使用
这个中断号作为索引,在中断描述符表中索引对应的入口地址,该入口地址就是
中断服务程序的入口地址,处理器取得入口地址后就跳转到这个地址执行中断
服务程序.
中断描述符表(IDT)中每个表项就是一个中断描述符,每个中断描述符包含
一个中断服务程序的地址.
中断描述符结构:
+------------------------------+---+---+-----+---+--------+
| Offset 16 - 31 | P |DPL|0D110|000|Reserved| 4
+------------------------------+---+---+-----+---+--------+
31 1615 141312 87 54 0
+------------------------------+--------------------------+
| Segment selector | Offset 0 - 15 | 0
+------------------------------+--------------------------+
31 1615 0
P: 置1表这个描述符可以被使用
DPL: 特权级
系统是通过中断描述符表寄存器(IDTR)来载入中断描述符表的,该寄存器结
构是:
+---------------------------------+----------+
| Base address | Limit |
+---------------------------------+----------+
47 1615 0
4.内存映象
==========
+---------------+
| ... |
+---------------+
| kernel.c |
+---------------+ 0x6000
| GDT table(2KB)|
+---------------+ 0x5800
| IDT table(2KB)|
+---------------+ 0x5000
| 页表page3(4KB)|
+---------------+ 0x4000
| 页表page2(4KB)|
+---------------+ 0x3000
| 页表page1(4KB)|
+---------------+ 0x2000
| 页表page0(4KB)|
+---------------+ 0x1000
| 页目录表(4KB) |
+---------------+ 0x0000