自己写操作系统---bootsector篇 [转]

自己写操作系统---bootsector篇 

其实博主本来想在寒假自己写一个OSkernal的,高高兴兴的影印了本《一个操作系统的实现》。

然后又去图书馆借来《30天自制操作系统》和《X86/X64体系探索编程》,结果还是被自己的懒惰给打败了。。。

原本我感觉自制力还不错的,好歹春节前也看了很多东西,但是过了一个春节就懒散了。。

当然也有一部分原因是因为《30天》写的实在是太乱了。。缺少一个理论的上的指导和概括,看的云里雾里。

再就是汇编。。。博主原来只学过8086和AT&T汇编啊。。。这下又来个nasm汇编。。这学期还开了个ARM汇编。。Orz。。。

不过nasm汇编真的是很好用,它还有类似c++默认构造的宏指令,很强大啊!

当然了,如果我不是一个喜欢深究的人,也可以用《30天》提供的工具也能很快的写出来。但我毕竟还是有点追求的。。

废话了这么多,开始进入主题吧。。

首先,bootsector是个什么东西呢?其实就是个引导的作用,引导到bootloader或者是操作系统上。

注意,bootsector不是双系统的那种引导,而是在它之前的程序。

那么bootsector程序是如何发挥作用的呢?这得从计算机的开机流程讲起。

还记得学校上的操作系统教材上面说,计算机开机加电直接就去读取硬盘上的操作系统。(但其实漏掉了好些东西啊!!国产教材误人子弟啊!!!!)

其实一开机,并不是直接读硬盘,而是从主板的BIOS启动。

(BIOS不知道可以自己百度,它还把一些自带的中断加载到了内存中)

上电后,BIOS的ROM中程序通过硬件加载到内存。

根据BIOS的ROM中的程序,来检测相关硬件是否安装正确。然后才是寻找操作系统。

完整流程如下:

bios->bootsector->bootloader->kernel(后面两个以后再说)

这样就有问题了,BIOS怎么知道操作系统放在哪呢?

这需要了解通用计算机所遵循的规范了,bios只从硬盘的第一个扇区读取并加载程序。

扇区又是什么呢?这里我简单的带着你联想一下.

由于原来32位地址总线只能寻址4G的大小。那么硬盘不断发展,64位总线还没出现,但是硬盘大小超过4g。

所以多出来的部分就没有用了!但是工程师很聪明,所以就让每个地址存储的内容更多吧!(自己回顾组成原理)

所以,硬盘就出现了所谓的扇区!一般一个扇区的大小为512b。4G*512b=2t的样子。

这样来算,现在的发展已经够用了,以后换到64位系统就不用担心地址不够了。

回到正题。由于BIOS只能自动读一个扇区,512b的大小。

这么点大小肯定装不下操作系统~所以只好用bootsector来转让计算机使用的权力了。

于是我们就清楚了bootsector的作用----读入硬盘上的其他程序,并将cpu交给它。

下面是我写的bootsector。由于没有文件系统也不想用fat12,所以读取loader的位置是我自己随便定的。

如果fat12那一段不注释的话,U盘就可以被识别了,但是U盘中的内容都是乱的~~~

linux下可以用dd命令直接写到你的U盘中去。

dd if=(OBOOT)of=

(DEVICE) bs=512 count=1 conv=notrunc
OBOOT表示生成文件,直接用nasm汇编生成.bin文件即可。

DEVICE就是你U盘在linux下的路径了。

然后就可以通过U盘启动,来执行你的bootsector了~

  1. %include "boot.inc"

  2. %ifdef DEBUG

  3. org 0100h ;07c00h 0100

  4. %else

  5. org 07c00h

  6. %endif

  7. jmp short LABEL_START

  8. nop

  9. ;head of FAT12

  10. ; BS_OEMName DB 'meiboyu ' ; OEM String, 必须 8 个字节

  11. ; BPB_BytsPerSec DW 512 ; 每扇区字节数

  12. ; BPB_SecPerClus DB 1 ; 每簇多少扇区

  13. ; BPB_RsvdSecCnt DW 1 ; Boot 记录占用多少扇区

  14. ; BPB_NumFATs DB 2 ; 共有多少 FAT 表

  15. ; BPB_RootEntCnt DW 224 ; 根目录文件数最大值

  16. ; BPB_TotSec16 DW 2880 ; 逻辑扇区总数

  17. ; BPB_Media DB 0xF0 ; 媒体描述符

  18. ; BPB_FATSz16 DW 9 ; 每FAT扇区数

  19. ; BPB_SecPerTrk DW 18 ; 每磁道扇区数

  20. ; BPB_NumHeads DW 2 ; 磁头数(面数)

  21. ; BPB_HiddSec DD 0 ; 隐藏扇区数

  22. ; BPB_TotSec32 DD 0 ; wTotalSectorCount为0时这个值记录扇区数

  23. ; BS_DrvNum DB 0 ; 中断 13 的驱动器号

  24. ; BS_Reserved1 DB 0 ; 未使用

  25. ; BS_BootSig DB 29h ; 扩展引导标记 (29h)

  26. ; BS_VolID DD 0 ; 卷序列号

  27. ; BS_VolLab DB 'MOS by mby '; 卷标, 必须 11 个字节

  28. ; BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须 8个字节

  29. times 18 db 0

  30. LABEL_START:

  31. mov ax, cs

  32. mov ds, ax

  33. mov es, ax ;make all pointer point null place

  34. mov dx,0

  35. mov ax,BootMessage

  36. mov cx,BMlength

  37. mov dh,0

  38. call showStr ;show string function

  39. call Loader ;Loader getting loading

  40. jmp fin ;while(1)

  41. Loader:

  42. mov ax,4200h

  43. mov dl,0x80

  44. mov cx,0

  45. mov ds,cx

  46. mov si,DAP

  47. int 0x13

  48. jc LoaderError

  49. mov ax,0 ;clean es register

  50. mov es,ax

  51. mov dx,0

  52. mov ax,LSuccess

  53. mov cx,LSlength

  54. mov dh,1

  55. call showStr

  56. jmp BaseOffLoader:SetOffLoader ;jump to Loader !

  57. LoaderError:

  58. mov ax,0

  59. mov es,ax

  60. mov ax,LError

  61. mov cx,LElength

  62. mov dh,1

  63. call showStr

  64. fin:

  65. hlt

  66. jmp fin

  67. showStr:

  68. mov bp,ax

  69. mov ax,01301h

  70. mov bx,000Fh

  71. mov dl,0

  72. int 10h

  73. ret

  74. LSuccess: db "Loader OK!"

  75. LSlength equ $-LSuccess

  76. LError: db "Booting Loader get wrong!"

  77. LElength equ $-LError

  78. BootMessage: db "Boot Sector Start!"

  79. BMlength equ $-BootMessage

  80. DAP:

  81. db 16 ;packet size

  82. db 0 ;must 0

  83. dw 100 ;number of block need to read

  84. dw 0 ;the offset

  85. dw 8000h ;the segment address

  86. dw 1h ;start block

  87. dw 0

  88. dw 0

  89. dw 0

  90. times 510-(−

  1. $) db 0

  2. dw 0xaa55

程序短,所以懒得用宏了。。这样对于新手看着也方便。

具体汇编的内容很简单,我就不讲了,这里说一下我写这个遇到的个坑。。。

使用BIOS的int 13h+al=02h的时候,在真机上是无法加载loader的!!软盘跟U盘还是有区别的!

我看《一个操作系统 的实现》和《30天》的时候,就是这里。。他们都使用的是软盘,但是用U盘就有问题!!

于是发现要用扩展BIOS中断,详细的可以去google扩展BIOS中断。(我记得我是在wiki上看到的,但是现在找不到了)

当然看我的代码也可以~

bootsector就介绍到这里了。过几天我再来写loader的部分~

恩。。现在正在写,并且写图形化界面的时候又遇到坑了。。

PS:

装过win+linux双系统的知道,得先装windows再装linux。

我估计就是windows直接重写bootsetor,然后直接引导到他的loader了,而linux的引导程序grub会识别原来的系统

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值