MBR初认识

打印 上一主题 下一主题

主题 664|帖子 664|积分 1992

1.什么是MBR
  说实话,我一直都不喜欢在一大堆内容一开始就抛出一长条概念,这很劝退,但现在记录一下是很有必要的,否则后续忘记就难理解了。
  简单来讲,MBR记录着硬盘各个分区的大小和位置信息,就像人口普查一样,对整个硬盘的分布了熟于心。它是开机后访问硬盘时要读取的第一个扇区,不难理解,毕竟要知道自己去哪得先看地图。噢,对了,它的全称是主引导记录(master boot record),由于os需要一步步进行权限的完善,有程序进行接力和指引是必须的事情。
2. 0x7c00?why?
  好吧,这个问题我也一直都很好奇,在进行6.s081实验时,取断点并跳转总是从0x7c00开始,搜了很多操作系统有关的文章都没有给我一个满意的答案,现在算是知道了:
  早期的CPU要求物理地址 0x0~0x3FF 存放中断向量表(我还不知道这是什么意思),所以只能找其他地方放MBR了,在那时DOS(古老的系统)要求最小内存是32KB,但是MBR自然不可能覆盖在前面或中间(不然其他功能去哪开始加载,无序会导致混乱和时间变长),所以它必须预留空间,所以就得在32KB的末尾。
  写程序的大家都知道,程序必须要用到栈,MBR虽说是汇编语言但也是一段程序,它在内存里由于要给栈分配空间实际上总空间要大于512字节,最大估计也就1KB了(毕竟功能就那点),所以选32KB中最后1KB最合适,而那个地方就是0x7c00。
3.启动MBR的坎坷风雪路
  首先是简单的MBR代码:
  1. 1 ;主引导程序
  2. 2 ;---------------------
  3. 3
  4. 4 SECTION MBR vstart=0x7c00 ;程序开始的地址
  5. 5     mov ax, cs            ;使用cs初始化其他的寄存器
  6. 6     mov ds, ax            ;因为是通过jmp 0:0x7c00到的MBR开始地址
  7. 7     mov es, ax            ;所以此时的cs为0,也就是用0初始化其他寄存器
  8. 8     mov ss, ax            ;此类的寄存器不同通过立即数赋值,采用ax中转
  9. 9     mov fs, ax
  10. 10     mov sp, 0x7c00  ;初始化栈指针
  11. 11
  12. 12 ;清屏利用0x10中断的0x6号功能
  13. 13 ;------------------------
  14. 14     mov ax, 0x600
  15. 15     mov bx, 0x700
  16. 16     mov cx, 0
  17. 17     mov dx, 0x184f
  18. 18
  19. 19     int 0x10
  20. 20     ;获取光标位置
  21. 21 ;---------------------
  22. 22     mov ah, 3   ; 3号子功能获取光标位置
  23. 23     mov bh, 1   ; bh寄存器存储带获取光标位置的页号,从0开始,此处填1可以看成将光标移动到最开始
  24. 24     int 0x10
  25. 25
  26. 26 ;打印字符串
  27. 27 ;------------------
  28. 28     mov ax, message
  29. 29     mov bp, ax
  30. 30
  31. 31     mov cx, 6    ;字符串长度,不包括'\0'
  32. 32     mov ax, 0x1301
  33. 33     mov bx, 0x2
  34. 34
  35. 35     int 0x10
  36. 36
  37. 37     jmp $
  38. 38
  39. 39     message db "My MBR"
  40. 40     times 510-($-$$) db 0
  41. 41     db 0x55, 0xaa
复制代码
 注释都说的很清楚,显示器相关就不提了,主要写写第24行0x10中断和37、40、41行。
0x10中断在这里负责有关打印的例程。调用方法是将功能号送入ah寄存器,其他参数按照中断要求放在适当寄存器,然后执行int 0x10,具体了解在这贴个链接:(3条消息) BIOS INT 10中断功能详解_bios显示模式 int10_rhxznp的博客-CSDN博客
37行是一个死循环,$是本行指令的地址,jmp是近跳转,那么jmp $就是跳到自己的地址再执行自己,再跳到自己的地址再跳转,这样是为了让程序悬停在此处,等待下一步。
40行的$$是本section的起始地址,和上面$区别还是很大的,section起始地址和行起始地址并不是一个东西。$-$$是本行到本section的偏移量,MBR的最后两个字节必须是固定的内容,也就是BIOS认为可执行的程序MBR啦!如果不是,OK,BIOS不认识,无法启动。
那么一串times 和 - 号、db是什么意思?因为要预留出0x55,0xaa,所以得要计算填满扇区用的字节数,MBR共有512字节,那么510个字节就得填充,但是扇区里还有其他东西加载,所以用510-($-$$)得到剩余量,然后用0填充,这样预留的两字节就能确保了。
也就是说,到这里程序加载的顺序是BIOS -> 跳转0x7c00 -> 跳转0x55,0xaa.
接下来是最艰难的启动之路!
  利用dd和nasm分别写入和编译MBR,这个没问题,注意路径就行,主要是启动bochs时,错误主要有三个(反反复复!):

  • 这个每次启动都会弹出,真的很鸡肋!通过查阅发现img.lock删除后重启就行,还是不行命令加个sudo也可以。
  • sector size of 0 is in error. 措施:中文意思是扇区大小0出错,我怀疑是我硬盘没有建立,或者建立了系统没反应,所以重新又建立了一次,解决了问题。
  • NO bootable device. 措施:一开始我很困惑,明明我dd也nasm了怎么不认呢?原来是第二个错误的连锁反应,建立硬盘后再dd nasm一次就能识别MBR了。
  虽说就三个错误,折腾了我大半天时间,一些文章也没有我的错误,反反复复重启删除,最后终于出现在bochs的图让我成就感满满,附个胜利图:

呃,别问我为什么和上面的程序显示不一样,为了解释重点的MBR结构,我搜索了这个比较简单的程序,但图中的这个是《操作系统真象还原》里的完整代码运行出的结果,所以不一样。
  OK!总算是写完初认识啦!我只是个小菜鸡,一些认识肯定是浅显或有些不准确的,后面会随着OS的完善逐步深入,感谢浏览!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表