赞
踩
我们使用软盘来启动操作系统时,系统首先就是从软盘的第一个扇区中开始读取数据,也就是第0面,0磁道的第0个扇区,软盘的每个扇区为512个字节的大小,如果最后两个字节为0xaa55(当BIOS看到这两个字节时,就认为是引导扇区的结束标志),则代表该两个字节前的机器指令都是启动扇区的指令,以0x00开头一直到0xaa55这512个字节的扇区就称之为启动扇区。
代码(程序名称为boot.S)以及注释如下:
- .code16
- .text
- mov %cs,%ax
- mov %ax,%ds
- mov %ax,%es #将寄存器ds和es同时指向与cs相同的段,使得后续在进行数据操作时能定位到正确的位置
- call DispStr #调用DispStr函数
- jmp . #进入死循环
- DispStr:
- mov $BootMessage,%ax
- mov %ax,%bp
- mov $16,%cx
- mov $0x1301,%ax
- mov $0x00c,%bx
- mov $0,%dl
- int $0x10
- ret
- BootMessage:.ascii "Hello, OS world!"
- .org 510
- .word 0xaa55
DispStr函数的注释如下:
- DispStr:
- mov $BootMessage,%ax #将字符串变量“BootMessage”的首地址传给寄存器ax
- mov %ax,%bp #使用寄存器ES:BP保存字符串的地址
- mov $16,%cx #保存字符串的长度
- mov $0x1301,%ax #寄存器ax高位为 0x13h,低位为0x01h
- mov $0x00c,%bx #设置页号为0(高位0X0h),字符串颜色为红色高亮(低位0x0ch)
- mov $0,%dl
- int $0x10 #10h号中断
- ret
剩下的代码注释如下:
- BootMessage:.ascii "Hello, OS world!" #字符串函数
- .org 510 #用0x00填满剩下的字节,一直到第510个字节
- .word 0xaa55 #剩下的两个字节填0xaa55
要想将一个程序编译成可执行文件,我们需要经过类似中间代码生成、连接等步骤(可以参考之前写过的一篇文章:【c语言】从高级语言到可以执行的EXE程序的编译过程),所以,在编译之前,我们还需要编写一个连接脚本(名称为solrex_X86.ld),代码如下:
- SECTIONS
- {
- . = 0x7c00;
- .text :
- {
- _ftext = .;
- } = 0
- }
当BIOS发现了引导分区(以0xaa55结尾的前512个字节的扇区)之后,就会把这512个字节的内容转载到内存的0000:7c00处(可以参考之前写过的一篇文章:【操作系统】操作系统的启动都干了些什么),然后跳转到0000:7c00处将控制权彻底交给这段引导代码中,所以该连接脚本的功能就是在进行连接时,将程序入口设置到内存0000:7c00的位置,而如果我们希望将代码放置到其他地址空间时,就可以直接修改连接脚本的地址即可。
下一步我们编写Makefile脚本,用于将高级语言(.S)编译成中间文件(.o),再将连接脚本(.ld)和中间文件(.o)连接编译成可执行文件(.elf),最后将可执行文件写入到软盘镜像中(.img),代码如下:
- CC=gcc
- LD=ld
- LDFILE=solrex_X86.ld #连接脚本
- OBJCOPY=objcopy
-
- all: boot.img
-
- boot.o: boot.S #生成中间文件
- $(CC) -c boot.S
-
- boot.elf: boot.o #连接脚本+中间文件=可执行文件
- $(LD) boot.o -o boot.elf -e c -T$(LDFILE)
-
- boot.bin: boot.elf #移除可执行文件中没有用到的块
- @$(OBJCOPY) -R .pdr -R .comment -R.note -S -O binary boot.elf boot.bin
-
- boot.img: boot.bin #生成软盘镜像
- @dd if=boot.bin of=boot.img bs=512 count=1
- @dd if=/dev/zero of=boot.img skip=1 seek=1 bs=512 count=2879
-
- clean:
- @rm -rf boot.o boot.elf boot.bin boot.img
使用指令:
make
进行编译,输出如下:
最后即生成一个软盘镜像(boot.img)和一些中间文件:
我们在虚拟机上新建一个虚拟电脑,然后按照推荐一直点下一步:
创建完成后,我们选择虚拟电脑的“设置”项,添加一个虚拟软盘:
点击”添加虚拟软驱“,然后点击”注册“,将你先前编译的boot.img进行注册操作:
注册完成后选择对应的软盘镜像,即可保存退出:
为了让系统优先导入我们的软盘镜像,我们可以将控制器:IDE整个删除,使得我们的镜像处于最高优先级:
最后我们直接点击“启动”,即可看见先前编写的字符串黑底红字!!
恭喜!你已经踏入了编写操作系统的第一步!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。