当前位置:   article > 正文

【操作系统】半小时写一个微型操作系统-写一个启动扇区并且导入到软盘镜像中_写入软盘映像

写入软盘映像

一.什么是启动扇区

        我们使用软盘来启动操作系统时,系统首先就是从软盘的第一个扇区中开始读取数据,也就是第0面,0磁道的第0个扇区,软盘的每个扇区为512个字节的大小,如果最后两个字节为0xaa55(当BIOS看到这两个字节时,就认为是引导扇区的结束标志),则代表该两个字节前的机器指令都是启动扇区的指令,以0x00开头一直到0xaa55这512个字节的扇区就称之为启动扇区

二.引导扇区的程序编写

        代码(程序名称为boot.S)以及注释如下:

  1. .code16
  2. .text
  3. mov %cs,%ax
  4. mov %ax,%ds
  5. mov %ax,%es #将寄存器ds和es同时指向与cs相同的段,使得后续在进行数据操作时能定位到正确的位置
  6. call DispStr #调用DispStr函数
  7. jmp . #进入死循环
  8. DispStr:
  9. mov $BootMessage,%ax
  10. mov %ax,%bp
  11. mov $16,%cx
  12. mov $0x1301,%ax
  13. mov $0x00c,%bx
  14. mov $0,%dl
  15. int $0x10
  16. ret
  17. BootMessage:.ascii "Hello, OS world!"
  18. .org 510
  19. .word 0xaa55

        DispStr函数的注释如下:

  1. DispStr:
  2. mov $BootMessage,%ax #将字符串变量“BootMessage”的首地址传给寄存器ax
  3. mov %ax,%bp #使用寄存器ES:BP保存字符串的地址
  4. mov $16,%cx #保存字符串的长度
  5. mov $0x1301,%ax #寄存器ax高位为 0x13h,低位为0x01h
  6. mov $0x00c,%bx #设置页号为0(高位0X0h),字符串颜色为红色高亮(低位0x0ch)
  7. mov $0,%dl
  8. int $0x10 #10h号中断
  9. ret

         剩下的代码注释如下:

  1. BootMessage:.ascii "Hello, OS world!" #字符串函数
  2. .org 510 #用0x00填满剩下的字节,一直到第510个字节
  3. .word 0xaa55 #剩下的两个字节填0xaa55

三.连接脚本的编写

        要想将一个程序编译成可执行文件,我们需要经过类似中间代码生成、连接等步骤(可以参考之前写过的一篇文章:【c语言】从高级语言到可以执行的EXE程序的编译过程),所以,在编译之前,我们还需要编写一个连接脚本(名称为solrex_X86.ld),代码如下:

  1. SECTIONS
  2. {
  3. . = 0x7c00;
  4. .text :
  5. {
  6. _ftext = .;
  7. } = 0
  8. }

        当BIOS发现了引导分区(以0xaa55结尾的前512个字节的扇区)之后,就会把这512个字节的内容转载到内存的0000:7c00处(可以参考之前写过的一篇文章:【操作系统】操作系统的启动都干了些什么),然后跳转到0000:7c00处将控制权彻底交给这段引导代码中,所以该连接脚本的功能就是在进行连接时,将程序入口设置到内存0000:7c00的位置,而如果我们希望将代码放置到其他地址空间时,就可以直接修改连接脚本的地址即可。

四.Makefile脚本编写

        下一步我们编写Makefile脚本,用于将高级语言(.S)编译成中间文件(.o),再将连接脚本(.ld)和中间文件(.o)连接编译成可执行文件(.elf),最后将可执行文件写入到软盘镜像中(.img),代码如下:

  1. CC=gcc
  2. LD=ld
  3. LDFILE=solrex_X86.ld #连接脚本
  4. OBJCOPY=objcopy
  5. all: boot.img
  6. boot.o: boot.S #生成中间文件
  7. $(CC) -c boot.S
  8. boot.elf: boot.o #连接脚本+中间文件=可执行文件
  9. $(LD) boot.o -o boot.elf -e c -T$(LDFILE)
  10. boot.bin: boot.elf #移除可执行文件中没有用到的块
  11. @$(OBJCOPY) -R .pdr -R .comment -R.note -S -O binary boot.elf boot.bin
  12. boot.img: boot.bin #生成软盘镜像
  13. @dd if=boot.bin of=boot.img bs=512 count=1
  14. @dd if=/dev/zero of=boot.img skip=1 seek=1 bs=512 count=2879
  15. clean:
  16. @rm -rf boot.o boot.elf boot.bin boot.img

        使用指令:

make

        进行编译,输出如下:

         最后即生成一个软盘镜像(boot.img)和一些中间文件:

 五.虚拟机VXBox开启镜像

        我们在虚拟机上新建一个虚拟电脑,然后按照推荐一直点下一步:

       创建完成后,我们选择虚拟电脑的“设置”项,添加一个虚拟软盘:

         点击”添加虚拟软驱“,然后点击”注册“,将你先前编译的boot.img进行注册操作:

         注册完成后选择对应的软盘镜像,即可保存退出:

        为了让系统优先导入我们的软盘镜像,我们可以将控制器:IDE整个删除,使得我们的镜像处于最高优先级:

        最后我们直接点击“启动”,即可看见先前编写的字符串黑底红字!!

        恭喜!你已经踏入了编写操作系统的第一步!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/346640
推荐阅读
  

闽ICP备14008679号