ReactOS 系统中DOSMBR

前端之家收集整理的这篇文章主要介绍了ReactOS 系统中DOSMBR前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

  1. .code16
  2. real_start:
  3. cli
  4. cld
  5. xor ax,ax
  6. mov ss,ax
  7. mov ds,ax
  8. mov bp,HEX(7c00)
  9. lea sp,[bp-32]
  10. sti
  11. mov ax,HEX(1FE0)
  12. mov es,ax
  13. mov si,bp
  14. mov di,bp
  15. mov cx,256
  16. rep movsw
首先将整个数据从1FE0:7C00处给复制到0:7C00处;然后对复制过去的数据进行验证。
  1. ljmp16 HEX(1FE0),cont
  2. cont:
  3. mov ds,ax
  4. xor ax,ax
  5. mov es,ax
  6. lea di,[bp + HEX(1be)] // start of partition table
  7. test_next_for_active:
  8. test byte ptr ds:[di],HEX(80)
  9. jne active_partition_found
  10. add di,16 // next table
  11. cmp di,HEX(07c00) + HEX(1fe) // scanned beyond end of table ??
  12. jb test_next_for_active
首先,跳转的时候会将CS给设置为1FE0。然后设置其他的段寄存器,注意上面的DS没有设置成1FE0,所以是复制到0:7C00,然后找到活动的主目录。
  1. call print
  2. .asciz "no active partition found"
  3.  
  4. WAIT_FOR_REBOOT:
  5. jmp WAIT_FOR_REBOOT
  6. trouble_reading_drive:
  7. call print
  8. .asciz "read error while reading drive"
  9. jmp WAIT_FOR_REBOOT
  10.  
  11. invalid_partition_code:
  12. call print
  13. .asciz "partition signature != 55AA"
  14.  
  15. jmp WAIT_FOR_REBOOT
  16.  
  17. active_partition_found:
  18. call read_boot_sector
  19.    jc trouble_reading_drive 
  20.  
  21. 如果没有找到却推出循环,那么就要打印出“no activate partition found"字符串,下面先看看这个打印函数,这个函数的实现很有趣,很类似于C语言的函数调用

  22. print_1char:
  23.     xor bx,bx                   // video page 0
  24.     mov ah,HEX(0E)              // else print it
  25.     int HEX(10)                  // via TTY mode
  26. print:
  27.     pop si                       // this is the first character
  28. print1:
  29.     lodsb                        // get token
  30.     push si                      // stack up potential return address
  31.     cmp al,0                    // end of string?
  32.     jne print_1char              // until done
  33.     ret                          // and jump to it
  34. 首先,执行的第一条语句是pop si,然后由将si当中的额字符经过lodsb指令传递给al,这里由于si指向整个字符串,这些字符串由伪指令.asciz放入到堆栈当中,同时这里也是需要执行的下一条指令,所以需要压栈,以便于后面的ret执行。如果需要打印消息了,就死循环等待用户按下开机重启键。而如果找到相应的活动分区,就执行读MBR操作。
  35.  
  36. read_boot_sector:
  37.     mov bx,HEX(55aa)
  38.     mov ah,HEX(41)
  39.     int HEX(13)//利用系统中断对参数进行再一次验证,如果置进位并且BX不等于AA55,则表明返回错误
  40.     jc  StandardBios    //  
  41.     cmp bx,HEX(0aa55)  //    
  42.     jne StandardBios
  43.     test cl,1         //如果CX的最低位为1,表明使用包结构访问数据,否则返回错误
  44.     jz StandardBios
  45.     jmp short LBABios
  46. _bios_LBA_address_packet:
  47.     .byte 16
  48.     .byte 0
  49.     .byte 4         // read four sectors - why not
  50.     .byte 0
  51.     .word HEX(7c00) // fixed boot address for DOS sector
  52.     .word HEX(0000)
  53. _bios_LBA_low:
  54.     .word 0
  55. _bios_LBA_high:
  56.     .word 0
  57.     .word 0,0
  58. LBABios:
  59. 	mov ax,[di + 8]
  60. 	mov word ptr ds:[_bios_LBA_low],ax
  61. 	mov ax,[di + 8 + 2]
  62. 	mov word ptr ds:[_bios_LBA_high],ax
  63.        mov ax,HEX(4200)    //  regs.a.x = LBA_READ;
  64.        mov si,offset _bios_LBA_address_packet // regs.si = FP_OFF(&dap);
  65.        int HEX(13)
  66.        ret
  67.  
  68. INT13 AH=42用于读取磁盘的数据,调用的时候需要传入三个参数,AH=42表明调用函数的序号,DL表示磁盘驱动的序号,在这里整个DL一直没有改变,所以是在读取硬盘分区表的时候就存在的,DS:SI在上面的函数当中进行设置.首先通过两条mov指令设置_bios_LBA_high和_bios_LBA_low,然后在后面将_bios_LBA_address_packet 的偏移放到SI当中。其中整个SI所指向的地址的数据要求如下:

  69.  
  70.  
  71. 00h

  72. 1 byte

  73. 整个数据区域的大小,为16

  74. 01h

  75. 1 byte

  76. 未用,必须为0

  77. 02h..03h

  78. 2 bytes

  79. 需要读取多少个扇区,这里是4

  80. 04h..07h

  81. 4 bytes

  82. 整个扇区将被读入内存的偏移地址

  83. 08h..0Fh

  84. 8 bytes

  85. 从哪里开始读,这八个字节由上面的mov指令实现

  86. 硬盘分区表的结构

  87.  
  88. 字节偏移

  89. 字段名及说明

  90. 00

  91. 活动分区标志,只能是00H和80H。80H为活动,00H为非活动。

  92. 01 - 03

  93. 开始柱面(Starting Cylinder)、开始磁头(Starting Head)、开始扇区(Starting Sector)

  94. 04

  95. 分区的类型

  96. 05 - 07

  97. 结束柱面(Ending Cylinder)、结束磁头(Ending Head)、结束扇区(Ending Sector

  98. 08 – 0B

  99. 相对扇区数(Relative Sectors)从磁盘的开始到该分区开始的偏移量,可以看成是分区在硬盘中的起始地址。

  100. 0C – 0F

  101. 总扇区数(Total Sectors)为该分区的扇区总数。通过4个字节可以表示2^32个扇区。

  102. 通过上面两个表可以很容易那两句mov指令了,之所以需要两句mov,是因为现在系统还在16位模式下面。读取到完整的数据到内存当中之后,下面就验证一下,然后跳转到内存地址开始执行。上面的LBABios最后的ret返回语句将直接返回到call read_boot_sector后面。而进位标志则由LBABios中的int 13设置或者清空。如果设置了进位标志表明读取出错,反之读取正确。
    cmp word ptr es:[HEX(7c00)+HEX(1fe)],HEX(0aa55)
  103.     jne invalid_partition_code
  104.     ljmp16 0,HEX(7c00)            
  105. 在进行简单地比较之后,就直接跳转到7C00位置开始执行。

  106.  

猜你在找的React相关文章