扩展Int 13H调用规范
- 格式:docx
- 大小:27.17 KB
- 文档页数:8
CHS(或称为Normal)模式:适应容量≤504MB的硬盘LBA(Logical Block Addressing)模式:适应容量≥504MB的硬盘,但BIOS需支持扩展INT13H,否则也只能适应≤8.4GB的硬盘LARGE(或称LRG)模式:适应504MB≤容量≤8.4GB的硬盘LARGE大硬盘模式。
当硬盘的柱面超过1024而又不为LBA支持时可采用此种模式。
LARGE模式采取的方法是把柱面数除以2,把磁头数乘以2,其结果总容量不变。
例如,在NORMAL 模式下柱面数为1220,磁头数为16,进入LARGE模式则柱面数为610,磁头数为32。
这样在DOS看来柱面数小于1024,即可正常工作。
目前基本上只有LBA有实际意义了。
LARGE寻址模式把柱面数除以整数倍、磁头数乘以整数倍而得到的逻辑磁头/柱面/扇区参数进行寻址,所以表示的已不是硬盘中的物理位置,而是逻辑位置。
LBA寻址模式是直接以扇区为单位进行寻址的,不再用磁头/柱面/扇区三种单位来进行寻址。
但为了保持与CHS模式的兼容,通过逻辑变换算法,可以转换为磁头/柱面/扇区三种参数来表示,但表示的也和LARGE寻址模式一样,已不是硬盘中的物理位置,而是逻辑位置了。
LBA(Logical Block Addressing)逻辑块寻址模式。
这种模式所管理的硬盘空间突破了528KB的瓶颈,可达8.4GB。
在LBA模式下,设置的柱面、磁头、扇区等参数并不是实际硬盘的物理参数。
在访问硬盘时,由IDE控制器把由柱面、磁头、扇区等参数确定的逻辑地址转换为实际硬盘的物理地址。
在LBA模式下,可设置的最大磁头数为255,其余参数与普通模式相同。
由此可计算出可访问的硬盘容量为:512×63×255×1024=8.4GB。
为什么会变成LGR模式?是硬盘坏了``我以前也遇到过只能访问C盘,其它盘说盘符无效,当时拿到厂家保修,他说坏了, 当然你如果不能保修,可以试着自己弄, 我那时候是从BIOS已经看不到硬盘了, 如果你的还可以的话,可以用工具去对硬盘的分区表进行重建,也可以重新分区,检查.低格等. 如果BIOS看不到的话,那就看是不是零磁道坏了,也可以用工具查看一下`` 具体的作法可以到网上去查.不过一般这种挽回的可能性都不怎么大. 努力,希望采纳扩展int13h调用详解(修正)第一部分简介一. 硬盘结构简介1. 硬盘参数释疑到目前为止, 人们常说的硬盘参数还是古老的 CHS (Cylinder/ Head/Sector)参数. 那么为什么要使用这些参数, 它们的意义是什么? 它们的取值范围是什么? 很久以前, 硬盘的容量还非常小的时候, 人们采用与软盘类似的结构生产硬盘. 也就是硬盘盘片的每一条磁道都具有相同的扇区数. 由此产生了所谓的3D 参数 (Disk Geometry). 既磁头数(Heads), 柱面数 (Cylinders), 扇区数(Sectors),以及相应的寻址方式. 其中: 磁头数(Heads) 表示硬盘总共有几个磁头,也就是有几面盘片, 最大为 255 (用 8 个二进制位存储); 柱面数(Cylinders) 表示硬盘每一面盘片上有几条磁道, 最大为 1023 (用 10 个二进制位存储); 扇区数(Sectors) 表示每一条磁道上有几个扇区, 最大为 63 (用 6 个二进制位存储). 每个扇区一般是 512个字节, 理论上讲这不是必须的, 但好象没有取别的值的. 所以磁盘最大容量为: 255 * 1023 * 63 * 512 / 1048576 = 8024 MB ( 1M = 1048576 Bytes ) 或硬盘厂商常用的单位: 255 * 1023 * 63 * 512 / 1000000 = 8414 MB ( 1M = 1000000 Bytes ) 在 CHS 寻址方式中, 磁头, 柱面, 扇区的取值范围分别为 0 到 Heads - 1, 0 到 Cylinders - 1, 1 到 Sectors (注意是从 1 开始).2. 基本 Int 13H 调用简介 BIOS Int 13H 调用是 BIOS 提供的磁盘基本输入输出中断调用, 它可以完成磁盘(包括硬盘和软盘)的复位, 读写, 校验, 定位, 诊断, 格式化等功能. 它使用的就是 CHS 寻址方式, 因此最大识能访问 8 GB 左右的硬盘 ( 本文中如不作特殊说明, 均以 1M = 1048576 字节为单位).3. 现代硬盘结构简介在老式硬盘中, 由于每个磁道的扇区数相等, 所以外道的记录密度要远低于内道, 因此会浪费很多磁盘空间 (与软盘一样). 为了解决这一问题, 进一步提高硬盘容量, 人们改用等密度结构生产硬盘. 也就是说, 外圈磁道的扇区比内圈磁道多. 采用这种结构后, 硬盘不再具有实际的3D参数, 寻址方式也改为线性寻址, 即以扇区为单位进行寻址. 为了与使用3D寻址的老软件兼容 (如使用BIOS Int13H接口的软件), 在硬盘控制器内部安装了一个地址***器, 由它负责将老式3D参数***成新的线性参数. 这也是为什么现在硬盘的3D参数可以有多种选择的原因 (不同的工作模式, 对应不同的3D参数, 如 LBA, LARGE, NORMAL).4. 扩展 Int 13H 简介虽然现代硬盘都已经采用了线性寻址, 但是由于基本 Int 13H 的制约, 使用 BIOS Int 13H 接口的程序, 如 DOS 等还只能访问 8 G 以内的硬盘空间. 为了打破这一限制, Microsoft 等几家公司制定了扩展 Int 13H 标准 (Extended Int13H), 采用线性寻址方式存取硬盘, 所以突破了 8 G 的限制, 而且还加入了对可拆卸介质 (如活动硬盘) 的支持.二. Boot Sector 结构简介1. Boot Sector 的组成Boot Sector 也就是硬盘的第一个扇区, 它由 MBR (Master Boot Record), DPT (Disk Partition Table) 和 Boot Record ID 三部分组成. MBR 又称作主引导记录占用 Boot Sector 的前 446 个字节 ( 0 to0x1BD ), 存放系统主引导程序 (它负责从活动分区中装载并运行系统引导程序). DPT 即主分区表占用 64 个节 (0x1BE to 0x1FD), 记录了磁盘的基本分区信息. 主分区表分为四个分区项, 每项 16 字节, 分别记录了每个主分区的信息 (因此最多可以有四个主分区). Boot Record ID 即引导区标记占用两个字节(0x1FE and 0x1FF), 对于合法引导区, 它等于 0xAA55, 这是判别引导区是否合法的标志. Boot Sector 的具体结构如下图所示 (参见 NightOwl 大侠的文章):2. 分区表结构简介分区表由四个分区项构成, 每一项的结构如下:BYTE State : 分区状态, 0 = 未激活, 0x80 = 激活 (注意此项)BYTE StartHead : 分区起始磁头号WORD StartSC : 分区起始扇区和柱面号, 底字节的低6位为扇区号,高2位为柱面号的第 9,10 位, 高字节为柱面号的低 8 位BYTE Type : 分区类型, 如 0x0B = FAT32, 0x83 = Linux 等,00 表示此项未用BYTE EndHead : 分区结束磁头号WORD EndSC : 分区结束扇区和柱面号, 定义同前DWORD Relative : 在线性寻址方式下的分区相对扇区地址(对于基本分区即为绝对地址)DWORD Sectors : 分区大小 (总扇区数) 注意: 在 DOS / Windows 系统下, 基本分区必须以柱面为单位划分 ( Sectors * Heads 个扇区), 如对于 CHS 为 764/255/63 的硬盘, 分区的最小尺寸为 255 * 63 * 512 / 1048576 = 7.844 MB.3. 扩展分区简介由于主分区表中只能分四个分区, 无法满足需求, 因此设计了一种扩展分区格式. 基本上说, 扩展分区的信息是以链表形式存放的, 但也有一些特别的地方. 首先, 主分区表中要有一个基本扩展分区项, 所有扩展分区都隶属于它, 也就是说其他所有扩展分区的空间都必须包括在这个基本扩展分区中. 对于 DOS / Windows 来说, 扩展分区的类型为 0x05或0x0F(>8GB). 除基本扩展分区以外的其他所有扩展分区则以链表的形式级联存放, 后一个扩展分区的数据项记录在前一个扩展分区的分区表中, 但两个扩展分区的空间并不重叠. 扩展分区类似于一个完整的硬盘, 必须进一步分区才能使用. 但每个扩展分区中只能存在一个其他分区. 此分区在 DOS/Windows 环境中即为逻辑盘. 因此每一个扩展分区的分区表 (同样存储在扩展分区的第一个扇区中)中最多只能有两个分区数据项(包括下一个扩展分区的数据项). 扩展分区和逻辑盘的示意图如下:三. 系统启动过程简介系统启动过程主要由一下几步组成(以硬盘启动为例):1. 开机 :-)2. BIOS 加电自检 ( Power On Self Test -- POST ) 内存地址为 0ffff:00003. 将硬盘第一个扇区 (0头0道1扇区, 也就是Boot Sector) 读入内存地址 0000:7c00 处.4. 检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于则转去尝试其他启动介质, 如果没有其他启动介质则显示 "No ROM BASIC" 然后死机.5. 跳转到 0000:7c00 处执行 MBR 中的程序.6. MBR 首先将自己复制到 0000:0600 处, 然后继续执行.7. 在主分区表中搜索标志为活动的分区. 如果发现没有活动分区或有不止一个活动分区, 则转停止.8. 将活动分区的第一个扇区读入内存地址 0000:7c00 处.9. 检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于则显示 "Missing Operating System" 然后停止, 或尝试软盘启动.10. 跳转到 0000:7c00 处继续执行特定系统的启动程序.11. 启动系统 ...以上步骤中 2,3,4,5 步是由 BIOS 的引导程序完成. 6,7,8,9,10 步由MBR中的引导程序完成. 一般多系统引导程序 (如 SmartFDISK, BootStar, PQBoot 等) 都是将标准主引导记录替换成自己的引导程序, 在运行系统启动程序之前让用户选择要启动的分区. 而某些系统自带的多系统引导程序 (如 lilo, NT Loader 等) 则可以将自己的引导程序放在系统所处分区的第一个扇区中, 在 Linux 中即为 SuperBlock (其实 SuperBlock 是两个扇区). 注: 以上各步骤中使用的是标准 MBR, 其他多系统引导程序的引导过程与此不同.第二部分技术资料第一章扩展 Int13H 技术资料一. 简介设计扩展 Int13H 接口的目的是为了扩展 BIOS 的功能, 使其支持多于1024柱面的硬盘, 以及可移动介质的琐定, 解锁及弹出等功能.二. 数据结构1. 数据类型约定BYTE 1 字节整型 ( 8 位 )WORD 2 字节整型 ( 16 位 )DWORD 4 字节整型 ( 32 位 )QWORD 8 字节整型 ( 64 位 )2. 磁盘地址数据包 Disk Address Packet (DAP) DAP 是基于绝对扇区地址的, 因此利用 DAP, Int13H 可以轻松地逾越 1024 柱面的限制, 因为它根本就不需要 CHS 的概念. DAP 的结构如下:struct DiskAddressPacket{BYTE PacketSize; // 数据包尺寸://(固定值,恒等于16,即10H,指本结构所占用的存储空间)BYTE Reserved; // ==0WORD BlockCount; // 要传输的数据块个数(以扇区为单位)DWORD BufferAddr; // 传输缓冲地址(segment:offset)QWORD BlockNum; // 磁盘起始绝对块地址};PacketSize 保存了 DAP 结构的尺寸, 以便将来对其进行扩充. 在目前使用的扩展 Int13H 版本中PacketSize 恒等于 16. 如果它小于 16, 扩展 Int13H 将返回错误码( AH=01, CF=1 ). BlockCount 对于输入来说是需要传输的数据块总数, 对于输出来说是实际传输的数据块个数. BlockCount = 0 表示不传输任何数据块. BufferAddr 是传输数据缓冲区的 32 位地址 (段地址:偏移量). 数据缓冲区必须位于常规内存以内(1M). BlockNum 表示的是从磁盘开始算起的绝对块地址(以扇区为单位), 与分区无关. 第一个块地址为 0. 一般来说, BlockNum 与 CHS 地址的关系是: BlockNum = (cylinder * NumberOfHeads + head) * SectorsPerTrack + sector - 1; 其中 cylinder, head, sector 是 CHS 址, NumberOfHeads 是磁盘的磁头数, SectorsPerTrack 是磁盘每磁道的扇区数. 也就是说 BlockNum 是沿着扇区->磁道->柱面的顺序记数的. 这一顺序是由磁盘控制器虚拟的, 磁盘表面数据块的实际排列顺序可能与此不同 (如为了提高磁盘速度而设置的间隔因子将会打乱扇区的排列顺序). 3. 驱动器参数数据包 Drive Parameters Packet 驱动器参数数据包是在扩展 Int13H 的取得驱动器参数子功能调用中使用的数据包. 格式如下: struct DriveParametersPacket{WORD InfoSize; // 数据包尺寸: //(固定值,等于26,即1AH,指本结构所占用的存储空间)WORD Flags; // 信息标志DWORD Cylinders; // 磁盘柱面数DWORD Heads; // 磁盘磁头数DWORD SectorsPerTrack; // 每磁道扇区数QWORD Sectors; // 磁盘总扇区数WORD SectorSize; // 扇区尺寸 (以字节为单位)};信息标志用于返回磁盘的附加信息, 每一位的定义如下:0 位:0 = 可能发生 DMA 边界错误1 = DMA 边界错误将被透明处理如果这位置 1, 表示 BIOS 将自动处理 DMA 边界错误, 也就是说错误代码 09H 永远也不会出现.1 位:0 = 未提供 CHS 信息1 = CHS 信息合法如果块设备的传统 CHS 几何信息不适当的话, 该位将置 0.2 位:0 = 驱动器不可移动1 = 驱动器可移动3 位: 表示该驱动器是否支持写入时校验.4 位:0 = 驱动器不具备介质更换检测线1 = 驱动器具备介质更换检测线5 位:0 = 驱动器不可锁定1 = 驱动器可以锁定要存取驱动器号大于 0x80 的可移动驱动器, 该位必须置 1(某些驱动器号为 0 到 0x7F 的设备也需要置位)6 位:0 = CHS 值是当前存储介质的值 (仅对于可移动介质), 如果驱动器中有存储介质, CHS 值将被返回.1 = CHS 值是驱动器支持的最大值 (此时驱动器中没有介质).7 - 15 位: 保留, 必须置 0.三. 接口规范1. 寄存器约定在扩展 Int13H 调用中一般使用如下寄存器约定:ds:si ==> 磁盘地址数据包( disk address packet )dl ==> 驱动器号ah ==> 功能代码 / 返回码在基本 Int13H 调用中, 0 - 0x7F 之间的驱动器号代表可移动驱动器0x80 - 0xFF 之间的驱动器号代表固定驱动器. 但在扩展 Int13H 调用中0x80 - 0xFF 之间还包括一些新出现的可移动驱动器, 比如活动硬盘等.这些驱动器支持先进的锁定,解锁等功能. ah 返回的错误码除了标准 Int13H 调用规定的基本错误码以外,又增加了以下错误码:B0h 驱动器中的介质未被锁定B1h 驱动器中的介质已经锁定B2h 介质是可移动的B3h 介质正在被使用B4h 锁定记数溢出B5h 合法的弹出请求失败2. API 子集介绍1.x 版的扩展 Int13H 调用中规定了两个主要的 API 子集.第一个子集提供了访问大硬盘所必须的功能, 包括检查扩展 In13H 是否存在( 41h ), 扩展读( 42h ), 扩展写( 43h ), 校验扇区( 44h ), 扩展定位( 47h ) 和取得驱动器参数( 48h ). 第二个子集提供了对软件控制驱动器锁定和弹出的支持, 包括检查扩展 Int13H 是否存在( 41h ), 锁定/解锁驱动器( 45h ), 弹出驱动器( 46h ), 取得驱动器参数( 48h ), 取得扩展驱动器改变状态( 49h ), int 15h.如果使用了调用规范中不支持的功能, BIOS 将返回错误码 ah = 01h, CF = 1.3. API 详解1) 检验扩展功能是否存在入口:AH = 41hBX = 55AAhDL = 驱动器号返回:CF = 0AH = 扩展功能的主版本号AL = 内部使用BX = AA55hCX = API 子集支持位图CF = 1AH = 错误码 01h, 无效命令这个调用检验对特定的驱动器是否存在扩展功能. 如果进位标志置 1 则此驱动器不支持扩展功能. 如果进位标志为 0, 同时 BX = AA55h, 则存在扩展功能. 此时 CX 的 0 位表示是否支持第一个子集, 1位表示是否支持第二个子集. 对于 1.x 版的扩展 Int13H 来说, 主版本号 AH = 1. AL 是副版本号, 但这仅限于 BIOS 内部使用, 任何软件不得检查 AL 的值.2) 扩展读入口:AH = 42hDL = 驱动器号DS:DI = 磁盘地址数据包(Disk Address Packet)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用将磁盘上的数据读入内存. 如果出现错误, DAP 的 BlockCount 项中则记录了出错前实际读取的数据块个数.3) 扩展写入口:AH = 43hAL0 位 = 0 关闭写校验1 打开写校验1 - 7 位保留, 置 0DL = 驱动器号DS:DI = 磁盘地址数据包(DAP)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用将内存中的数据写入磁盘. 如果打开了写校验选项, 但 BIOS不支持, 则会返回错误码 AH = 01h, CF = 1. 功能 48h 可以检测BIOS是否支持写校验. 如果出现错误, DAP 的 BlockCount 项中则记录了出错前实际写入的数据块个数.4) 校验扇区入口:AH = 44hDL = 驱动器号DS:DI = 磁盘地址数据包(Disk Address Packet)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用校验磁盘数据, 但并不将数据读入内存.如果出现错误, DAP 的BlockCount 项中则记录了出错前实际校验的数据块个数.5) 锁定/解锁驱动器入口:AH = 45hAL= 0 锁定驱动器= 1 驱动器解锁= 02 返回锁定/解锁状态= 03h-FFh - 保留DL = 驱动器号返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用用来缩定指定驱动器中的介质. 所有标号大于等于 0x80 的可移动驱动器必须支持这个功能. 如果在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用, 将会成功返回. 驱动器必须支持最大255次锁定, 在所有锁定被解锁之前, 不能在物理上将驱动器解锁. 解锁一个未锁定的驱动器,将返回错误码 AH= B0h. 如果锁定一个已锁定了255次的驱动器, 将返回错误码 AH = B4h. 锁定一个没有介质的驱动器是合法的.6) 弹出可移动驱动器中的介质入口:AH = 46hAL = 0 保留DL = 驱动器号返回:CF = 0, AH = 0 成功 CF = 1, AH = 错误码这个调用用来弹出指定的可移动驱动器中的介质. 所有标号大于等于 0x80 的可移动驱动器必须支持这个功能. 如果在支持可移动驱动器控制功能子集的固定驱动器上使用这个功调用, 将会返回错误码 AH = B2h (介质不可移动). 如果试图弹出一个被锁定的介质将返回错误码 AH = B1h (介质被锁定). 如果试图弹出一个没有介质的驱动器, 则返回错误码 Ah = 31h (驱动器中没有介质). 如果试图弹出一个未锁定的可移动驱动器中的介质, Int13h会调用 Int15h (AH = 52h) 来检查弹出请求能否执行. 如果弹出请求被拒绝则返回错误码(同 Int15h). 如果弹出请求被接受,但出现了其他错误, 则返回错误码 AH = B5h. 7) 扩展定位入口:AH = 47hDL = 驱动器号DS:DI = 磁盘地址数据包(Disk Address Packet)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用将磁头定位到指定扇区.8) 取得驱动器参数入口:AH = 48hDL = 驱动器号DS:DI = 返回数据缓冲区地址返回:CF = 0, AH = 0 成功DS:DI 驱动器参数数据包地址, (参见前面的文章)CF = 1, AH = 错误码这个调用返回指定驱动器的参数.9) 取得扩展驱动器介质更换检测线状态入口:AH = 49hDL = 驱动器号返回:CF = 0, AH = 0 介质未更换CF = 1, AH = 06h 介质可能已更换这个调用返回指定驱动器的介质更换状态. 这个调用与 Int13h AH = 16h 子功能调用相同, 只是允许任何驱动器标号. 如果对一台支持可移动介质功能子集的固定驱动器使用此功能,则永远返回 CF = 0, AH = 0. 简单地将可移动介质锁定再解锁就可以激活检测线, 而无须真正更换介质.10) Int 15h 可移动介质弹出支持入口:AH = 52hDL = 驱动器号返回:CF = 0, AH = 0 弹出请求可能可以执行CF = 1, AH = 错误码 B1h 或 B3h 弹出请求不能执行这个调用是由 Int13h AH=46h 弹出介质功能调用内部使用的.。
关于int13与扩展int13第一部分简介1,1一. 硬盘结构简介1. 硬盘参数释疑到目前为止, 人们常说的硬盘参数还是古老的CHS (Cylinder/Head/Sector)参数. 那么为什么要使用这些参数, 它们的意义是什么? 它们的取值范围是什么? 很久以前, 硬盘的容量还非常小的时候, 人们采用与软盘类似的结构生产硬盘. 也就是硬盘盘片的每一条磁道都具有相同的扇区数. 由此产生了所谓的3D参数(Disk Geometry). 既磁头数(Heads), 柱面数(Cylinders), 扇区数(Sectors),以及相应的寻址方式.其中:磁头数(Heads) 表示硬盘总共有几个磁头,也就是有几面盘片, 最大为255 (用8 个二进制位存储); 柱面数(Cylinders) 表示硬盘每一面盘片上有几条磁道, 最大为1023 (用10 个二进制位存储); 扇区数(Sectors) 表示每一条磁道上有几个扇区, 最大为63 (用6 个二进制位存储).每个扇区一般是512个字节, 理论上讲这不是必须的, 但好象没有取别的值的.所以磁盘最大容量为: 255 * 1023 * 63 * 512 / 1048576 = 8024 GB ( 1M = 1048576 Bytes ) 或硬盘厂商常用的单位:255 * 1023 * 63 * 512 / 1000000 = 8414 GB ( 1M = 1000000 Bytes ) 在CHS 寻址方式中, 磁头, 柱面, 扇区的取值范围分别为0 到Heads - 1, 0 到Cylinders - 1, 1 到Sectors (注意是从1 开始).2. 基本Int 13H 调用简介BIOS Int 13H 调用是BIOS 提供的磁盘基本输入输出中断调用, 它可以完成磁盘(包括硬盘和软盘)的复位, 读写, 校验, 定位, 诊断, 格式化等功能.它使用的就是CHS 寻址方式, 因此最大识能访问8 GB 左右的硬盘( 本文中如不作特殊说明, 均以1M = 1048576 字节为单位).3. 现代硬盘结构简介在老式硬盘中, 由于每个磁道的扇区数相等, 所以外道的记录密度要远低于内道, 因此会浪费很多磁盘空间(与软盘一样). 为了解决这一问题, 进一步提高硬盘容量, 人们改用等密度结构生产硬盘. 也就是说, 外圈磁道的扇区比内圈磁道多. 采用这种结构后, 硬盘不再具有实际的3D参数, 寻址方式也改为线性寻址, 即以扇区为单位进行寻址.为了与使用3D寻址的老软件兼容(如使用BIOS Int13H接口的软件), 在硬盘控制器内部安装了一个地址翻译器, 由它负责将老式3D参数翻译成新的线性参数. 这也是为什么现在硬盘的3D参数可以有多种选择的原因(不同的工作模式, 对应不同的3D参数, 如LBA, LARGE, NORMAL).4. 扩展Int 13H 简介虽然现代硬盘都已经采用了线性寻址, 但是由于基本Int 13H 的制约, 使用BIOS Int 13H 接口的程序, 如DOS 等还只能访问8 G 以内的硬盘空间.为了打破这一限制, Microsoft 等几家公司制定了扩展Int 13H 标准(Extended Int13H), 采用线性寻址方式存取硬盘, 所以突破了8 G 的限制, 而且还加入了对可拆卸介质(如活动硬盘) 的支持.二. Boot Sector 结构简介1. Boot Sector 的组成Boot Sector 也就是硬盘的第一个扇区, 它由MBR (Master Boot Record), DPT (Disk Partition Table) 和Boot Record ID 三部分组成. MBR 又称作主引导记录占用Boot Sector 的前446 个字节( 0 to 0x1BD ), 存放系统主引导程序(它负责从活动分区中装载并运行系统引导程序). DPT 即主分区表占用64 个字节(0x1BE to 0x1FD), 记录了磁盘的基本分区信息. 主分区表分为四个分区项, 每项16 字节, 分别记录了每个主分区的信息(因此最多可以有四个主分区).Boot Record ID 即引导区标记占用两个字节(0x1FE and 0x1FF), 对于合法引导区, 它等于0xAA55, 这是判别引导区是否合法的标志.Boot Sector 的具体结构如下图所示:0000 |------------------------------------------------|| || || Master Boot Record || || || 主引导记录(446字节) || || || |01BD | |01BE |------------------------------------------------|| |01CD | 分区信息1(16字节) |01CE |------------------------------------------------|| |01DD | 分区信息2(16字节) |01DE |------------------------------------------------|| |01ED | 分区信息3(16字节) |01EE |------------------------------------------------|| |01FD | 分区信息4(16字节) ||------------------------------------------------|| 01FE | 01FF || 55 | AA ||------------------------------------------------|2. 分区表结构简介分区表由四个分区项构成, 每一项的结构如下:BYTE State : 分区状态, 0 = 未激活, 0x80 = 激活(注意此项)BYTE StartHead : 分区起始磁头号WORD StartSC : 分区起始扇区和柱面号, 底字节的低6位为扇区号,高2位为柱面号的第9,10 位, 高字节为柱面号的低8 位BYTE Type : 分区类型, 如0x0B = FAT32, 0x83 = Linux 等,00 表示此项未用BYTE EndHead : 分区结束磁头号WORD EndSC : 分区结束扇区和柱面号, 定义同前DWORD Relative : 在线性寻址方式下的分区相对扇区地址(对于基本分区即为绝对地址)DWORD Sectors : 分区大小(总扇区数)注意: 在DOS / Windows 系统下, 基本分区必须以柱面为单位划分( Sectors * Heads 个扇区), 如对于CHS 为764/255/63 的硬盘, 分区的最小尺寸为255 * 63 * 512 / 1048576 = 7.844 MB.3. 扩展分区简介由于主分区表中只能分四个分区, 无法满足需求, 因此设计了一种扩展分区格式. 基本上说, 扩展分区的信息是以链表形式存放的, 但也有一些特别的地方.首先, 主分区表中要有一个基本扩展分区项, 所有扩展分区都隶属于它, 也就是说其他所有扩展分区的空间都必须包括在这个基本扩展分区中. 对于DOS / Windows 来说, 扩展分区的类型为0x05. 除基本扩展分区以外的其他所有扩展分区则以链表的形式级联存放, 后一个扩展分区的数据项记录在前一个扩展分区的分区表中, 但两个扩展分区的空间并不重叠.扩展分区类似于一个完整的硬盘, 必须进一步分区才能使用. 但每个扩展分区中只能存在一个其他分区. 此分区在DOS/Windows 环境中即为逻辑盘. 因此每一个扩展分区的分区表(同样存储在扩展分区的第一个扇区中)中最多只能有两个分区数据项(包括下一个扩展分区的数据项). 扩展分区和逻辑盘的示意图如下:|-----------------------| --------| 主扩展分区(/dev/hda2) | ^|-----------------------| || 扩展| 分区项1 |--/ || |------------| | || 分区表| 分区项2 |--+--/ ||-----------------------| | | || | | | || 逻辑盘1 (/dev/hda5) |<-/ | || | | ||-----------------------| | 主| 扩展分区2 |<----/|-----------------------| 扩| 扩展| 分区项1 |--/| |------------| | 展| 分区表| 分区项2 |--+--/|-----------------------| | | 分| | | || 逻辑盘2 (/dev/hda6) |<-/ | 区| | | ||-----------------------| | || 扩展分区3 |<----/ ||-----------------------| || 扩展| 分区项1 |--/ || |------------| | || 分区表| 分区项2 | | ||-----------------------| | || | | || 逻辑盘3 (/dev/hda7) |<-/ || | ||-----------------------| ---------三. 系统启动过程简介系统启动过程主要由一下几步组成(以硬盘启动为例):1. 开机:-)2. BIOS 加电自检( Power On Self Test -- POST )内存地址为0ffff:00003. 将硬盘第一个扇区(0头0道1扇区, 也就是Boot Sector)读入内存地址0000:7c00 处.4. 检查(WORD) 0000:7dfe 是否等于0xaa55, 若不等于则转去尝试其他启动介质, 如果没有其他启动介质则显示"No ROM BASIC" 然后死机.5. 跳转到0000:7c00 处执行MBR 中的程序.6. MBR 首先将自己复制到0000:0600 处, 然后继续执行.7. 在主分区表中搜索标志为活动的分区. 如果发现没有活动分区或有不止一个活动分区, 则转停止.8. 将活动分区的第一个扇区读入内存地址0000:7c00 处.9. 检查(WORD) 0000:7dfe 是否等于0xaa55, 若不等于则显示"Missing Operating System" 然后停止, 或尝试软盘启动.10. 跳转到0000:7c00 处继续执行特定系统的启动程序.11. 启动系统 ...以上步骤中2,3,4,5 步是由BIOS 的引导程序完成. 6,7,8,9,10步由MBR中的引导程序完成.一般多系统引导程序(如SmartFDISK, BootStar, PQBoot 等) 都是将标准主引导记录替换成自己的引导程序, 在运行系统启动程序之前让用户选择要启动的分区. 而某些系统自带的多系统引导程序(如lilo, NT Loader 等) 则可以将自己的引导程序放在系统所处分区的第一个扇区中, 在Linux 中即为SuperBlock (其实SuperBlock 是两个扇区). 注: 以上各步骤中使用的是标准MBR, 其他多系统引导程序的引导过程与此不同.第二部分技术资料第一章扩展Int13H 技术资料一. 简介设计扩展Int13H 接口的目的是为了扩展BIOS 的功能, 使其支持多于1024柱面的硬盘, 以及可移动介质的琐定, 解锁及弹出等功能.二. 数据结构1. 数据类型约定BYTE 1 字节整型( 8 位)WORD 2 字节整型( 16 位)DWORD 4 字节整型( 32 位)QWORD 8 字节整型( 64 位)2. 磁盘地址数据包Disk Address Packet (DAP)DAP 是基于绝对扇区地址的, 因此利用DAP, Int13H 可以轻松地逾越1024 柱面的限制, 因为它根本就不需要CHS 的概念.DAP 的结构如下:struct DiskAddressPacket{BYTE PacketSize; // 数据包尺寸(16字节)BYTE Reserved; // ==0WORD BlockCount; // 要传输的数据块个数(以扇区为单位)DWORD BufferAddr; // 传输缓冲地址(segment:offset)QWORD BlockNum; // 磁盘起始绝对块地址};PacketSize 保存了DAP 结构的尺寸, 以便将来对其进行扩充. 在目前使用的扩展Int13H 版本中PacketSize 恒等于16. 如果它小于16, 扩展Int13H 将返回错误码( AH=01, CF=1 ). BlockCount 对于输入来说是需要传输的数据块总数, 对于输出来说是实际传输的数据块个数. BlockCount = 0 表示不传输任何数据块. BufferAddr 是传输数据缓冲区的32 位地址(段地址:偏移量). 数据缓冲区必须位于常规内存以内(1M). BlockNum 表示的是从磁盘开始算起的绝对块地址(以扇区为单位), 与分区无关. 第一个块地址为0. 一般来说, BlockNum 与CHS 地址的关系是: BlockNum = cylinder * NumberOfHeads + head * SectorsPerTrack + sector - 1; 其中cylinder, head, sector 是CHS 地址, NumberOfHeads 是磁盘的磁头数, SectorsPerTrack 是磁盘每磁道的扇区数. 也就是说BlockNum 是沿着扇区->磁道->柱面的顺序记数的. 这一顺序是由磁盘控制器虚拟的, 磁盘表面数据块的实际排列顺序可能与此不同(如为了提高磁盘速度而设置的间隔因子将会打乱扇区的排列顺序).3. 驱动器参数数据包Drive Parameters Packet驱动器参数数据包是在扩展Int13H 的取得驱动器参数子功能调用中使用的数据包. 格式如下:struct DriveParametersPacket{WORD InfoSize; // 数据包尺寸(26 字节)WORD Flags; // 信息标志DWORD Cylinders; // 磁盘柱面数DWORD Heads; // 磁盘磁头数DWORD SectorsPerTrack; // 每磁道扇区数QWORD Sectors; // 磁盘总扇区数WORD SectorSize; // 扇区尺寸(以字节为单位)};信息标志用于返回磁盘的附加信息, 每一位的定义如下:0 位:0 = 可能发生DMA 边界错误1 = DMA 边界错误将被透明处理如果这位置1, 表示BIOS 将自动处理DMA 边界错误, 也就是说错误代码09H 永远也不会出现.1 位:0 = 未提供CHS 信息1 = CHS 信息合法如果块设备的传统CHS 几何信息不适当的话, 该位将置0.2 位:0 = 驱动器不可移动1 = 驱动器可移动3 位: 表示该驱动器是否支持写入时校验.4 位:0 = 驱动器不具备介质更换检测线1 = 驱动器具备介质更换检测线5 位:0 = 驱动器不可锁定1 = 驱动器可以锁定要存取驱动器号大于0x80 的可移动驱动器, 该位必须置1(某些驱动器号为0 到0x7F 的设备也需要置位)6 位:0 = CHS 值是当前存储介质的值(仅对于可移动介质), 如果驱动器中有存储介质, CHS 值将被返回.1 = CHS 值是驱动器支持的最大值(此时驱动器中没有介质).7 - 15 位: 保留, 必须置0.三. 接口规范1. 寄存器约定在扩展Int13H 调用中一般使用如下寄存器约定:ds:di ==> 磁盘地址数据包( disk address packet )dl ==> 驱动器号ah ==> 功能代码/ 返回码在基本Int13H 调用中, 0 - 0x7F 之间的驱动器号代表可移动驱动器0x80 - 0xFF 之间的驱动器号代表固定驱动器. 但在扩展Int13H 调用中0x80 - 0xFF 之间还包括一些新出现的可移动驱动器, 比如活动硬盘等. 这些驱动器支持先进的锁定,解锁等功能. ah 返回的错误码除了标准Int13H 调用规定的基本错误码以外,又增加了以下错误码:B0h 驱动器中的介质未被锁定B1h 驱动器中的介质已经锁定B2h 介质是可移动的B3h 介质正在被使用B4h 锁定记数溢出B5h 合法的弹出请求失败2. API 子集介绍1.x 版的扩展Int13H 调用中规定了两个主要的API 子集. 第一个子集提供了访问大硬盘所必须的功能, 包括检查扩展In13H 是否存在( 41h ), 扩展读( 42h ), 扩展写( 43h ), 校验扇区( 44h ), 扩展定位( 47h ) 和取得驱动器参数( 48h ). 第二个子集提供了对软件控制驱动器锁定和弹出的支持, 包括检查扩展Int13H 是否存在( 41h ), 锁定/解锁驱动器( 45h ), 弹出驱动器( 46h ), 取得驱动器参数( 48h ), 取得扩展驱动器改变状态( 49h ), int 15h. 如果使用了调用规范中不支持的功能, BIOS 将返回错误码ah = 01h, CF = 1.3. API 详解1) 检验扩展功能是否存在入口:AH = 41hBX = 55AAhDL = 驱动器号返回:CF = 0AH = 扩展功能的主版本号AL = 内部使用BX = AA55hCX = API 子集支持位图CF = 1AH = 错误码01h, 无效命令这个调用检验对特定的驱动器是否存在扩展功能. 如果进位标志置1 则此驱动器不支持扩展功能. 如果进位标志为0, 同时BX = AA55h, 则存在扩展功能. 此时CX 的0 位表示是否支持第一个子集, 1位表示是否支持第二个子集.对于1.x 版的扩展Int13H 来说, 主版本号AH = 1. AL 是副版本号, 但这仅限于BIOS 内部使用, 任何软件不得检查AL 的值. 2) 扩展读入口:AH = 42hDL = 驱动器号DS:DI = 磁盘地址数据包(Disk Address Packet)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用将磁盘上的数据读入内存. 如果出现错误, DAP 的BlockCount项中则记录了出错前实际读取的数据块个数.3) 扩展写入口:AH = 43hAL0 位= 0 关闭写校验1 打开写校验1 - 7 位保留, 置0DL = 驱动器号DS:DI = 磁盘地址数据包(DAP)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用将内存中的数据写入磁盘. 如果打开了写校验选项, 但BIOS不支持, 则会返回错误码AH = 01h, CF = 1. 功能48h 可以检测BIOS是否支持写校验. 如果出现错误, DAP 的BlockCount 项中则记录了出错前实际写入的数据块个数.4) 校验扇区入口:AH = 44hDL = 驱动器号DS:DI = 磁盘地址数据包(Disk Address Packet)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用校验磁盘数据, 但并不将数据读入内存.如果出现错误, DAP 的BlockCount 项中则记录了出错前实际校验的数据块个数.5) 锁定/解锁驱动器入口:AH = 45hAL= 0 锁定驱动器= 1 驱动器解锁= 02 返回锁定/解锁状态= 03h-FFh - 保留DL = 驱动器号返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用用来缩定指定驱动器中的介质. 所有标号大于等于0x80 的可移动驱动器必须支持这个功能. 如果在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用, 将会成功返回. 会成功返回. 驱动器必须支持最大255次锁定, 在所有锁定被解锁之前, 不能在物理上将驱动器解锁. 解锁一个未锁定的驱动器,将返回错误码AH= B0h. 如果锁定一个已锁定了255次的驱动器, 将返回错误码AH = B4h. 锁定一个没有介质的驱动器是合法的.6) 弹出可移动驱动器中的介质入口:AH = 46hAL = 0 保留DL = 驱动器号返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用用来弹出指定的可移动驱动器中的介质.所有标号大于等于0x80 的可移动驱动器必须支持这个功能. 如果在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用, 将会返回错误码AH = B2h (介质不可移动). 如果试图弹出一个被锁定的介质将返回错误码AH = B1h (介质被锁定).如果试图弹出一个没有介质的驱动器, 则返回错误码Ah = 31h (驱动器中没有介质).中没有介质).如果试图弹出一个未锁定的可移动驱动器中的介质, Int13h会调用Int15h(AH = 52h) 来检查弹出请求能否执行. 如果弹出请求被拒绝则返回错误码(同Int15h). 如果弹出请求被接受,但出现了其他错误, 则返回错误码AH = B5h.7) 扩展定位入口:AH = 47hDL = 驱动器号DS:DI = 磁盘地址数据包(Disk Address Packet)返回:CF = 0, AH = 0 成功CF = 1, AH = 错误码这个调用将磁头定位到指定扇区.8) 取得驱动器参数入口:AH = 48hDL = 驱动器号DS:DI = 返回数据缓冲区地址返回:CF = 0, AH = 0 成功DS:DI 驱动器参数数据包地址, (参见前面的文章)CF = 1, AH = 错误码这个调用返回指定驱动器的参数.9) 取得扩展驱动器介质更换检测线状态入口:AH = 49hDL = 驱动器号返回:CF = 0, AH = 0 介质未更换CF = 1, AH = 06h 介质可能已更换这个调用返回指定驱动器的介质更换状态.这个调用与Int13h AH = 16h 子功能调用相同, 只是允许任何驱动器标号. 如果对一台支持可移动介质功能子集的固定驱动器使用此功能,则永远返回CF = 0, AH = 0. 简单地将可移动介质锁定再解锁就可以激活检测线, 而无须真正更换介质.10) Int 15h 可移动介质弹出支持入口:AH = 52hDL = 驱动器号返回:CF = 0, AH = 0 弹出请求可能可以执行CF = 1, AH = 错误码B1h 或B3h 弹出请求不能执行这个调用是由Int13h AH=46h 弹出介质功能调用内部使用的。
用扩展INT13H研析并恢复大容量硬盘分区信息链表内容摘要:本文利用扩展INT13H的磁盘地址数据包及相关调用,分析了整个分区链表并给出了链表中任一结点分区信息丢失或被破坏之后的一种恢复方法。
关键字:扩展INT13H、数据包、分区信息、链表、恢复一、 扩展INT13H相关读写接口规范概述扩展INT13H接口设计的目的是为了扩展BIOS的功能,使之能处理柱面数大于1024的硬盘,并支持移动存贮介质的锁定、解锁和弹出等各类新增功能。
1、 数据类型定义:BYTE 一字节; WORD 二字节; DWORD 四字节; QWORD 八字节;磁盘读写地址数据包DRWAP(Disk Read Write Address Packet),利用该数据包中断INT13H可以直接读写处理目前主流硬盘上的任一扇区,匆需理会传统磁盘概念中的通过柱面号、磁头号及扇区号(CHS)的物理扇区定位方式。
DRWAP结构如下:Struct DRWAP{ BYTE PacketSize;//数据包所占字节数,有10H和18H两种,本文用前者BYTE Reserved;//保留字节,设为00HWORD Blockcount;//传输的数据块个数(最大值为7FH),以扇区为单位DORD TransferBuffer;//传输缓冲区地址(SEG:OFFSET)QORD AbsoluteBlockNumber;//磁盘起始绝对扇区号(主引导扇区为0号)}AbsoluteBlockNumber与传统CHS的关系如下:AbsoluteBlockNumber=(Cylinder*NumHeads+Head)*SectorPerTrack+Secto r-1DRWAP数据包的获取及实际操作2、 定义磁盘读写地址数据包获取指定扇区之内容入口参数:AH=42H; DL=80H; DS:SI=DRWAP首地址出口参数:CF=NC OK;CF=CY ERROR二、分区信息链表解析读取主引导扇区操作过程:(为操作的连续性,本文不采用传统INT13H的功能号02)磁盘读写地址数据包按如下方式定义:进入DEBUG状态之后,DS和SI采用当前默认值,假设为DS=1216,SI=0000 则E 命令或F命令从1216:0000处输入以下16个字节内容1216:0000 10 00 01 00 00 02 16 12-00 00 00 00 00 00 00 00数据包长度=10H=16个字节 保留字节=00H 要传输的扇区个数=0001H=1个 缓冲区地址DS:SI=1216:0200 磁盘起始绝对扇区号=0000000000000000H=0号-A1001216:0100 MOV AH,42MOV DL,80INT 13INT 3-G=100-D3BE80 011216:03B0 01 00 0B FE BF D9 3F 00-00 00 1B F2 B2 00 00 00:03C0 81 DA 0F FE FF FF 5A F2-B2 00 3E DE E0 02 00 00从上述内容可知:C区的起始点为0柱1头1扇,即磁盘起始绝对扇区0号;C区的结束点为729柱254头63扇,并隐含了63个扇区;C区共占用了00B2F21BH个扇区约为5.58GB。
硬盘百科名片硬盘(港台称之为硬碟,英文名:Hard Disk Drive 简称HDD 全名温彻斯特式硬盘)是电脑主要的存储媒介之一,由一个或者多个铝制或者玻璃制的碟片组成。
这些碟片外覆盖有铁磁性材料。
绝大多数硬盘都是固定硬盘,被永久性地密封固定在硬盘驱动器中。
目录1硬盘硬盘种类1硬盘技术1机械硬盘1接口ATA1IDE1SATA1SATA Ⅱ1SATA Ⅲ1SCSI1光纤通道1SAS接口尺寸制造厂商1物理结构1.磁头12.磁道13.扇区14.柱面1逻辑结构3D参数1基本Int 13H 调用1现代硬盘结构1扩展Int 13H1基本参数一、容量1二、转速1三、平均访问时间1四、传输速率1五、缓存1磁头数1薄膜感应磁头11.读写过程中忌断电12.保持良好的环境13.防止受震动14.减少频繁操作15.恰当的使用时间16.定期整理碎片17.稳定的电源供电18.不要强制性关机硬盘硬盘种类硬盘拼音Yìngpán;硬盘分为固态硬盘(SSD)和机械硬盘(HDD);SSD采用闪存颗粒来存储,HDD采用磁性碟片来存储。
硬盘技术磁头复位节能技术:通过在闲时对磁头的复位来节能。
西部数据在最新的硬盘上采用了该技术来减少空闲时功耗。
多磁头技术:通过在同一碟片增加多个磁头同时的读或写来为硬盘提速,或同时在多碟片同时利用磁头来读或写来为磁盘提速。
希捷和日立数据的部分型号采用了该技术。
多用于服务器和数据库中心。
机械硬盘1.1956年,IBM的IBM 350RAMAC是现代硬盘的雏形,它相当于两个冰箱的体积,不过其储存容量只有5MB。
1973年IBM 3340问世,它拥有“温彻斯特”这个绰号,来源于他两个30MB的储存单元,恰是当时出名的“温彻斯特来福枪”的口径和填弹量。
至此,硬盘的基本架构被确立。
2.1980年,两位前IBM员工创立的公司开发出5.25英寸规格的5MB硬盘,这是首款面向台式机的产品,而该公司正是希捷(SEAGATE)公司。
用扩展INT13H研析并恢复大容量硬盘分区信息链表【摘要】本文旨在探讨如何利用扩展INT13H来研析并恢复大容量硬盘分区信息链表。
在将介绍背景知识和研究意义,为读者提供研究的必要背景。
在将详细讨论扩展INT13H的功能、研析大容量硬盘分区信息链表的方法、以及恢复分区信息的技术挑战和数据分析。
结论部分将对整篇文章进行总结归纳,并展望未来在这一领域的发展方向。
通过本文的阐述,希望读者能够深入了解利用扩展INT13H进行大容量硬盘分区信息链表恢复的技术原理和方法,为数据恢复领域的研究提供更多启发和思路。
【关键词】扩展INT13H、大容量硬盘、分区信息链表、恢复、技术挑战、数据分析、背景介绍、研究意义、总结归纳、展望未来1. 引言1.1 背景介绍随着科技的发展,大容量硬盘逐渐成为了日常生活和工作中不可或缺的存储设备。
在处理大容量硬盘时,我们经常会遇到一些问题,比如分区信息丢失或损坏,导致数据无法访问。
为了解决这些问题,研究人员开始着手研究扩展INT13H功能,并通过分析大容量硬盘分区信息链表来恢复数据。
扩展INT13H是一种BIOS中断调用,可以扩展硬盘的操作功能,包括支持大容量硬盘的操作。
通过扩展INT13H,我们可以更加灵活地操作大容量硬盘,包括读取和写入数据等操作。
研究大容量硬盘分区信息链表可以帮助我们了解硬盘的分区结构,从而更好地恢复数据。
在恢复大容量硬盘分区信息时,我们面临着一些技术挑战,比如数据的准确性和完整性问题。
通过数据分析,我们可以更深入地了解数据的特点和结构,从而提高数据恢复的成功率。
在本文中,我们将深入探讨扩展INT13H的功能,研析大容量硬盘分区信息链表,探讨恢复大容量硬盘分区信息的技术挑战,并进行数据分析,最后进行总结归纳并展望未来的研究方向。
通过这些工作,我们希望能够提高大容量硬盘数据恢复的效率和成功率。
1.2 研究意义硬盘分区信息链表是硬盘分区表的核心数据结构,在存储设备上记录了硬盘的分区信息,包括分区的起始位置、大小、文件系统类型等。
c语言中强制类型转换规则C语言中的强制类型转换规则在C语言中,强制类型转换是一种将一个数据类型转换为另一个数据类型的操作。
强制类型转换可以在程序中使用,以便将一个数据类型转换为另一个数据类型,以便在程序中进行正确的计算和操作。
在本文中,我们将讨论C语言中的强制类型转换规则。
强制类型转换的语法在C语言中,强制类型转换的语法如下:(type) expression其中,type是要转换的数据类型,expression是要转换的表达式。
在这个语法中,括号是必需的,以便告诉编译器要进行强制类型转换。
例如,下面的代码将一个整数转换为浮点数:int i = 10;float f = (float) i;在这个例子中,我们使用了强制类型转换将整数i转换为浮点数f。
在括号中,我们指定了要转换的数据类型float。
强制类型转换的规则在C语言中,强制类型转换有一些规则,需要遵守。
下面是一些强制类型转换的规则:1. 可以将任何数据类型转换为另一个数据类型。
在C语言中,可以将任何数据类型转换为另一个数据类型。
例如,可以将整数转换为浮点数,也可以将浮点数转换为整数。
但是,需要注意的是,转换后的数据类型可能会丢失一些信息。
2. 可以将较小的数据类型转换为较大的数据类型。
在C语言中,可以将较小的数据类型转换为较大的数据类型。
例如,可以将char类型转换为int类型。
这种转换被称为“扩展”。
3. 不能将较大的数据类型转换为较小的数据类型。
在C语言中,不能将较大的数据类型转换为较小的数据类型。
例如,不能将int类型转换为char类型。
这种转换被称为“截断”。
4. 可以将指针类型转换为另一个指针类型。
在C语言中,可以将指针类型转换为另一个指针类型。
例如,可以将int类型的指针转换为char类型的指针。
但是,需要注意的是,转换后的指针可能会指向错误的内存地址。
5. 可以将指针类型转换为整数类型。
在C语言中,可以将指针类型转换为整数类型。
中国科技论文在线 无操作系统环境下硬盘参数获取罗冰南京理工大学计算机系,南京(210094)E-mail: luobing4365@摘要:硬盘是最常用的存储介质之一。
在各种安全应用的场合,常常需要获取硬盘的详细参数,但是大部分文献只研究了在操作系统下获取硬盘信息的理论和方法。
本文研究了在无操作系统的情况下获取硬盘参数的方法,并对IDE硬盘和SATA硬盘的不同进行了阐述,在此基础上给出了具体实现方案和程序流程。
关键词:硬盘;int 13h;CHS;LBA;ECh中图分类号: T P3191 引言硬盘是一个半导体与机械的集合体。
自从1956年的IBM 350问世以来,盘片技术、电机技术都有了质的飞跃。
一直以来,我们都是采用ATA/IDE并行接口的方式进行硬盘数据的传输。
Intel 在2000年的IDF会上提出了SATA接口,到现在,SATA接口的硬盘几乎完全替代了IDE接口的硬盘了。
在很多的IT项目中,都需要获取硬盘的信息,比如软件加密等。
如果是在操作系统层面,使用操作系统提供的API能够满足项目要求。
当前很多获取硬盘信息的实现方法都是在操作系统层面进行的,理论和实现方法都已经比较完善。
在无操作系统支持的环境中,只能使用BIOS中断和I/O指令访问硬件,此时获取硬盘信息是不小的挑战。
另外的一个难题是现在流行的SATA硬盘与传统的IDE硬盘不同,其I/O访问端口不是固定不变的,必须通过BIOS提供的信息来确定其端口值。
本文阐述了如何在无操作系统的环境下访问硬盘,并给出了使用I/O指令获取硬盘信息的方法和代码。
2 底层访问硬盘的方法在无操作系统的情况下,有两种方法可以访问硬盘,其一是使用BIOS提供的中断。
另外一种是直接使用I/O指令访问。
以下分别说明。
2.1 硬盘的逻辑结构BIOS中断提供了int 13h来访问硬盘,常使用的有CHS模式和LBA模式两种逻辑结构。
在了解如何通过硬盘中断访问硬盘前,必须了解CHS模式和LBA模式的区别,这两中模式分别对于于标准硬盘中断和扩展硬盘中断。
C语言技术的扩展与库调用指南C语言作为一种广泛使用的编程语言,拥有强大的功能和灵活性。
然而,为了更好地应对不断变化的技术需求,C语言也需要不断扩展和更新。
本文将介绍C语言技术的扩展与库调用指南,帮助读者更好地利用C语言进行编程。
一、C语言的扩展技术1. 宏定义宏定义是C语言中一种重要的扩展技术。
通过使用宏定义,我们可以在编译过程中将一些常用的代码片段替换为宏定义的形式,从而提高代码的复用性和可读性。
例如,我们可以使用宏定义来定义一个常用的计算平方的函数,简化代码编写过程。
2. 预处理指令预处理指令是C语言中另一种重要的扩展技术。
通过使用预处理指令,我们可以在编译过程中对源代码进行预处理,实现一些特定的功能。
例如,我们可以使用预处理指令来包含头文件、定义常量、进行条件编译等。
3. 结构体和联合体结构体和联合体是C语言中用于扩展数据类型的重要工具。
通过使用结构体和联合体,我们可以将多个不同类型的数据组合在一起,形成一个新的数据类型。
这样可以更好地组织和管理数据,提高代码的可读性和可维护性。
4. 指针指针是C语言中一种重要的扩展技术。
通过使用指针,我们可以直接访问内存中的数据,实现更灵活和高效的编程。
指针可以用于动态分配内存、传递参数、访问数组等。
二、C语言的库调用指南1. 标准库函数C语言标准库提供了丰富的函数库,包括字符串处理、数学计算、文件操作等。
通过调用标准库函数,我们可以快速实现各种功能,提高代码的开发效率。
例如,通过调用标准库函数可以实现字符串的复制、连接、比较等操作。
2. 第三方库除了标准库,C语言还有许多优秀的第三方库可供调用。
这些库提供了各种功能,如图形界面、网络通信、数据库操作等。
通过调用第三方库,我们可以快速实现复杂的功能,提高代码的可扩展性和可重用性。
3. 自定义库在实际开发中,我们也可以根据自己的需求编写自定义的库。
通过将一些常用的功能封装成库,我们可以提高代码的复用性和可维护性。
INT 10H 是由 BIOS 对屏幕及显示器所提供的服务程序,而后倚天公司针对倚天中文提供了许多服务程序,这些服务程序也加挂在 INT 10H 内。
使用 INT 10H 中断服务程序时,先指定 AH 寄存器为下表编号其中之一,该编号表示欲调用的功用,而其他寄存器的详细说明,参考表后文字,当一切设定好之后再调用 INT 10H。
底下是它们的说明:BIOS中断:1、显示服务(Video Service——INT 10H)00H —设置显示器模式01H —设置光标形状02H —设置光标位置03H —读取光标信息04H —读取光笔位置05H —设置显示页06H、07H —初始化或滚屏08H —读光标处的字符及其属性09H —在光标处按指定属性显示字符0AH —在当前光标处显示字符0BH —设置调色板、背景色或边框0CH —写图形象素0DH —读图形象素0EH —在Teletype模式下显示字符0FH —读取显示器模式10H —颜色11H —字体12H —显示器的配置13H —在Teletype模式下显示字符串1AH —读取/设置显示组合编码1BH —读取功能/状态信息1CH —保存/恢复显示器状态(1)、功能00H功能描述:设置显示器模式入口参数:AH=00HAL=显示器模式,见下表所示出口参数:无可用的显示模式如下所列:00H:40×25 16色文本01H:40×25 16色文本02H:80×25 16色文本03H: 80×25 16色文本04H:320×200 4色05H:320×200 4色06H:640×200 2色07H:80×25 2色文本08H:160×200 16色09H:320×200 16色0AH:640×200 4色0BH:保留0CH:保留0DH:320×200 16色0EH:640×200 16色0FH:640×350 2(单色)10H:640×350 4色10H:640×350 16色11H:640×480 2色12H:640×480 16色13H:640×480 256色对于超级VGA显示卡,我们可用AX=4F02H和下列BX的值来设置其显示模式。
MBR病毒分析Date:2010.10.29Author:Cryin’Blog:/justear一、基础知识1、Windows启动过程系统引导过程主要由以下几个步骤组成(以硬盘启动为例)1、开机;2、BIOS加电自检(POST---Power On Self Test),内存地址为0fff:0000;3、将硬盘第一个扇区(0头0道1扇区,也就是Boot Sector)读入内存地址0000:7c00处;4、检查(WORD)0000:7dfe是否等于0xaa55.若不等于则转去尝试其他介质;如果没有其他启动介质,则显示”No ROM BASIC”,然后死机;5、跳转到0000:7c00处执行MBR中的程序;6、MBR先将自己复制到0000:0600处,然后继续执行;7、在主分区表中搜索标志为活动的分区.如果发现没有活动分区或者不止一个活动分区,则停止;8、将活动分区的第一个扇区读入内存地址0000:7c00处;9、检查(WORD)0000:7dfe是否等于0xaa55,若不等于则显示“Missing Operating System”,然后停止,或尝试软盘启动;10、跳转到0000:7c00处继续执行特定系统的启动程序;11、启动系统.以上步骤中(2),(3),(4),(5)步由BIOS的引导程序完成;(6),(7),(8),(9),(10)步由MBR中的引导程序完成.Windows启动过程主要由以下几个步骤组成,其中vista和win7可一概而论;2、硬盘主引导区结构硬盘的主引导区在0柱面0磁道1扇区,包括硬盘主引导记录MBR(Main Boot Record)、四个分区表DPT(Disk Partition Table)信息和主引导记录有效标志字三部分,如表所示:主引导记录MBR从0000H开始到00D9H结束,共218个字节。
MBR的作用就是检查分区表是否正确以及确定哪个分区为引导分区,并在程序结束时把该分区的启动程序(也就是操作系统引导扇区)调入内存加以执行。
BIOS INT 13H 中断扩展目录一、接口及错误码 (1)二、 API 中断子集 (2)1.X版的扩展 Int13H 调用中规定了两个主要的 API 子集。
(2)三、子集介绍 (2)(一) 41H 检验扩展功能是否存在 (2)(二) 42H 扩展读 (3)(三) 43H 扩展写 (4)(四) 44H 校验扇区 (4)(五) 45H 锁定/解锁驱动器 (5)(六) 46H 弹出可移动驱动器中的介质 (5)(七) 47H 扩展定位 (6)(八) 48H 取得驱动器参数 (6)(九) 49H 取得扩展驱动器介质更换检测线状态 (6)(十) Int 15h 可移动介质弹出支持 (7)四、数据结构 (7)1. 数据类型约定 (7)2. 磁盘地址数据包 Disk Address Packet (DAP) (7)3. 驱动器参数数据包 Drive Parameters Packet (9)一、接口及错误码在扩展 Int13H 调用中一般使用如下寄存器约定:ds:si ==> 磁盘地址数据包( disk address packet )dl ==> 驱动器号ah ==> 功能代码 / 返回码在基本 Int13H 调用中,0 - 0x7F 之间的驱动器号代表可移动驱动器;0x80 - 0xFF 之间的驱动器号代表固定驱动器。
但在扩展 Int13H 调用中0x80 - 0xFF 之间还包括一些新出现的可移动驱动器, 比如活动硬盘等。
这些驱动器支持先进的锁定,解锁等功能。
ah 返回的错误码除了标准 Int13H 调用规定的基本错误码以外,又B1h 驱动器中的介质已经锁定B2h 介质是可移动的B3h 介质正在被使用B4h 锁定记数溢出B5h 合法的弹出请求失败二、API 中断子集1.X版的扩展 Int13H 调用中规定了两个主要的 API 子集。
第一个子集提供了访问大硬盘所必须的功能, 包括检查扩展In13H 是否存在( 41h ), 扩展读( 42h ), 扩展写( 43h ), 校验扇区( 44h ), 扩展定位( 47h ) 和取得驱动器参数( 48h ).第二个子集提供了对软件控制驱动器锁定和弹出的支持, 包括检查扩展Int13H 是否存在( 41h ), 锁定/解锁驱动器( 45h ), 弹出驱动器( 46h ), 取得驱动器参数( 48h ), 取得扩展驱动器改变状态( 4Arrayh ), int 15h。
INT 10H 是由BIOS 对屏幕及显示器所提供的服务程序,而后倚天公司针对倚天中文提供了许多服务程序,这些服务程序也加挂在INT 10H 内。
使用INT 10H 中断服务程序时,先指定AH 寄存器为下表编号其中之一,该编号表示欲调用的功用,而其他寄存器的详细说明,参考表后文字,当一切设定好之后再调用INT 10H。
底下是它们的说明:BIOS中断:1、显示服务(Video Service——INT 10H)00H —设置显示器模式01H —设置光标形状02H —设置光标位置03H —读取光标信息04H —读取光笔位置05H —设置显示页06H、07H —初始化或滚屏08H —读光标处的字符及其属性09H —在光标处按指定属性显示字符0AH —在当前光标处显示字符0BH —设置调色板、背景色或边框0CH —写图形象素0DH —读图形象素0EH —在Teletype模式下显示字符0FH —读取显示器模式10H —颜色11H —字体12H —显示器的配置13H —在Teletype模式下显示字符串1AH —读取/设置显示组合编码1BH —读取功能/状态信息1CH —保存/恢复显示器状态(1)、功能00H功能描述:设置显示器模式入口参数:AH=00HAL=显示器模式,见下表所示出口参数:无可用的显示模式如下所列:00H:40×25 16色文本01H:40×25 16色文本02H:80×25 16色文本03H: 80×25 16色文本04H:320×200 4色05H:320×200 4色06H:640×200 2色07H:80×25 2色文本08H:160×200 16色09H:320×200 16色0AH:640×200 4色0BH:保留0CH:保留0DH:320×200 16色0EH:640×200 16色0FH:640×350 2(单色)10H:640×350 4色10H:640×350 16色11H:640×480 2色12H:640×480 16色13H:640×480 256色对于超级VGA显示卡,我们可用AX=4F02H和下列BX的值来设置其显示模式。
C标准库源码解剖(11):扩展整数类型stdint.h和inttypes.h分类:C 2009-10-20 18:06 931人阅读评论(0) 收藏举报C语言的基本精神是让实现选择标准类型的长度,但是这种指导思想使可移植代码难以编写。
C99中引入了stdint.h和inttypes.h,对整数类型的定义和格式转换进行了规范。
这种扩展整数类型的定义非常清晰,从类型名字上就可以看出它的长度,这有利于编写可移植的代码。
stint.h对整数类型进行定义,inttypes.h包含了stdint.h并增加了可移植的格式控制串和转换函数。
1、stdint.h:定义标准的扩展整数类型。
包括准确长度类型intN_t、最小长度类型int_leastN_t、快速长度类型int_fastN_t、指针长度类型intptr_t、最大长度类型intmax_t(N 为类型宽度)。
定义规则:1)类型的长度用宽度N参数化,如intN_t,N常常有8,16,32,64。
2)若要定义某种类型,则该类型的带符号和无符号类型、类型长度都要定义。
如定义int32_t,则有uint32_t类型。
3)要用...MIN和...MAX宏定义类型的范围。
如INT32_MIN,INT32_MAX,UINT32_MAX。
4)在inttypes.h要用PRIcKN和SCNcKN定义打印该类型的printf和scanf格式控制字符串。
c表示转换操作符,有d,i,o,u,x或X;K表示种类,为空或者LEAST,FAST,PTR,MAX;N是该类型的宽度。
view plaincopy to clipboardprint?1. /* ISO C99: 7.18 整数类型 <stdint.h> */2. #ifndef _STDINT_H3. #define _STDINT_H 14. #include <features.h>5. #include <bits/wchar.h>6. #include <bits/wordsize.h>7. /* 准确类型:指定长度的准确类型 */8. /* 有符号 */9. /* 有一些与<sys/types.h>中众所周知的inet代码重叠 */10. #ifndef __int8_t_defined11. # define __int8_t_defined12. typedef signed char int8_t; /* 8位的准确长度类型int8_t=signed char */13. typedef short int int16_t; /* 16位的准确长度类型 */14. typedef int int32_t;15. # if __WORDSIZE == 6416. typedef long int int64_t; /* 64位平台上64位的准确类型为long */17. # else18. __extension__19. typedef long long int int64_t; /* 32位平台上64位的准确类型为long long */20. # endif21. #endif22. /* 无符号 */23. typedef unsigned char uint8_t;24. typedef unsigned short int uint16_t;25. #ifndef __uint32_t_defined26. typedef unsigned int uint32_t;27. # define __uint32_t_defined28. #endif29. #if __WORDSIZE == 6430. typedef unsigned long int uint64_t;31. #else32. __extension__33. typedef unsigned long long int uint64_t;34. #endif35.36. /* 最小类型:指定长度的最小类型 */37. /* 有符号 */38. typedef signed char int_least8_t;39. typedef short int int_least16_t;40. typedef int int_least32_t;41. #if __WORDSIZE == 6442. typedef long int int_least64_t;43. #else44. __extension__45. typedef long long int int_least64_t;46. #endif47. /* 无符号 */48. typedef unsigned char uint_least8_t;49. typedef unsigned short int uint_least16_t;50. typedef unsigned int uint_least32_t;51. #if __WORDSIZE == 6452. typedef unsigned long int uint_least64_t;53. #else54. __extension__55. typedef unsigned long long int uint_least64_t;56. #endif57.58. /* 快速类型:指定长度的最快类型 */59. /* 有符号 */60. typedef signed char int_fast8_t;61. #if __WORDSIZE == 64 /* 64位平台 */62. typedef long int int_fast16_t;63. typedef long int int_fast32_t;64. typedef long int int_fast64_t;65. #else /* 32位平台 */66. typedef int int_fast16_t; /* 16位和32位的最快类型均为int */67. typedef int int_fast32_t;68. __extension__69. typedef long long int int_fast64_t;70. #endif71. /* 无符号 */72. typedef unsigned char uint_fast8_t;73. #if __WORDSIZE == 6474. typedef unsigned long int uint_fast16_t;75. typedef unsigned long int uint_fast32_t;76. typedef unsigned long int uint_fast64_t;77. #else78. typedef unsigned int uint_fast16_t;79. typedef unsigned int uint_fast32_t;80. __extension__81. typedef unsigned long long int uint_fast64_t;82. #endif83.84. /* 通用指针类型:即void * 型指针的类型,64位平台上为long,32位平台上为int */85. #if __WORDSIZE == 6486. # ifndef __intptr_t_defined87. typedef long int intptr_t;88. # define __intptr_t_defined89. # endif90. typedef unsigned long int uintptr_t;91. #else92. # ifndef __intptr_t_defined93. typedef int intptr_t;94. # define __intptr_t_defined95. # endif96. typedef unsigned int uintptr_t;97. #endif98.99. /* 最大类型:指定长度的最大整数类型 */100. #if __WORDSIZE == 64101. typedef long int intmax_t; /* 64位平台上的最大整数类型为long */ 102. typedef unsigned long int uintmax_t;103. #else104. __extension__105. typedef long long int intmax_t; /* 32位平台上的最大整数类型为long long */106. __extension__107. typedef unsigned long long int uintmax_t;108. #endif109. /* ISO C99标准指出,在C++实现中这些宏应该只在被请求到的时候才定义 */110. #if !defined __cplusplus || defined __STDC_LIMIT_MACROS111. # if __WORDSIZE == 64112. # define __INT64_C(c) c ## L113. # define __UINT64_C(c) c ## UL114. # else115. # define __INT64_C(c) c ## LL116. # define __UINT64_C(c) c ## ULL117. # endif118. /* 整数类型的范围 */119. /* 有符号整数类型的最小值:-2**(N-1),其中最小负数-2**(N-1)=100...0没有对应正数,其反数还是自己 */120. # define INT8_MIN (-128)121. # define INT16_MIN (-32767-1)122. # define INT32_MIN (-2147483647-1)123. # define INT64_MIN (-__INT64_C(9223372036854775807)-1)124. /* 有符号整数类型的最大值:2**(N-1)-1 */125. # define INT8_MAX (127)126. # define INT16_MAX (32767)127. # define INT32_MAX (2147483647)128. # define INT64_MAX (__INT64_C(9223372036854775807))129. /* 无符号整数类型的最大值:2**(N-1)-1,注意有Min=-MAX-1 */130. # define UINT8_MAX (255)131. # define UINT16_MAX (65535)132. # define UINT32_MAX (4294967295U)133. # define UINT64_MAX (__UINT64_C(18446744073709551615))134.135. /* 有符号最小类型的最小值 */136. # define INT_LEAST8_MIN (-128)137. # define INT_LEAST16_MIN (-32767-1)138. # define INT_LEAST32_MIN (-2147483647-1)139. # define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1) 140. /* 有符号最小类型的最大值 */141. # define INT_LEAST8_MAX (127)142. # define INT_LEAST16_MAX (32767)143. # define INT_LEAST32_MAX (2147483647)144. # define INT_LEAST64_MAX (__INT64_C(9223372036854775807)) 145. /* 无符号最小类型的最大值 */146. # define UINT_LEAST8_MAX (255)147. # define UINT_LEAST16_MAX (65535)148. # define UINT_LEAST32_MAX (4294967295U)149. # define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))150.151. /* 有符号快速类型的最小值 */152. # define INT_FAST8_MIN (-128)153. # if __WORDSIZE == 64154. # define INT_FAST16_MIN (-9223372036854775807L-1)155. # define INT_FAST32_MIN (-9223372036854775807L-1)156. # else157. # define INT_FAST16_MIN (-2147483647-1)158. # define INT_FAST32_MIN (-2147483647-1)159. # endif160. # define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1) 161. /* 有符号快速类型的最大值 */162. # define INT_FAST8_MAX (127)163. # if __WORDSIZE == 64164. # define INT_FAST16_MAX (9223372036854775807L)165. # define INT_FAST32_MAX (9223372036854775807L)166. # else167. # define INT_FAST16_MAX (2147483647)168. # define INT_FAST32_MAX (2147483647)169. # endif170. # define INT_FAST64_MAX (__INT64_C(9223372036854775807)) 171. /* 无符号快速类型的最大值 */172. # define UINT_FAST8_MAX (255)173. # if __WORDSIZE == 64174. # define UINT_FAST16_MAX (18446744073709551615UL)175. # define UINT_FAST32_MAX (18446744073709551615UL)176. # else177. # define UINT_FAST16_MAX (4294967295U)178. # define UINT_FAST32_MAX (4294967295U)179. # endif180. # define UINT_FAST64_MAX (__UINT64_C(18446744073709551615))181.182. /* 指针类型(持有void*型指针)的范围 */183. # if __WORDSIZE == 64184. # define INTPTR_MIN (-9223372036854775807L-1)185. # define INTPTR_MAX (9223372036854775807L)186. # define UINTPTR_MAX (18446744073709551615UL)187. # else188. # define INTPTR_MIN (-2147483647-1)189. # define INTPTR_MAX (2147483647)190. # define UINTPTR_MAX (4294967295U)191. # endif192.193. /* 有符号最大类型的最小值 */194. # define INTMAX_MIN (-__INT64_C(9223372036854775807)-1) 195. /* 符号最大类型的最大值 */196. # define INTMAX_MAX (__INT64_C(9223372036854775807)) 197. /* 无符号最大类型的最大值 */198. # define UINTMAX_MAX (__UINT64_C(18446744073709551615)) 199.200. /* 其他整数类型的范围 */201. /* ptrdiff_t类型的范围 */202. # if __WORDSIZE == 64203. # define PTRDIFF_MIN (-9223372036854775807L-1)204. # define PTRDIFF_MAX (9223372036854775807L)205. # else206. # define PTRDIFF_MIN (-2147483647-1)207. # define PTRDIFF_MAX (2147483647)208. # endif209. /* sig_atomic_t类型的范围 */210. # define SIG_ATOMIC_MIN (-2147483647-1)211. # define SIG_ATOMIC_MAX (2147483647)212. /* size_t类型的范围 */213. # if __WORDSIZE == 64214. # define SIZE_MAX (18446744073709551615UL)215. # else216. # define SIZE_MAX (4294967295U)217. # endif218. /* wchar_t类型的范围 */219. # ifndef WCHAR_MIN220. /* 这些常量可能在<wchar.h>也定义了 */221. # define WCHAR_MIN __WCHAR_MIN222. # define WCHAR_MAX __WCHAR_MAX223. # endif224. /* wint_t类型的范围 */225. # define WINT_MIN (0u)226. # define WINT_MAX (4294967295u)227. #endif /* C++ && limit macros */228. /* ISO C99标准指出,在C++实现中这些宏应该只在被请求到的时候才定义 */229. #if !defined __cplusplus || defined __STDC_CONSTANT_MACROS 230. /* 有符号 */231. # define INT8_C(c) c232. # define INT16_C(c) c233. # define INT32_C(c) c234. # if __WORDSIZE == 64235. # define INT64_C(c) c ## L236. # else237. # define INT64_C(c) c ## LL238. # endif239. /* 无符号 */240. # define UINT8_C(c) c241. # define UINT16_C(c) c242. # define UINT32_C(c) c ## U243. # if __WORDSIZE == 64244. # define UINT64_C(c) c ## UL245. # else246. # define UINT64_C(c) c ## ULL247. # endif248. /* 最大类型 */249. # if __WORDSIZE == 64250. # define INTMAX_C(c) c ## L251. # define UINTMAX_C(c) c ## UL 252. # else253. # define INTMAX_C(c) c ## LL 254. # define UINTMAX_C(c) c ## ULL 255. # endif256. #endif /* C++ && constant macros */ 257. #endif /* stdint.h */正数,其反数还是自己。
扩展Int 13H调用规范第一部分简介一.硬盘结构简介1.硬盘参数释疑到目前为止,人们常说的硬盘参数还是古老的CHS(Cylinder/Head/Sector)参数。
那么为什么要使用这些参数,它们的意义是什么?它们的取值范围是什么?很久以前,硬盘的容量还非常小的时候,人们采用与软盘类似的结构生产硬盘。
也就是硬盘盘片的每一条磁道都具有相同的扇区数。
由此产生了所谓的3D参数(DiskGeometry)。
即磁头数(Heads),柱面数(Cylinders),扇区数(Sectors),以及相应的寻址方式。
其中:①磁头数(Heads)表示硬盘总共有几个磁头,也就是有几面盘片,最大为255(用8个二进制位存储);②柱面数(Cylinders)表示硬盘每一面盘片上有几条磁道,最大为1023(用10个二进制位存储);③扇区数(Sectors)表示每一条磁道上有几个扇区,最大为63(用6个二进制位存储)。
每个扇区一般是512个字节,理论上讲这不是必须的,但都选择这个值。
所以磁盘最大容量为:255*1023*63*512/1048576=8024MB(1MB=1048576Bytes)或硬盘厂商常用的单位:255*1023*63*512/1000000=8414MB(1MB=1000000Bytes)在CHS寻址方式中,磁头,柱面,扇区的取值范围分别为0到Heads-1,0到Cylinders-1,1到Sectors(注意是从1开始)。
2.基本Int13H调用简介BIOS Int13H调用是BIOS提供的磁盘基本输入输出中断调用,它可以完成磁盘(包括硬盘和软盘)的复位,读写,校验,定位,诊断,格式化等功能。
它使用的就是CHS寻址方式,因此最大识能访问8GB左右的硬盘。
3.现代硬盘结构简介在老式硬盘中,由于每个磁道的扇区数相等,所以外道的记录密度要远低于内道,因此会浪费很多磁盘空间(与软盘一样)。
为了解决这一问题,进一步提高硬盘容量,人们改用等密度结构生产硬盘。
也就是说,外圈磁道的扇区比内圈磁道多。
采用这种结构后,硬盘不再具有实际的3D参数,寻址方式也改为线性寻址,即以扇区为单位进行寻址。
为了与使用3D寻址的老软件兼容(如使用BIOS Int13H接口的软件),在硬盘控制器内部安装了一个地址翻译器,由它负责将老式3D参数翻译成新的线性参数。
这也是为什么现在硬盘的3D参数可以有多种选择的原因(不同的工作模式,对应不同的3D参数,如LBA,LARGE,NORMAL)。
4.扩展Int13H简介虽然现代硬盘都已经采用了线性寻址,但是由于基本Int13H的制约,使用BIOS Int13H 接口的程序,如DOS等还只能访问8G以内的硬盘空间。
为了打破这一限制,Microsoft等几家公司制定了扩展Int13H标准(ExtendedInt13H),采用线性寻址方式存取硬盘,所以突破了8G的限制,而且还加入了对可拆卸介质(如活动硬盘)的支持。
二.BootSector结构简介1.BootSector的组成BootSector也就是硬盘的第一个扇区,它由MBR(MasterBootRecord),DPT(DiskPartitionTable)和BootRecordID三部分组成。
MBR又称作主引导记录占用BootSector的前446个字节(0to0x1BD),存放系统主引导程序(它负责从活动分区中装载并运行系统引导程序)。
DPT即主分区表占用64个字节(0x1BE~0x1FD),记录了磁盘的基本分区信息。
主分区表分为四个分区项,每项16字节,分别记录了每个主分区的信息(因此最多可以有四个主分区)。
BootRecordID即引导区标记占用两个字节(0x1FE and 0x1FF),对于合法引导区,它等于0xAA55,这是判别引导区是否合法的标志。
BootSector的具体结构如下图所示:Offset0000HOffset01BDHOffset01BEHOffset01CDHOffset01CEHOffset01DDHOffset01DEHOffset01EDHOffset01EEHOffset01FDHOffset01FEHOffset01FFHMasterBootRecord主引导记录(446字节)分区信息1分区信息2分区信息3分区信息4校验字0xAA552.分区表结构简介分区表由四个分区项构成,每一项的结构如下:BYTEState :分区状态,0=未激活,0x80=激活(注意此项)BYTEStartHead :分区起始磁头号WORDStartSC :分区起始扇区和柱面号,底字节的低6位为扇区号,高2位为柱面号的第9,10位,高字节为柱面号的低8位BYTEType :分区类型,如0x0B=FAT32,0x83=Linux等,00表示此项未用(注1) BYTEEndHead :分区结束磁头号WORDEndSC :分区结束扇区和柱面号,定义同前DWORDRelative :在线性寻址方式下的分区相对扇区地址(对于基本分区即为绝对地址)DWORDSectors :分区大小(总扇区数)注意:在DOS/Windows系统下,基本分区必须以柱面为单位划分(Sectors*Heads个扇区),如对于CHS为764/255/63的硬盘,分区的最小尺寸为255*63*512/1048576=7.844MB。
3.扩展分区简介由于主分区表中只能分四个分区,无法满足需求,因此设计了一种扩展分区格式。
基本上说,扩展分区的信息是以链表形式存放的,但也有一些特别的地方。
首先,主分区表中要有一个基本扩展分区项,所有扩展分区都隶属于它,也就是说其他所有扩展分区的空间都必须包括在这个基本扩展分区中。
对于DOS/Windows来说,扩展分区的类型为0x05。
除基本扩展分区以外的其他所有扩展分区则以链表的形式级联存放,后一个扩展分区的数据项记录在前一个扩展分区的分区表中,但两个扩展分区的空间并不重叠。
扩展分区类似于一个完整的硬盘,必须进一步分区才能使用。
但每个扩展分区中只能存在一个其他分区。
此分区在DOS/Windows环境中即为逻辑盘。
因此每一个扩展分区的分区表(同样存储在扩展分区的第一个扇区中)中最多只能有两个分区数据项(包括下一个扩展分区的数据项)。
第二部分扩展Int13H技术资料一.简介设计扩展Int13H接口的目的是为了扩展BIOS的功能,使其支持多于1024柱面的硬盘,以及可移动介质的锁定,解锁及弹出等功能。
二.数据结构1.数据类型约定BYTE 1字节整型( 8位)WORD 2字节整型(16位)DWORD 4字节整型(32位)QWORD 8字节整型(64位)2.磁盘地址数据包DiskAddressPacket(DAP)DAP是基于绝对扇区地址的,因此利用DAP,Int13H可以轻松地逾越1024柱面的限制,因为它根本就不需要CHS的概念。
DAP的结构如下:structDiskAddressPacket{BYTE PacketSize; //数据包尺寸(16字节)BYTE Reserved; //==0WORD BlockCount; //要传输的数据块个数(以扇区为单位)DWORD BufferAddr; //传输缓冲地址(segment:offset)QWORD BlockNum; //磁盘起始绝对块地址};PacketSize保存了DAP结构的尺寸,以便将来对其进行扩充。
在目前使用的扩展Int13H 版本中PacketSize恒等于16。
如果它小于16,扩展Int13H将返回错误码(AH=01,CF=1)。
BlockCount对于输入来说是需要传输的数据块总数,对于输出来说是实际传输的数据块个数。
BlockCount=0表示不传输任何数据块。
BufferAddr是传输数据缓冲区的32位地址(段地址:偏移量)。
数据缓冲区必须位于常规内存以内(1M)。
BlockNum表示的是从磁盘开始算起的绝对块地址(以扇区为单位),与分区无关。
第一个块地址为0。
一般来说,BlockNum与CHS地址的关系是:BlockNum=(cylinder*NumberOfHeads+head)*SectorsPerTrack+sector-1;其中cylinder,head,sector是CHS地址,NumberOfHeads是磁盘的磁头数,SectorsPerTrack是磁盘每磁道的扇区数。
也就是说BlockNum是沿着扇区->磁道->柱面的顺序记数的。
这一顺序是由磁盘控制器虚拟的,磁盘表面数据块的实际排列顺序可能与此不同(如为了提高磁盘速度而设置的间隔因子将会打乱扇区的排列顺序)。
3.驱动器参数数据包DriveParametersPacket驱动器参数数据包是在扩展Int13H的取得驱动器参数子功能调用中使用的数据包。
格式如下:structDriveParametersPacket{WORD InfoSize; //数据包尺寸(26字节)WORD Flags; //信息标志DWORD Cylinders; //磁盘柱面数DWORD Heads; //磁盘磁头数DWORD SectorsPerTrack; //每磁道扇区数QWORD Sectors; //磁盘总扇区数WORD SectorSize; //扇区尺寸(以字节为单位)};信息标志用于返回磁盘的附加信息,每一位的定义如下:0位:0=可能发生DMA边界错误1=DMA边界错误将被透明处理如果这位置1,表示BIOS将自动处理DMA边界错误,也就是说错误代码09H永远也不会出现.1位:0=未提供CHS信息1=CHS信息合法如果块设备的传统CHS几何信息不适当的话,该位将置0.2位:0=驱动器不可移动1=驱动器可移动3位:表示该驱动器是否支持写入时校验.4位:0=驱动器不具备介质更换检测线1=驱动器具备介质更换检测线5位:0=驱动器不可锁定1=驱动器可以锁定要存取驱动器号大于0x80的可移动驱动器,该位必须置1(某些驱动器号为0到0x7F的设备也需要置位)6位:0=CHS值是当前存储介质的值(仅对于可移动介质),如果驱动器中有存储介质,CHS值将被返回.1=CHS值是驱动器支持的最大值(此时驱动器中没有介质).7-15位:保留,必须置0.三.接口规范1.寄存器约定在扩展Int13H调用中一般使用如下寄存器约定:ds:si==>磁盘地址数据包(diskaddresspacket)dl==>驱动器号ah==>功能代码/返回码在基本Int13H调用中,0-0x7F之间的驱动器号代表可移动驱动器0x80-0xFF之间的驱动器号代表固定驱动器。
但在扩展Int13H调用中0x80-0xFF之间还包括一些新出现的可移动驱动器,比如活动硬盘等。