打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
<<自己动手写操作系统>>学习笔记(一)
  比划着书,反汇编着NTLDR,大概写一个MBR出来了,但貌似进入了死循环???
我把编译出来的文件写入磁盘MBR中,重启,没反应,各种调试输出没错
很大可能是:MBR读取了MBR再次加载到0x7C00转移控制权?
我明明读取的是分区表的PBR呀?贴代码吧。
bios.inc
  1. include 'macro/struct.inc'  
  2. ;BIOS服务中断定义  
  3.   
  4. ;从下一设备启动  
  5. BIOS_BOOT_FROM_NEXT_DEVICE          =   0x18  
  6.   
  7. ;直接磁盘服务,功能号=AH,下面列出  
  8. BIOS_DIRECT_DISK_SERVICE                =   0x13  
  9. ;复位驱动器  
  10. BIOS_DDS_RESET_DEVICE                       =   0x00  
  11. ;读取驱动器参数  
  12. ;成功返回值:DH=磁头,DL=驱动器数,CL低6位=扇区  
  13. BIOS_DDS_READ_DEVICE_PARAMETER  =   0x08  
  14. ;读扇区  
  15. ;参数:AL=扇区数,CH=柱面,CL=扇区,DH=磁头  
  16. ;DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘  
  17. ;ES:BX=缓冲区的地址  
  18. BIOS_DDS_READ_SECTOR                        =   0x02  
  19. ;检测扩展DDS是否存在  
  20. ;参数:DL=驱动器,0x80=第一块硬盘,0x81=第二块硬盘......  
  21. BIOS_DDS_CHECK_EXTENSION                =   0x41  
  22. ;扩展直接硬盘读写数据包结构  
  23. struct STRUCT_DDS_EXTENSION_PACK  
  24.     ;大小必须=0x10  
  25.     Size                    db  ?  
  26.     ;保留  
  27.     Resvered1           db  ?  
  28.     ;数据块数量  
  29.     BlockCount      dw  ?  
  30.     ;缓冲区段偏移  
  31.     BufferOffset    dw  ?  
  32.     ;缓冲区段值  
  33.     BufferSegment   dw  ?  
  34.     ;要读的数据,扇区(低6位)和柱面(高10位)  
  35.     SC_L                    dw  ?  
  36.     SC_H                    dw  ?  
  37.     ;未知=0  
  38.     Unknown1            dd  ?  
  39. ends  
  40. BIOS_DDS_EXTENSION_READ                 =   0x42  
  41. BIOS_DDS_EXTENSION_WRITE                =   0x43  

fs.inc
  1. include 'macro/struct.inc'  
  2. ;文件系统定义  
  3.   
  4. FSID_FAT12              =   0x01  
  5. FSID_FAT16              =   0x04  
  6. FSID_FAT16_2            =   0x06  
  7. FSID_FAT16_3            =   0x0E  
  8. FSID_FAT32              =   0x0B  
  9. FSID_FAT32_2            =   0x0C  
  10. FSID_NTFS                   =   0x07  
  11. FSID_HPFS                   =   FSID_NTFS  
  12. FSID_EXTENDED           =   0x05  
  13.   
  14. FS_ACTIVE                   =   0x80  
  15.   
  16. ;分区表结构=16字节  
  17. struct STRUCT_PARTITION_TABLE  
  18.     ;分区状态,0=未激活,0x80=激活  
  19.     State                           db  ?  
  20.     ;起始磁头号  
  21.     BeginHead                   db  ?  
  22.     ;起始扇区(低6位)和柱面号(高10位)  
  23.     BeginSC                     dw  ?  
  24.     ;分区类型  
  25.     FSID                            db  ?  
  26.     ;结束磁头号  
  27.     EndHead                     db  ?  
  28.     ;结束扇区和柱面号,同BeginHead  
  29.     EndSC                           dw  ?  
  30.     ;相对扇区地址,低16+高16=32位  
  31.     InfoAreaSectors_L   dw  ?  
  32.     InfoAreaSectors_H   dw  ?  
  33.     ;总扇区数  
  34.     Sectors                     dd  ?  
  35. ends  
  36.   
  37. FLAG_BOOT_RECORD    =   0xAA55  
  38.   
  39. ;主引导记录,512字节  
  40. struct STRUCT_MASTER_BOOT_RECORD  
  41.     Codes               rb  446  
  42.     Partition1  STRUCT_PARTITION_TABLE  
  43.     Partition2  STRUCT_PARTITION_TABLE  
  44.     Partition3  STRUCT_PARTITION_TABLE  
  45.     Partition4  STRUCT_PARTITION_TABLE  
  46.     ;结束标志=0x55AA  
  47.     Flag                dw  ?  
  48. ends  
  49.   
  50. ;FAT磁盘参数表,25字节,FAT12和FAT16应该是一样的  
  51. struct STRUCT_BIOS_PARAMETER_BLOCK_FAT  
  52.     ;每扇区字节数  
  53.     BytsPerSec  dw  ?  
  54.     ;每簇扇区数  
  55.     SecPerClus  db  ?  
  56.     ;Boot记录占用多少扇区  
  57.     RsvdSecCnt  dw  ?  
  58.     ;共有多少FAT表  
  59.     NumFATs         db  ?  
  60.     ;根目录文件数最大值  
  61.     RootEntCnt  dw  ?  
  62.     ;扇区总数  
  63.     TotSec16        dw  ?  
  64.     ;介质描述符  
  65.     Media               db  ?  
  66.     ;每FAT扇区数  
  67.     FATSz16         dw  ?  
  68.     ;每磁道扇区数  
  69.     SecPerTrk       dw  ?  
  70.     ;磁头数(面数)  
  71.     NumHeads        dw  ?  
  72.     ;隐藏扇区数  
  73.     HiddSec         dd  ?  
  74.     ;如果TotSec16=0则由这个记录扇区数  
  75.     TotSec32        dd  ?  
  76. ends  
  77.   
  78. ;分区引导记录=512字节  
  79. struct STRUCT_PARTITION_BOOT_RECORD  
  80.     ;短跳转代码  
  81.     CodeJmp         rb  3  
  82.     ;厂商名(字符串)  
  83.     OEMName         rb  8  
  84.     ;BIOS_PARAMETER_BLOCK  
  85.     BPB                 STRUCT_BIOS_PARAMETER_BLOCK_FAT  
  86.     ;中断13的驱动器号  
  87.     DrvNum          db  ?  
  88.     ;磁头号(书上说这一字节是保留的)  
  89.     Head                db  ?  
  90.     ;扩展引导标记=0x29  
  91.     BootSig         db  ?  
  92.     ;卷序列号  
  93.     VolID               dd  ?  
  94.     ;卷标(字符串)  
  95.     VolLab          rb  11  
  96.     ;文件系统类型(字符串)  
  97.     FileSysType rb  8  
  98.     ;代码,数据等  
  99.     Others          rb  448  
  100.     ;标志=0x55AA  
  101.     Flag                dw  ?  
  102. ends  
  103.   
  104. ;根目录结构,32字节  
  105. struct STRUCT_ROOT_DIRECTORY_FAT  
  106.     ;文件名8字节,扩展名3字节  
  107.     Name                rb  11  
  108.     ;文件属性  
  109.     Attr                db  ?  
  110.     ;保留  
  111.     Reserved1       rb  10  
  112.     ;最后写入时间  
  113.     WrtTime         dw  ?  
  114.     ;最后写入日期  
  115.     WrtDate         dw  ?  
  116.     ;开始簇号  
  117.     FstClus         dw  ?  
  118.     ;文件大小  
  119.     FileSize        dd  ?  
  120. ends  

mbr.asm
  1. include 'bios.inc'  
  2. include 'fs.inc'  
  3. MASTER_BOOT_RECORD_BASE         =   0x7C00  
  4. MASTER_BOOT_RECORD_NEW_BASE =   0x0600  
  5.   
  6. use16  
  7. ORG MASTER_BOOT_RECORD_BASE  
  8. Main:;入口,初始化,移动代码,转移控制权  
  9.     ;初始化段寄存器  
  10.     xor  ax, ax  
  11.     mov  ss, ax  
  12.     mov  es, ax  
  13.     mov  ds, ax  
  14.     ;初始化堆栈  
  15.     mov  sp, MASTER_BOOT_RECORD_BASE  
  16.     ;移动代码,转移控制权  
  17.     mov  si, MbrEntry  
  18.     mov  di, (MASTER_BOOT_RECORD_NEW_BASE + MbrEntry - $$)  
  19.     push ax  
  20.     push di  
  21.     mov  cx, (MbrEnd - MbrEntry)  
  22.     rep  movsb  
  23.     retf;ax:di  
  24. ;Main结束  
  25.   
  26. MbrEntry:  
  27.     mov  bp, (MASTER_BOOT_RECORD_NEW_BASE + par1 - $$)  
  28.     mov  cx, 4  
  29. .Loop_FindActivePartition:  
  30.     cmp  [bp + STRUCT_PARTITION_TABLE.State], 0  
  31.     jl   .ToLoadPbr  
  32.     jne  .InvalidMbr  
  33.     add  bp, sizeof.STRUCT_PARTITION_TABLE  
  34.     loop .Loop_FindActivePartition  
  35.     ;从下一设备启动  
  36.     int  BIOS_BOOT_FROM_NEXT_DEVICE  
  37. .InvalidMbr:  
  38.     mov  bp, (MASTER_BOOT_RECORD_NEW_BASE + szMbrError - $$)  
  39.     mov  cx, 31  
  40.     call DisplayMessage  
  41.     jmp  $  
  42. .ToLoadPbr:;bp=分区表地址  
  43.     call LoadPbr  
  44.     jb  .LoadPbrFail  
  45.     cmp  word [flag], FLAG_BOOT_RECORD  
  46.     jne  .PbrError  
  47.     push ax;ax=0  
  48.     push MASTER_BOOT_RECORD_BASE  
  49.     retf;转移控制权到PBR  
  50. .LoadPbrFail:  
  51.     mov  bp, (MASTER_BOOT_RECORD_NEW_BASE + szLoadPbrFail - $$)  
  52.     mov  cx, 33  
  53.     call DisplayMessage  
  54.     jmp  $  
  55. .PbrError:  
  56.     mov  bp, (MASTER_BOOT_RECORD_NEW_BASE + szPbrError - $$)  
  57.     mov  cx, 30  
  58.     call DisplayMessage  
  59.     jmp  $  
  60. ;MbrEntry结束  
  61.   
  62. LoadPbr:;bp=分区表地址  
  63.     mov  di, 5;尝试5次ReadPBR  
  64.     mov  dl, [bp + STRUCT_PARTITION_TABLE.State]  
  65.     mov  ah, BIOS_DDS_READ_DEVICE_PARAMETER  
  66.     int  BIOS_DIRECT_DISK_SERVICE  
  67.     jb   .ReadPBR;失败,尝试直接读取PBR  
  68.     mov  al, cl;AX=0  
  69.     and  al, 00111111B;取低6位  
  70.     cbw;把AL的符号扩展到AH  
  71.     mov  bl, dh;磁头数  
  72.     mov  bh, ah;AH=0  
  73.     inc  bx;得出总磁头数  
  74.     mul  bx;扇区*磁头=ax*bx,结果=dx:ax  
  75.     mov  dx, cx  
  76.     xchg dh, dl  
  77.     shr  dh, 6;取高2位  
  78.     inc  dx  
  79.     ;总的扇区数*总的磁头数*总的柱面数=磁盘容量  
  80.     mul  dx  
  81.     cmp  [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_H], dx  
  82.     ja   .ReadPBREx;无符号比较,大于则跳  
  83.     jb   .ReadPBR;无符号比较,小于则跳  
  84.     cmp  [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_L], ax  
  85.     jnb  .ReadPBREx;无符号比较,大于等于则跳  
  86. .ReadPBR:  
  87.     mov  ah, BIOS_DDS_READ_SECTOR  
  88.     mov  al, 1  
  89.     mov  bx, MASTER_BOOT_RECORD_BASE  
  90.     mov  cx, [bp + STRUCT_PARTITION_TABLE.BeginSC]  
  91.     xor  dx, dx  
  92.     mov  dl, [bp + STRUCT_PARTITION_TABLE.State];dx=FS_ACTIVE=0x80=代表硬盘  
  93.     int  BIOS_DIRECT_DISK_SERVICE  
  94.     jnb  .Ret;成功  
  95.     dec  di  
  96.     je   .Ret;尝试了5次,直接返回  
  97.     ;复位驱动器,继续尝试  
  98.     xor  ah, ah  
  99.     mov  dl, [bp + STRUCT_PARTITION_TABLE.State]  
  100.     int  BIOS_DIRECT_DISK_SERVICE  
  101.     jmp  .ReadPBR  
  102. .ReadPBREx:  
  103.     mov  dl, [bp + STRUCT_PARTITION_TABLE.State]  
  104.     pusha  
  105.     mov  bx, 0x55AA;为什么倒过来了?  
  106.     mov  ah, BIOS_DDS_CHECK_EXTENSION  
  107.     int  BIOS_DIRECT_DISK_SERVICE  
  108.     jb   .Failure;不支持  
  109.     ;继续检查  
  110.     cmp  bx, FLAG_BOOT_RECORD  
  111.     jne  .Failure  
  112.     test cl, 1;其他资料没有这个,什么意思?  
  113.     je   .Failure  
  114.     popa  
  115. .Loop_ReadPBREx:  
  116.     pusha  
  117.     ;使用扩展直接磁盘服务读取  
  118.     ;填充数据包.由于转移了代码,所以要修正数据包地址  
  119.     mov  si, MASTER_BOOT_RECORD_NEW_BASE + Pack_Extend - MASTER_BOOT_RECORD_BASE  
  120.     mov  [si + STRUCT_DDS_EXTENSION_PACK.BufferOffset], MASTER_BOOT_RECORD_BASE  
  121.     mov  [si + STRUCT_DDS_EXTENSION_PACK.BufferSegment], 0  
  122.     push ax  
  123.     mov  ax, [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_L]  
  124.     mov  [si + STRUCT_DDS_EXTENSION_PACK.SC_L], ax  
  125.     mov  ax, [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_H]  
  126.     mov  [si + STRUCT_DDS_EXTENSION_PACK.SC_H], ax  
  127.     pop  ax  
  128.     mov  ah, BIOS_DDS_EXTENSION_READ  
  129.     int  BIOS_DIRECT_DISK_SERVICE  
  130.     popa  
  131.     dec  di  
  132.     je   .Ret;尝试了5次,直接返回  
  133.     ;复位,继续尝试  
  134.     xor  ah, ah  
  135.     mov  dl, [bp + STRUCT_PARTITION_TABLE.State]  
  136.     int  BIOS_DIRECT_DISK_SERVICE  
  137.     jmp  .Loop_ReadPBREx  
  138. .Failure:  
  139.     popa  
  140.     stc;设置CF=1  
  141. .Ret:  
  142.     retn  
  143. ;LoadPBR结束  
  144.   
  145. DisplayMessage:  
  146.     mov  ax, 0x1301  
  147.     mov  bx, 0xC  
  148.     xor  dl, dl  
  149.     int  0x10  
  150.     ret  
  151. ;DisplayMessage结束  
  152.   
  153. szMbrError      db  "Invalid Master Partition Table."  
  154. szLoadPbrFail   db  "Can't Load Partition Boot Record."  
  155. szPbrError      db  "Invalid Partition Boot Record."  
  156.   
  157. Pack_Extend             STRUCT_DDS_EXTENSION_PACK 0x10, 0, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0  
  158. CodeEnd:;代码结束,四个分区表结构+结束标志  
  159. times   sizeof.STRUCT_MASTER_BOOT_RECORD.Codes - ($-$$) db  0  
  160. par1 STRUCT_PARTITION_TABLE 0x80, 0x01, 0x0001, 0x07, 0xFE, 0xBFBF, 0x003F, 0, 0x00AC9281  
  161. par2 STRUCT_PARTITION_TABLE  
  162. par3 STRUCT_PARTITION_TABLE  
  163. par4 STRUCT_PARTITION_TABLE  
  164. flag                            dw  FLAG_BOOT_RECORD  
  165. MbrEnd:  

希望有人能帮我解决一下,谢谢。  
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
硬盘结构,主引导记录MBR,硬盘分区表DPT,主分区、扩展分区和逻辑分区,电脑启动过程
盘主引导扇区、分区表和分区引导扇区(MBR、DPT、DBR、BPB)详解
硬盘分区表知识——详解硬盘MBR
系统安装教程之硬盘分区格式化(MBR或GPT)
电脑故障维修判断大全
用U盘装完系统后,要是拔掉U盘无法启动系统,插入U盘才能进入系统,怎么解决啊
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服