第一个bootloader,当然就是显示hello world。把它写成软盘镜像,然后用虚拟机vmware启动,当然用真机器也是可以的。
bootloader被BIOS加载到内存物理地址0x7c00处执行,代码为16位实模式。以下是AT&T汇编代码:
.code16 #按16位编译
.text
.global _start
_start:
movw $0x07c0,%ax #段地址0x7c0,offset从0开始
movw %ax,%es #后面要用
movw %ax,%sp #设堆栈,因为int中断要用
showmsg:
movb $0x3,%ah
movb $0,%bh
int $0x10 #BIOS调用,得到光标位置 (当然也可以直接在0行0列处写)
movw $0x1301,%ax
movw $0x0007,%bx
movw $msglen,%cx #es:cx 字符串位置segment:offset
movw $mymsg,%bp
int $0x10 #BIOS调用,显示字符串
movw $0xfff,%ax #延时程序
movw $0xffff,%cx
myloop:
loop myloop #loop=自动减cx至0
subw $1,%ax
cmp $0,%ax
jne myloop
jmp showmsg #循环显示
#没有用.data段,可能是为了节省空间,不使内存分配中断
mymsg: .string "Hello world,I'm wushigang/r/n/b"
msglen =.-mymsg #取mymsg长度
.org 510 #一个扇区512字节,最后两字节0xAA55代表活动分区
bootflag: .word 0xaa55
#.org 1474560 #若加上这个编译出来就是1.44M
编译采用Linux的as boot.S -o boot.o,链接ld boot.o -o boot -Ttext 0 --oformat binary -s
-Ttext 0表示代码段放在0位置,-s却掉符号,--oformat binary表示链接成平面二进制(???)
完成,查看文件boot只有512字节,对应一个扇区。把它写到软盘第一扇区或者把它做为软盘镜像载入vmware,启动就会不断的显示Hello world了。
BIOS参考:http://www.ctyme.com/intr/int.htm,中文http://hi.baidu.com/s1p2/blog/item/ade7c4fdb7ad8441d6887dbf.html
写完了编译出来,可万一运行不正常怎么办,得调试。可bootloader怎么调试,用bochs就行了。
bochs是个只有几M大的x86虚拟机,跟vmware一样,就是速度比较慢,可它能调试。下载安装吧,开源软件。
把上面结果boot当软件镜象装入bochs,调试启动,bochs可以设置在哪在地址断点,run然后就跟gdb一样一条条走,走几步看reg值。就不多介绍了。
我就是这样才把上面那个bootloader搞完成的。