注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

DOS编程技术

讨论在纯DOS下的编程技术

 
 
 

日志

 
 
关于我

1984年大学毕业,1985年底有机会开始接触PC机,1986年开始在PC机上做开发工作,曾接触过MS-DOS、CP/M、UNIX、VMS、LINUX、iRMX等众多的操作系统并在上面从事技术开发,擅长做底层与硬件相关的软件开发,目前主要在DOS和LINUX平台下工作,主要从事软件,在硬件开发上也有一定造诣,亦有在8051系列、6502系列(凌阳)、z80系列、ARM、X86等各类平台下开发软硬件的经历。更详细情况可以参考http://resume.whowin.net

网易考拉推荐

GRUB主引导扇区分析  

2009-09-03 10:53:08|  分类: 杂七杂八 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

前一篇文章,我们一起分析了一下DOS的主引导扇区,在网上分析DOS主引导扇区的文章比较多,如果看我写的感觉有困难,到网上随便搜一下,应该一抓一大把。

写人家写过的东西,似乎不是我的风格,我写DOS主引导扇区的分析其实还是为了引出后面的两个主题,一个是GRUB主引导扇区的分析,还有就是主引导扇区的应用。

DOS的主引导程序,实际已经很少有地方用了,因为DOS的分区最大只能有2G,4个分区也只能是8G,大于8G以后的分区,DOS是引导不了的,个中原因,我不说,大家可以想一想。

百度了一下,好像分析GRUB主引导扇区的几乎没有,我这篇文章准备补一下这个空白。

GRUB是什么?可能有些人还不知道,它是一个Boot Loader,Linux下经常会用它引导(好像现在较高版本内核的发行Linux大多数都在用GRUB),GRUB其实分好几部分,其中一部分就放在主引导扇区中,今天我们就把它搞出来翻它个底儿掉。

其实不管是什么Boot Loader,其目的都是把分区引导扇区给读出来,然后稳稳地把控制权交给分区引导程序,至于你分区引导程序能不能引导起什么东东来,它不管,也管不了,GRUB的主引导程序也是一样,一定要记住,主引导程序的目的就是把分区引导扇区给读出来然后把控制权交给分区引导程序。

总在说主引导扇区和分区引导扇区,我怕有些读者可能会越来越乱,所以不妨再啰嗦几句。主引导扇区指的是硬盘上的0磁头、0磁道、1扇区,这个扇区是不属于任何分区的,不同的分区软件在实际进行分区时开始的位置不一样,但一般至少会把0磁头、0磁道给空出来不分给任何分区,有的地方把空出来的这些扇区叫做隐藏扇区;分区引导扇区是所在分区里的第一个扇区,比如一个分区从0磁头、5磁道、1扇区开始,那么分区引导扇区就在0磁头、5磁道、1扇区;PC机在启动时,BIOS并不去理会硬盘是怎么分区的,每个分区中安装着什么操作系统,而是直接去读硬盘上的主引导扇区,并且把控制权交给主引导程序,硬盘启动那个分区,全看硬盘上的启动程序,而基本的主引导程序的任务就是根据设置读出相应分区的分区引导程序,并把控制权交给分区引导程序。

好了,我们接着说我们的GRUB下的主引导扇区。

1、如何获得GRUB下的主引导扇区

和上一篇分析的DOS下的主引导扇区不同,GRUB下的主引导程序使用的386的32位的指令系统(DOS的主引导程序是用的16位的指令系统),所以使用DOS自带的debug程序是不能完整地反编译GRUB下的主引导程序的,因为debug只会反编译16位的指令,为此,我们要使用DOS下的32位版本的debug程序----debug32。

如果你手头没有这个工具,可以在下面地址下载:

DEBUG32下载地址:http://blog.whowin.net/software/debug32.zip(2017年3月22日注:链接已修复)

我正好手里有一张自己编译的linux的CF卡,把这张卡用IDE的CF卡座安装在PC机上,可以启动一个小巧的linux,这张linux的CF卡使用GRUB引导的,我把这张卡通过USB的CF卡读卡器连接到可以启动DOS的机器上,启动dos,同时驱动USB(DOS下驱动U盘的方法请参阅本博客以前的博文《关于构建DOS下编程平台的总结》),这样,USB下的这张CF卡就成为了DOS下的另一个硬盘,加入原来机器上只连接这一块硬盘,其驱动器标识为80h(在使用int 13h时使用),那么这张CF卡的驱动器标识就是81h,在debug32下使用下面的程序就可以读出主引导程序。 

  GRUB主引导扇区分析 - whowin - DOS编程技术

这段小程序的具体含义,在上一篇文章《DOS主引导扇区分析》中已经做了介绍,这里就不再赘述了。

还有一个方法可以获得GRUB下的主引导扇区,我也做了尝试,效果很好。

在我以前的博客文章中介绍过VirtualBox虚拟机,你可以在这个虚拟机上安装一个使用GRUB引导的linux,再安装一个DOS6.22(不要忘了在DOS下把debug32程序拷过来),然后把安装linux的那个虚拟硬盘安装成DOS下的第二块硬盘,启动DOS,DOS下就有了两块硬盘,尽管第二块硬盘DOS不能使用(因为它识别不了它的文件系统),但并不妨碍我们读取它的主引导扇区,使用上面的那段debug32下的小程序就可以把主引导扇区给读出来。

当然,我们也可以从linux下直接获得主引导扇区,方法如下:

  • 确定linux是使用grub引导的
  • 使用root登录系统(因为下面命令需要root权限)
  • 执行命令dd if=/dev/xxx of=bootsec.bin bs=512 count=1
    其中,/dev/xxx为引导设备的设备名,如果你不清楚,可以使用fdisk -l命令看一下,命令执行以后,文件bootsec.bin中就是整个的主引导扇区。
    Linux下命令的解释超出了本文的范围,以下是一个执行情况的屏幕截图GRUB主引导扇区分析 - whowin - DOS编程技术
    首先执行fdisk -l得到引导设备为/dev/sda1,然后执行dd命令把引导扇区存储在bootsec.Bin文件中。
    注意其中一个细节,fdisk -l列出引导分区为/dev/sda1,而我们在执行dd命令时却是用设备/dev/sda,这是由于我们要读取主引导扇区,主引导扇区并不属于那个分区,而/dev/sda1表示引导分区,请仔细体会/dev/sda和/dev/sda1的不同。
  • 将文件通过U盘、网络或者samba服务器共享等方式将bootsec.bin从linux系统中拷贝出来,供下面在DOS下研究所用

如果你对linux系统不熟悉,可以不了解这部分,对linux下的命令的说明超出了本文的范围。

这样获得的主引导扇区文件,无法使用上面的小程序读出,在实际使用debug32来调入主引导扇区文件bootsec.Bin的过程中,我个人感觉debug32可能有一些BUG,或者是我对它的了解还不够。

首先,按照debug32中help的说法,我可以用下面命令把文件调入,load bootsec.bin 7c00,但实际上不行,用这种方法,只能将bootsec.bin调入到0x0100处而不是像help中说的在0x7c00处;同样,我按照help中的说明又试了一些其他的命令及组合,均无法把我们的主引导扇区文件调入到0x7c00处,甚至按照help的说明我试图在debug32下使用move命令将主引导扇区的内容从0x0100处移到0x7c00处,试了多次均以死机而告终,如果有读者能够了解其中的原因,烦请告诉我,谢谢,联系email:hengch@163.Com。

但是我们还是要把主引导扇区文件想办法放到0x7c00的地方,最后我不得已在debug32中变了一小段程序来完成将主引导扇区从0x0100搬移到0x7c00的工作,我把这小段程序放在0x500的地方,实际的屏幕截图如下:

GRUB主引导扇区分析 - whowin - DOS编程技术

上例中我们没有用debug32下load命令来装载文件bootsec.Bin,而是使用命令行来直接把bootsec.Bin装载到内存,这两种方法都是一样的。

至此,我们介绍了三种获得grub下主引导扇区的办法,读者可以根据自己的情况选用。

2、扩展int 13h说明

扩展int 13h并不是本文的重点,因为在下面分析代码时要用到,所以仅就其中用到的部分做一个简短的说明。

传统的int 13h调用,使用CHS(柱面、磁头、扇区)的方法来表示一个扇区,这种方法可以表示的最大磁盘容量仅为8G(请参考有关资料);现代硬盘的容量已经远远超过了8G,硬盘结构也较以前有了非常大的变化,CHS的表示方法已经过时,现代硬盘无一例外第采用线性寻址方式,为了适应现代硬盘的发展,出现了扩展int 13h。

下面就程序中用到的几个扩展int 13h调用做一个说明

1) 检验扩展功能是否存在

   入口:

       AH = 41h
           BX = 55AAh
           DL = 驱动器号

   返回:

       CF = 0
           AH = 扩展功能的主版本号
           AL = 内部使用
           BX = AA55h
           CX = API子集支持位图
           CF = 1
           AH = 错误码 01h,无效命令

2) 扩展读扇区

   入口:

       AH = 42h
           DL = 驱动器号
           DS:DI = 磁盘地址数据包DAP(Disk Address Packet)

   返回:

       CF = 0,AH = 0 成功
           CF = 1,AH = 错误码

这个调用将磁盘上的数据读入内存。如果出现错误,DAP的BlockCount项中则记录了出错前实际读取的数据块个数。

DAP(Disk Address Packet)说明:

struct DiskAddressPacket
    {
        BYTE PacketSize;  // 数据包尺寸(恒定为16字节)
        BYTE Reserved;    // ==0
        WORD BlockCount;  // 要传输的数据块个数(以扇区为单位)
        DWORD BufferAddr; // 传输缓冲地址(segment:offset)
        QWORD BlockNum;   // 起始绝对扇区号
    };

绝对扇区号与CHS的换算关系:
    扇区号(S)≡(绝对扇区号 % 每磁道扇区数) + 1
    磁头号(H)≡(绝对扇区号 / 每磁道扇区数) % 磁头数
    磁道号(C)≡(绝对扇区号 / 每磁道扇区数) / 磁头数

3、GRUB下主引导扇区内数据结构说明

这部分说明一会儿分析程序的时候会用到,现在你可以先不看,但当你开始看程序时你应该会想起这里的说明。

我们假定把GRUB的主引导扇区读到了7C00h的地方,从7C04h到7C49h有一段数据区,其说明如下:

[7C04h] BYTE ---- 是否支持扩展int 13h的标志,1:表示支持,0:表示不支持

当使用扩展int 13h读扇区时,从7C05h开始的16个字节是DAP结构:

[7C05h] BYTE PacketSize;  // 数据包尺寸(恒定为16字节)
    [7C06h] BYTE Reserved;    // ==0
    [7C07h] WORD BlockCount;  // 要传输的数据块个数(以扇区为单位)
    [7C09h] DWORD BufferAddr; // 传输缓冲地址(segment:offset)
    [7C0Dh] QWORD BlockNum;   // 起始绝对扇区号

当使用普通int 13h读扇区时,从7C05h开始的数据和上面有所不同

[7C05h] DWORD ---- 每磁道的扇区数
    [7C09h] DWORD ---- 磁头数
    [7C0Dh] DWORD ---- 柱面数(磁道数)

以下部分为通用:

[7C40h]  BYTE ---- 启动盘标识,0FFh:标识使用缺省启动盘,否则bit7=1为合法值
    [7C41h]  BYTE ---- 这个标识用程序中用了一次,感觉意义不大,可以忽略
    [7C42h]  WORD ---- 分区引导程序的执行入口。这是一个偏移地址,主引导程序假定读入的分区引导程序最后搬移到的位置一定在以分段地址为0的64KB区域内,由于主引导扇区也在这个分段内,所以只要有偏移地址就可以了。
    [7C44h] DWORD ---- 分区引导扇区所在的绝对扇区号
    [7C48h]  WORD ---- 搬移分区引导扇区时,搬移的目的段地址,搬移时偏移地址恒为0。 

4、程序中用到的其他BIOS调用说明

int 13h ah=08h -- 取当前驱动器参数

入口: ah=08h
           dl=驱动器标识,80h:第一块硬盘,81h:第二块硬盘......

出口: DL 列出练级硬盘的数目
           DH 当前硬盘的最大磁头号
           CH 存放10位最大磁道柱面号的低8位
           CL 0--5位存放最大可用扇区数目,第6、7位是磁道柱面号的高2位

错误信息:
           若检测出错误,CF=1,错误代码放在AH中

5、GRUB下的主引导程序流程图

 GRUB主引导扇区分析 - whowin - DOS编程技术

(点击上图可看原图)

 

6、GRUB下主引导程序分析

以下代码是使用debug32反汇编过来的,为了阅读方便,和前一篇文章一样,去掉了段地址部分和汇编码(opcode)部分,在每行的后面加上了注释,结合上一节的流程图,以及前几节的相关知识介绍,看懂应该没有问题。

注意,是使用debug32反汇编过来的。由于GRUB下的主引导程序使用32位的汇编指令完成,所以用DOS自带的debug反汇编会有些问题。

7C00   JMP Short 7C4A

7C00 EB 48 90 00 00 00 00 00-00 00 00 00 00 00 00 00
    7C10 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
    7C20 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
    7C30 00 00 00 00 00 00 00 00-00 00 00 00 00 00 03 02
    7C40 FF 00 00 20 01 00 00 00-00 02 FA 90 90 F6 C2 80

7C4A   CLI                              ;关中断
    7C4B   NOP
    7C4C   NOP
    7C4D   TEST DL,80h                      ;检查DL是否为一个合法的驱动器标识
    7C50   JNZ Short 7C54                   ;DL是一个合法的驱动器标识
    7C52   MOV DL,80h                       ;DL设置为第一个硬盘的标志
    7C54   JMP 0000:7C59                    ;继续执行
    7C59   XOR AX,AX                        ;AX=0
    7C5B   MOV DS,AX                        ;DS=0
    7C5D   MOV SS,AX                        ;SS=0
    7C5F   MOV SP,2000h                     ;SP=2000h栈顶
    7C62   STI                              ;开中断
    7C63   MOV AL,[7C40]                    ;[7C40]为启动盘标识

    7C66   CMP AL,0FFh                      ;检查启动盘标志是否为0FFh
    7C68   JZ Short 7C6C                    ;[7C40]为0FFh,表示使用缺省的驱动器启动
    7C6A   MOV DL,AL                        ;[7C40]<>0FFh,表示要求使用[7C40]中表示的驱动器启动
    7C6C   PUSH DX                          ;保存DL中的启动盘标识
    7C6D   TEST DL,80h                      ;检查DL中的盘标识是否合法
    7C70   JZ Short 7CC6                    ;DL的值不合法,有问题
    7C72   MOV AH,41h                       ;扩展int13h功能代码
    7C74   MOV BX,55AAh                     ;该调用要求的输入值,见说明
    7C77   INT 13h                          ;检测BIOS是否支持扩展INT 13h
    7C79   POP DX                           ;恢复DL中的启动盘标识
    7C7A   PUSH DX
    7C7B   JB Short 7CC6                    ;BIOS不支持扩展int 13h
    7C7D   CMP BX,0AA55h
    7C81   JNZ Short 7CC6                   ;BIOS不支持扩展int 13h
    7C83   MOV AL,[7C41]                    ;
    7C86   TEST AL,AL                       ;
    7C88   JNZ Short 7C8F
    7C8A   AND CX,01h                       ;是否支持扩展int 13h的第一子集
    7C8D   JZ Short 7CC6                    ;不支持扩展int 13h的第一子集
    ;至此,表明BIOS至少支持扩展int 13h的第一子集
    7C8F   MOV ECX,[SI+10h]                 ;笔者认为此指令毫无意义,因为此时SI还没有赋值
    7C93   MOV SI,7C05h                     ;指向DAP的指针,准备开始使用扩展int 13h读扇区
    7C96   MOV Byte Ptr [SI-01h],01h        ;置标志,表明支持扩展int 13h
    7C9A   MOV EBX,[7C44]                   ;启动分区的起始绝对扇区号,也就是分区引导扇区的位置
    ;从这里开始填写DAP结构,以便扩展int 13h的42h功能调用使用,请参阅有关说明
    7C9F   MOV Word Ptr [SI],0010h          ;DAP,数据包尺寸,恒定为16
    7CA3   MOV Word Ptr [SI+02h],0001h      ;要传输的数据块,1个扇区
    7CA8   MOV [SI+08h],EBX                 ;分区起始绝对扇区号,也就是分区引导扇区的位置
    7CAC   MOV Word Ptr [SI+06h],7000h      ;传输缓冲区段地址,读出扇区的存放位置
    7CB1   XOR EAX,EAX                      ;EAX=0
    7CB4   MOV [SI+04h],AX                  ;传输缓冲区偏移地址
    7CB7   MOV [SI+0Ch],EAX                 ;磁盘起始绝对块地址补0
    7CBB   MOV AH,42h                       ;读扇区功能号
    7CBD   INT 13h                          ;读磁盘扇区
    7CBF   JB Short 7CC6                    ;读盘失败,认为不支持扩展int 13h
    7CC1   MOV BX,7000h                     ;读出的分区引导扇区的段地址
    7CC4   JMP Short 7D43
    ;BIOS不支持扩展int 13h,使用普通int 13h读分区引导扇区
    7CC6   MOV AH,08h
    7CC8   INT 13h                          ;取当前驱动器参数,此时DL为启动盘标识
    7CCA   JNB Short 7CD6                   ;int 13h执行成功
    7CCC   TEST DL,80h
    7CCF   JZ 7DC3                          ;不是硬盘,程序跑飞,这个跳转跑到了一个没有代码的地方
    7CD3   JMP 7D63                         ;显示Hard Disk Error,然后进入死循环
    ;获取当前驱动器参数成功,请仔细参阅第4节关于该调用的返回值
    7CD6   MOV SI,7C05h                     ;尽管与扩展int13h调用时使用了相同的指针,但其数据结构是不同的,请参阅相关说明
    7CD9   MOV Byte Ptr [SI-01h],00h        ;不支持扩展int 13h的标志
    7CDD   XOR EAX,EAX
    7CE0   MOV AL,DH                        ;DH=最大磁头号
    7CE2   INC AX                           ;磁头数量
    7CE3   MOV [SI+04h],EAX
    7CE7   XOR DX,DX
    7CE9   MOV DL,CL                        ;CL中bit6:7为最大柱面号的最高2位
    7CEB   SHL DX,02h
    7CEE   MOV AL,CH                        ;CH为最大柱面号的低8位
    7CF0   MOV AH,DH                        ;AX组成最大柱面号
    7CF2   INC AX                           ;+1成为柱面数
    7CF3   MOV [SI+08h],AX
    7CF6   XOR AX,AX
    7CF8   MOV AL,DL                        ;DL中bit2:7存放着最大扇区号
    7CFA   SHR AL,02h                       ;此时,AL中存放最大扇区号
    7CFD   MOV [SI],EAX                     ;每磁道的扇区数
    7D00   MOV EAX,[7C44]                   ;分区引导扇区的绝对扇区号
    7D04   XOR EDX,EDX                      ;EDX=0
    7D07   DIV Dword Ptr [SI]               ;绝对扇区号 / 每磁道扇区数
    7D0A   MOV [SI+0Ah],DL                  ;扇区号≡(绝对扇区号 % 每磁道扇区数)+1
    7D0D   XOR EDX,EDX                      ;EAX中为商
    7D10   DIV Dword Ptr [SI+04h]           ;(绝对扇区号 / 每磁道扇区数)/(磁头数)
    7D14   MOV [SI+0Bh],DL                  ;磁头号≡(绝对扇区号 / 每磁道扇区数)% 磁头数
    7D17   MOV [SI+0Ch],AX                  ;柱面号≡(绝对扇区号 / 每磁道扇区数)/ 磁头数
    7D1A   CMP AX,[SI+08h]                  ;分区引导扇区的柱面号是否超过最大值
    7D1D   JNL Short 7D5B                   ;>=,当前柱面号过大,显示Geom Error
    7D1F   MOV DL,[SI+0Dh]                  ;柱面号的高2位
    7D22   SHL DL,06h                       ;柱面号高2位放到bit6:7,准备与扇区号组合
    7D25   MOV CL,[SI+0Ah]                  ;CL=扇区号
    7D28   INC CL                           ;在前面放入[SI+0Ah]是没有+1,这里补上
    7D2A   OR CL,DL                         ;低6位为扇区号,高2位为柱面号的高2位
    7D2C   MOV CH,[SI+0Ch]                  ;CH=柱面号的低8位
    7D2F   POP DX                           ;DL=磁盘代码
    7D30   MOV DH,[SI+0Bh]                  ;DH=磁头号
    7D33   MOV BX,7000h
    7D36   MOV ES,BX
    7D38   XOR BX,BX                        ;放到7000:0的地方
    7D3A   MOV AX,0201h                     ;读一个扇区
    7D3D   INT 13h                          ;读扇区
    7D3F   JB Short 7D6B                    ;读扇区出错,显示:Read Error
    ;读扇区成功,使用扩展int 13h读扇区成功时转到7D43
    7D41   MOV BX,ES                        ;暂存段地址
    7D43   MOV ES,[7C48]                    ;存放分区引导程序的段地址
    7D47   PUSHA
    7D48   PUSH DS
    7D49   MOV CX,0100h                     ;搬移256个字,512字节
    7D4C   MOV DS,BX                        ;源地址为7000:0
    7D4E   XOR SI,SI                        ;SI=0
    7D50   XOR DI,DI                        ;DI=0
    7D52   CLD
    7D53   REPZ
    7D54   MOVSW                            ;搬移分区引导扇区
    7D55   POP DS
    7D56   POPA
    7D57   JMP [7C42]                       ;将控制权交给分区引导程序
    7D5B   MOV SI,7D7Fh                     ;指向字符串Geom
    7D5E   CALL 7DA1                        ;显示字符串
    7D61   JMP Short 7D71
    7D63   MOV SI,7D84h                     ;指向字符串Hard Disk
    7D66   CALL 7DA1                        ;显示字符串
    7D69   JMP Short 7D71
    7D6B   MOV SI,7D8Eh                     ;指向字符串Read
    7D6E   CALL 7DA1                        ;显示字符串
    7D71   MOV SI,7D93h                     ;指向字符串 Error
    7D74   CALL 7DA1                        ;显示字符串
    7D77   JMP Short 7D77                   ;死循环
    7D9A   MOV BX,0001h                     ;白字
    7D9D   MOV AH,0Eh                       ;显示AL中的字符
    7D9F   INT 10h                          ;显示字符
    7DA1   LOADSB
    7DA2   CMP AL,00h                       ;是否结束
    7DA4   JNZ Short 7D9A                   ;继续显示下一个字符
    7DA6   RET                              ;字符串结束,返回

-d7d79

7D79 47 52 55 42 20 00 47 65-6F 6D 00 48 61 72 64 20  GRUB .Geom.Hard 
    7D89 44 69 73 6B 00 52 65 61-64 00 20 45 72 72 6F 72  Disk.Read. Error
    7D99 00 BB 01 00 B4 0E CD 10-AC 3C 00 75 F4 C3 00 00  .;..4.m.,<.utC..
    7DA9 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 4A  ...............J
    7DB9 66 6E 9E 00 00

-d7dbe

7DBE 80 01 01 00 83 03 60 E9-20 00 00 00 E0 F4 00 00
    7DCE 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
    7DDE 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
    7DEE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    7DFE 55 AA

 

和上一篇文章一样,我们要对其中的一些地方做一些说明:

  • 关于分区信息表
    从程序中,我们看不到对分区表的使用,实际上,GRUB在生成主引导扇区的时候,已经将引导扇区的绝对扇区号放在了[7C44h]的位置,共占4个字节,所以,分区信息表就显得没有什么用处了,而且,对现代硬盘而言,用CHS的方式来表达分区位置也显得比较困难。
  • 绝对扇区号和CHS之间的关系
    之所以在分析DOS的主引导扇区时没有这个问题,而在分析GRUB的主引导扇区时却存在这个问题是因为GRUB的主引导扇区已经不再使用CHS的方式来记录分区的起始和结束位置,而是使用绝对扇区号的方式来表示一个分区的开始,这样可以表示8G以后的分区,但是在调用常规的int 13h时,却是使用CHS的方式来表示扇区位置的,所以我们需要做相应的转换。
    有关下面的转换公式的推导过程超出了本文的范围,以下仅列出公式,程序中会用到这些公式:
    扇区号≡(绝对扇区号 % 每磁道扇区数)+1
    磁头号≡(绝对扇区号 / 每磁道扇区数)% 磁头数
    柱面号≡(绝对扇区号 / 每磁道扇区数)/ 磁头数

  • 这段程序,首先要把分区引导程序读出放到7000h:0的地方,然后再将其搬移到由[7c48h]指定的段地址、偏移为0的位置,在本例中是从7000h:0处搬移到了0200h:0处,但要注意的是并不是所有的引导过程都是从7000h:0搬移到0200h:0处,其目的地址是可以变的,这个又GRUB安装主引导扇区时根据具体情况确定(grub下使用类似于setup(hd0)这样的命令来安装主引导程序。

  • 读出的分区引导扇区后,主引导扇区将控制权交给分区引导扇区时也并不是直接跳转到分区引导扇区的起始地址上,跳转地址将由[7c42h]中的内容决定,由此可见,GRUB的主引导过程比起DOS的主引导过程有着更大的灵活性。

7、结束语

看得出来,GRUB的主引导过程比起DOS的主引导过程要复杂一些,也要灵活一些,由于使用了扩展int 13h,所以其适应性更广,而DOS却只能引导8G以内的分区,DOS引导时是将自身搬移到别处,然后把分区引导扇区读到7c00h:0处,然后执行分区引导程序;GRUB引导时是将分区引导扇区读到7000h:0处再搬移到指定位置然后执行,这样看来,GRUB是无法再把分区引导扇区读到7c00h:0的(因为这个地方还放着主引导扇区的内容),那么GRUB的主引导程序是否能够引导起DOS来呢?好像有些困难,这个我们留着以后有机会讨论。

  评论这张
 
阅读(4849)| 评论(7)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018