system部分就是将来我们的内核部分,现在只有一个简单的head.S,而且就是打印一个字符‘S’,代码如下:
SETUPLEN = 4 BOOTSEG = 0x7c0 INITSEG = 0x9000 SETUPSEG = 0x9020 SYSSEG = 0x1000 ENDSEG = SYSSEG + SYSSIZE .text .globl start/*程序从start处开始运行*/ .code16 start: LABEL_SEG_CODE32: .align 32 .code32 movw $0x10,%ax movw %ax,%gs movl $((80*12+79)*2),%edi/*第12行,79列*/ movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/ movb $'S',%al/*显示的字符*/ movw %ax,%gs:(%edi) loop1:/*无限循环*/ jmp loop1
我们将system部分放到setup后面,也就是第六个及以后的扇区。
Makefile如下:
AS =as LD =ld LDFLAGS = --oformat binary -N -e start -Ttext 0x0 Image:bootsect setup head cat bootsect setup head >Image bootsect:bootsect.s $(AS) -o bootsect.o -a bootsect.s $(LD) $(LDFLAGS) -o bootsect bootsect.o setup:setup.s $(AS) -o setup.o -a setup.s $(LD) $(LDFLAGS) -o setup setup.o head:head.s $(AS) -o head.o -a head.s $(LD) $(LDFLAGS) -o head head.o clean: rm -f Image setup bootsect *.o
load_system代码将system读出放到内存0x10000处
启动扇区代码修改如下:
SETUPLEN = 4 BOOTSEG = 0x7c0 INITSEG = 0x9000 SETUPSEG = 0x9020 SYSSEG = 0x1000 ENDSEG = SYSSEG + SYSSIZE .text .globl start/*程序从start处开始运行*/ .code16 start: mov $BOOTSEG,%ax //将ds段寄存器设置为0x07c0 mov %ax,%ds mov $INITSEG,%ax //将es段寄存器设置为0x9000 mov %ax,%es mov $256,%cx sub %si,%si sub %di,%di rep movsw jmpl $INITSEG,$code msg: .string "Hello world!" code: mov %cs,%ax mov %ax,%ds mov %ax,%es mov %ax,%ss mov $0xff00,%sp call DispStr/*调用显示字符串函数*/ load_setup: movb $0x00,%dh//磁头号0 movb $0x00,%dl//驱动器号0 mov $0x0002,%cx mov $0x0200,%bx//es:bx指向缓冲区 movb $0x02,%ah//0x02,读磁盘扇区到内存 movb $SETUPLEN,%al//需要读出的扇区数量 int $0x13 jnc ok_load_setup//进位标志CF为0时就跳转 mov $0x0000,%dx mov $0x0000,%ax int $0x13 jmp load_setup ok_load_setup: load_system: mov $0x1000,%ax //将es段寄存器设置为0x1000 mov %ax,%es movb $0x00,%dh//磁头号0 movb $0x00,%dl//驱动器号0 mov $0x0006,%cx//开始扇区 mov $0x0000,%bx//es:bx指向缓冲区 movb $0x02,%ah//0x02,读磁盘扇区到内存 movb $0x10,%al//需要读出的扇区数量 int $0x13 jnc ok_load_system//进位标志CF为0时就跳转 mov $0x0000,%dx mov $0x0000,%ax int $0x13 jmp load_system ok_load_system: jmpl $SETUPSEG,$0 loop0:/*无限循环*/ jmp loop0 DispStr: mov $msg ,%ax mov %ax ,%bp/*es:bp = 串地址*/ mov $12 ,%cx/*cs = 串长度*/ mov $0x1301,%ax/*ah=13是功能号表示显示字符串 ,al=01是显示输出方式*/ mov $0x000c,%bx/*bh=0是0页,bl=0ch高亮 黑底红字*/ mov $0 ,%dl/*0行0列*/ int $0x10 ret .org 0x1fe, 0x90 .word 0xaa55