硬盘参数表

来源:互联网 发布:windows任务管理器 编辑:程序博客网 时间:2024/04/28 04:03
1>什么是硬盘参数表
         在PC机中BIOS设定的中断向量表中int 0x41的中断向量位置(4*0x41 =
     0x0000:0x0104)存放的并不是中断程序的地址,而是第一个硬盘的基本参数表
     对于100%兼容的BIOS来说,这里存放着硬盘参数表阵列的首地址0xF000:0E401
     第二个硬盘的基本参数表入口地址存于int 0x46中断向量位置处.每个硬盘参
     数表有16个字节大小.
   2>什么是A20门
         在8086/8088中,只有20根地址总线,所以可以访问的地址是2^20=1M,但由
     于8086/8088是16位地址模式,能够表示的地址范围是0-64K,所以为了在8086/
     8088下能够访问1M内存,Intel采取了分段的模式:16位段基地址:16位偏移.
     其绝对地址计算方法为:16位基地址左移4位+16位偏移=20位地址.
         但这种方式引起了新的问题,通过上述分段模式,能够表示的最大内存为:
     FFFFh:FFFFh=FFFF0h+FFFFh=10FFEFh=1M+64K-16Bytes(1M多余出来的部分被
     称做高端内存区HMA).但8086/8088只有20位地址线,如果访问100000h-
     10FFEFh之间的内存,则必须有第21根地址线.所以当程序员给出超过1M
     (100000H-10FFEFH)的地址时,系统并不认为其访问越界而产生异常,而是自动
     从重新0开始计算,也就是说系统计算实际地址的时候是按照对1M求模的方式
     进行的,这种技术被称为wrap-around.
         到了80286,系统的地址总线发展为24根,这样能够访问的内存可以达到
     2^24=16M.Intel在设计80286时提出的目标是,在实模式下系统所表现的行为
     应该和8086/8088所表现的完全一样,也就是说,在实模式下80286以及后续系
     列,应该和8086/8088完全兼容.但最终,80286芯片却存在一个BUG:如果程序员
     访问100000H-10FFEFH之间的内存,系统将实际访问这块内存,而不是象过去一
     样重新从0开始.
         为了解决上述问题,IBM使用键盘控制器上剩余的一些输出线来管理第21
     根地址线(从0开始数是第20根),被称为A20 Gate.如果A20 Gate被打开,则当
     程序员给出100000H-10FFEFH之间的地址的时候,系统将真正访问这块内存区
     域;如果A20 Gate被禁止,则当程序员给出100000H-10FFEFH之间的地址的时候,
     系统仍然使用8086/8088的方式.绝大多数IBM PC兼容机默认的A20 Gate是被
     禁止的.由于在当时没有更好的方法来解决这个问题,所以IBM使用了键盘控制
     器来操作A20 Gate.在80286以及更高系列的PC中,即使A20 Gate被打开,在实
     模式下所能够访问的内存最大也只能为10FFEFH,尽管它们的地址总线所能够
     访问的能力都大大超过这个限制.为了能够访问10FFEFH以上的内存,则必须进
     入保护模式.
         A20,其实它就是对于20-bit(从0开始数)的特殊处理(也就是对第21根地
     址线的处理).如果A20 Gate被禁止,对于80286来说其地址为24bit,其地址表
     示为EFFFFF;对于80386极其随后的32-bit芯片来说,其地址表示为FFEFFFFF.
     这种表示的意思是如果A20 Gate被禁止,则其第20-bit在CPU做地址访问的时
     候是无效的,永远只能被作为0;如果A20 Gate被打开,则其第20-bit是有效的,
     其值既可以是0,又可以是1.
         所以,在保护模式下,如果A20 Gate被禁止,则可以访问的内存只能是奇数
     1M段,即1M,3M,5M…,也就是00000-FFFFF,200000-2FFFFF,300000-3FFFFF….
     如果A20 Gate被打开,则可以访问的内存则是连续的.
   3>如何开启A20地址线
         多数PC都使用键盘控制器(8042芯片)来处理A20 Gate.从理论上讲,打开
     A20 Gate的方法是通过设置8042芯片输出端口(64h)的2nd-bit,但事实上,当
     你向8042芯片输出端口进行写操作的时候,在键盘缓冲区中,或许还有别的数
     据尚未处理,因此你必须首先处理这些数据.
     处理过程如下:
         1. 禁止中断;
2. 等待,直到8042 Input buffer为空为止;
3. 发送禁止键盘操作命令到8042 Input buffer;
4. 等待,直到8042 Input buffer为空为止;
5. 发送读取8042 Output Port命令;
6. 等待,直到8042 Output buffer有数据为止;
7. 读取8042 Output buffer,并保存得到的字节;
8. 等待,直到8042 Input buffer为空为止;
9. 发送Write 8042 Output Port命令到8042 Input buffer;
10. 等待,直到8042 Input buffer为空为止;
11. 将从8042 Output Port得到的字节的第2位置1(OR 2),然后写入8042
             Input buffer;
12. 等待,直到8042 Input buffer为空为止;
13. 发送允许键盘操作命令到8042 Input buffer;
14. 打开中断。
   4>如何检测A20地址线是否开启
         我们在之前已经提到,如果A20 Gate被打开了,则在实模式下,程序员可以
     直接访问100000H~10FFEFH之间的内存,如果A20 Gate被禁止,则在实模式下,
     若程序员访问100000H~10FFEFH之间的内存,则会被硬件自动转换为0H~0FFEFH
     之间的内存,所以我们可以利用这个差异来检测A20 Gate是否被打开.
   5>CR0寄存器
         CR0寄存器是处理器4个控制寄存器之一,结构如下
     +----+--------------------------+----+----+----+----+----+
     | PG |          Reserved          | ET | TS | EM | MP | PE |
     +----+--------------------------+----+----+----+----+----+
     31    30                          5     4     3     2     1     0
      BIT 0:PE 如果该位被置位,则运行保护模式,否则运行实模式
BIT 1:MP 控制wait指令
BIT 2:EM 表示协处理器功能是否可以被仿真
BIT 3:TS 用于任务转换
BIT 4:ET 表示当前协处理器的类型(80287或80387)
BIT 31:PG表示处理器是否使用分页机制
   6>描述符表
         在保护模式下内存的寻址方式跟实模式下不同,它并不是简单的将段寄存
     器的16位地址左移4位,然后加上偏移量来构成20位地址.在保护模式下,是可
     以寻址4GB空间的,因为有32跟地址线,所以2^32 = 4GB.在该模式下是通过段
     寄存器的索引值在描述符表(全局描述符表GDT或者局部描述符表LDT)内寻找
     到相应的表项,然后通过获取表项里保存的段基地址,段基地址与偏移量相加
     得到线性地址.如果系统没采用分页处理模式,那么线性地址就对应着实际的
     物理地址了.分页处理模式放到内存管理文档里详细说明.
         段寄存器格式:
     +--------------------------------+------+-----+
     |            Index             |   TI | RPL |
     +--------------------------------+------+-----+
    15                            32      1      0
     RPL: 优先级别 0 - 4 LINUX只用了0核心态 3用户态
     TI:   0使用全局描述符表(GDT),1使用局部描述符表(LDT)

         描述符表是保存在gdtr或者ldtr寄存器里的,该寄存器共占用6个字节大
     小.0-15位是表限,16-47位是表的基地址.表限是表示该表的大小,基地址是表
     示描述符表所在的线性地址中的位置.
     全局描述符号表和局部描述符号表的结构是一样的,如下:
     +---------------------------------+----------+
     |             Base address          |    Limit   |
     +---------------------------------+----------+
     47                                1615         0
         描述符表项是存储在描述符表里的内容.Intel公司将表项的第一个项设
     为空,从第2个表项开始使用.描述符表项的结构定义如下:
63      5655 5251     4847   4039     3231          1615       87      0
+---------+----+-------+-----+---------+-------------+-----------------+
|B31 - B24|    |L19-L16|     |B23 - B16|基地址 B15-B0|段上限L15 - L0|
+---------+----+-------+-----+---------+-------------+-----------------+

+------+------+------+------+
|    G   |   D/B |    O   |   AV   |
+------+------+------+------+
55                          52
G:    =1 段长以4K字节为单位 =0 段长以字节为单位
D/B: =1 表示对该段访问为32位指令 =0 表示为16位指令
O:    永远为0
AV:   可由软件使用,CPU忽略该位

+-----+----------+-----+-----+-------+-------+------+
|   P   |     DPL    |   S   |   E   | ED/C   |   R/W   |    A   |
+-----+----------+-----+-----+-------+-------+------+
47                    44    43                          40
A: =1 已经被访问过 =0 还未被访问过
R/W:   ---+         
ED/C: ---|----+---> +---- E = 0 数据段
E:     ---+     |      |
               |      +---- ED = 0 向上伸(数据段) ED = 1 向下伸(堆栈段)
               |      |
               |      +---- W = 0不可写 W = 1 可写
               |
               +---> +---- E = 1代码段
                     |
                     +---- C = 0 忽略特权级 C = 不忽略特权级
                     |
                     +---- R = 0 不能读 R = 1可读
S = 0表示用于系统管理的系统段 = 1表示一般的代码段或者数据段
DPL: 特权级
P = 1该段在内存中   = 0 不在内存中







1楼

硬盘基本参数表
中断向量表中,int 0x41 的中断向量位置(4 * 0x41 =0x0000:0x0104)存放的并不是中断程序的地
址而是第一个硬盘的基本参数表。对于100%兼容的BIOS 来说,这里存放着硬盘参数表阵列的首地址
F000h:E401h。第二个硬盘的基本参数表入口地址存于int 0x46 中断向量中。
表 硬盘基本参数信息表

位移 大小 说明
0x00 字 柱面数
0x02 字节 磁头数
0x03 字 开始减小写电流的柱面(仅PC XT 使用,其它为0)
0x05 字 开始写前预补偿柱面号(乘4)
0x07 字节 最大ECC 猝发长度(仅XT 使用,其它为0)
0x08 字节 控制字节(驱动器步进选择)
位0 未用
位1 保留(0) (关闭IRQ)
位2 允许复位
位3 若磁头数大于8 则置1
位4 未用(0)
位5 若在柱面数+1 处有生产商的坏区图,则置1
位6 禁止ECC 重试
位7 禁止访问重试。
0x09 字节 标准超时值(仅XT 使用,其它为0)
0x0A 字节 格式化超时值(仅XT 使用,其它为0)
0x0B 字节 检测驱动器超时值(仅XT 使用,其它为0)
0x0C 字 磁头着陆(停止)柱面号
0x0E 字节 每磁道扇区数
0x0F 字节 保留。
硬盘设备号命名方式
硬盘的主设备号是3。其它设备的主设备号分别为:
1-内存,2-磁盘,3-硬盘,4-ttyx,5-tty,6-并行口,7-非命名管道
由于1 个硬盘中可以存在1--4 个分区,因此硬盘还依据分区的不同用次设备号进行指定分区。因此
硬盘的逻辑设备号由以下方式构成:
设备号=主设备号*256 + 次设备号
也即dev_no = (major<<8) + minor
两个硬盘的所有逻辑设备号见下表所示。
表 硬盘逻辑设备号
逻辑设备号 对应设备文件说明
0x300 /dev/hd0 代表整个第1 个硬盘
0x301 /dev/hd1 表示第1 个硬盘的第1 个分区
0x302 /dev/hd2 表示第1 个硬盘的第2 个分区
0x303 /dev/hd3 表示第1 个硬盘的第3 个分区
0x304 /dev/hd4 表示第1 个硬盘的第4 个分区
0x305 /dev/hd5 代表整个第2 个硬盘
0x306 /dev/hd6 表示第2 个硬盘的第1 个分区
0x307 /dev/hd7 表示第2 个硬盘的第2 个分区
0x308 /dev/hd8 表示第2 个硬盘的第3 个分区
0x309 /dev/hd9 表示第2 个硬盘的第4 个分区

其中0x300 和0x305 并不与哪个分区对应,而是代表整个硬盘。
从linux 内核0.95 版后已经不使用这种烦琐的命名方式,而是使用与现在相同的命名方法了。
5.4.3.5 硬盘分区表
为了实现多个操作系统共享硬盘资源,硬盘可以在逻辑上分为1--4 个分区。每个分区之间的扇区号
是邻接的。分区表由4 个表项组成,每个表项由16 字节组成,对应一个分区的信息,存放有分区的大小
和起止的柱面号、磁道号和扇区号,见下表所示。分区表存放在硬盘的0柱面0头第1个扇区的0x1BE--0x1FD
处。
表 硬盘分区表结构
位置 名称 大小 说明
0x00 boot_ind 字节 引导标志。4 个分区中同时只能有一个分区是可引导的。
0x00-不从该分区引导操作系统;0x80-从该分区引导操作
系统。
0x01 head 字节 分区起始磁头号。
0x02 sector 字节 分区起始扇区号(位0-5)和起始柱面号高2 位(位6-7)。
0x03 cyl 字节 分区起始柱面号低8 位。
0x04 sys_ind 字节 分区类型字节。0x0b-DOS; 0x80-Old Minix; 0x83-Linux …
0x05 end_head 字节 分区的结束磁头号。
0x06 end_sector 字节 结束扇区号(位0-5)和结束柱面号高2 位(位6-7)。
0x07 end_cyl 字节 结束柱面号低8 位。
0x08--0x0b start_sect 长字 分区起始物理扇区号。
0x0c--0x0f nr_sects 长字 分区占用的扇区数。
__




bios执行完后把硬盘的参数放在某个地方,其入口地址由中断向量号0x41指定

中断向量0x41的地址是4*0x41(每个向量四个字节)
用bochs查看[xp/11x 0x104]
0x00000104 <bogus+ 0>: 0x9fc0003d 0xf000ff53 0xc0002544
0xf000ff53

可见入口地址为:0x9fc0003d

又入口地址的前个字节为偏移量(0x003d),后两个字节为段地址(0x9fc0),所以物理地址为9fc00+003d=0x9fc3d

查看硬盘参数表[xp/11x 0x9fc3d]
0x0009fc3d <bogus+ 0>: 0x00040132 0x00ffff00 0x000000c0
0x00110132


第0,1字节为柱面数,即0x0132(不是0x3201),第2个字节为磁头数0x04,倒数第二个字节为没磁道扇区数,即0x11

硬盘可以看成一个圆柱,三个参数为:
磁头,哪个面
柱面,哪个圈
扇区,圈上哪个弧