jmp start
start:
cli
mov al,1
mov ah,2
mov bx,0x1000
mov es,bx
mov bx,0
mov cx,0x0002
mov dx,0x0
int 0x13
jnc ok_load
die:
jmp die
ok_load:
mov ax,0x1000
mov ds,ax
mov si,0
mov di,0
mov es,di
mov cx,512
cpy:
movsb
dec cx
jcxz cpy_done
jmp cpy
cpy_done:
mov dx,0
mov ds,dx
lgdt [0x7c00+gdt_48]
mov edx,cr0
or edx,1
mov cr0,edx
mov ax,0x0010
mov ds,ax
jmp dword 0x0008:0
gdt_48:
DW 24
DW gdt+0x7c00,0
gdt:
DW 0,0,0,0
DW 0Xffff
DW 0X0000
DW 0X9e00
DW 0X0000
DW 0Xffff
DW 0X0000
DW 0X9200
DW 0X0000
TIMES 510-($-$$) DB 0
DW 0XAA55
;kernel.s
[BITS 32]
ORG 0
lgdt [GDT]
start:
mov ax,0x10
mov gs,ax
mov bl,'s'
mov [gs:((80*0+0)*2)],bl
jmp start
GDT:
DW 24
DW gdt,0
gdt:
DW 0,0,0,0
DW 0xffff
DW 0X0000
DW 0X9E00
DW 0X0000
DW 0Xffff
DW 0X8000;基地址0x0b8000
DW 0XF20b
DW 0X0000
jmp start
总结:
1.boot.s的改变
>复制的cx字节数要改变,要不然就会出现很奇怪的错误
>在进入kernel.s之前装好ds段寄存器
>ds段寄存器明显不能装0x8,因为0x8是代码段描述符,虽然两个的基地址都是0x00000000,但是有条件保护机制,所以要多加一个数据段描述符,而且gdt的长度也就要变成24
2.kernel.s的改变
>不用Int 0x10中断显示字符,就要把字符送到0xb8000的内存上去。(保护模式下是0xb8000,实模式下好像是0xb800)注意描述符的基址写法。
>(80*行号+列号)*2
>bh放属性,bl放值.0F黑底白字
3.lgdt
>lgdt默认的段寄存器是ds。应该跟数据有关的默认都是ds做段寄存器
4.BIT32
>kernel.s的BITS32和BIT16好像没什么区别