进入保护模式, 使用分页机制出错
boot.S,设置GDT表, copy kernel 到0x0000, 进入保护模式
- .code16
- .text
- .global _start
- .set CODE_SEL, 0x08
- .set DATA_SEL, 0x10
- .set GDT_ADDR, 0x80000
- .set GDT_ENTRIES, 3
- .set GDT_SIZE, (8*GDT_ENTRIES)
- _start:
- jmpl $0x7c0, $start2
- gdt:
- .quad 0x0000000000000000 # null selector
- .quad 0x00cf9a000000ffff # cs base 0x00000000 limit 0xfffff code read/exec
- .quad 0x00cf92000000ffff # ds base 0x00000000 limit 0xfffff data read/write
- gdt_48:
- .word .-gdt
- .long GDT_ADDR
- start2:
- movw %cs, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %ss
- movw $0x7c00, %sp
- cli
- cld
- movb $0x0f, %ah
- xorb %al, %al
- int $0x10
- movb $0x00, %ah
- int $0x10
- #target address [es:bx][1000:0000]
- movw $0x1000, %ax
- movw %ax, %es
- movw $0x00, %bx
- movb $0x02, %ah # ah: read disk
- movb $0x01, %al # al: count of sectors
- movb $0x00, %ch # ch: track
- movb $0x02, %cl # cl: cylinder
- # dl: driver num
- int $0x13 # 13h: disk I/O
- # [ds:si] -> [es:di]
- # move kernel to 0x0000:0000
- movw $0x1000,%ax
- movw %ax, %ds
- movw $0x0000,%ax
- movw %ax, %es
- xorw %si, %si
- xorw %di, %di
- movw $(512>>2),%cx
- rep
- movsl
- # move gdt to GDT_ADDR
- movw $0x7c0, %ax
- movw %ax, %ds # reset ds to 0x07c0
- movw $gdt, %si
- movw $GDT_ADDR>>4,%ax
- movw %ax, %es
- xorw %di, %di
- movw $GDT_SIZE>>2,%cx
- rep
- movsl
- enable_a20:
- inb $0x64, %al
- testb $0x2, %al
- jnz enable_a20
- movb $0xbf, %al
- outb %al, $0x64
- lgdt gdt_48
- # set PE=1
- movl %cr0, %eax
- orl $0x1, %eax # PE = 1
- movl %eax, %cr0
- ljmp $CODE_SEL, $0x0
- .org 510
- .word 0xAA55
复制代码
kernel.S, 设置分页页目录,页表,设置CR3,CR0,
然后怎么才能叫分配出一个页来使用?
就是说需要手动设置页表吗?
- .text
- .global _start
- .org 0
- _start:
- jmp start2
- .set CODE_SEL, 0x08 # cs 00001 000
- .set DATA_SEL, 0x10 # ds 00010 000
- start2:
- movl $DATA_SEL, %eax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %ss
- movw %ax, %gs
- movl $0xa0000, %esp
- cld
- # 0x80000 - 0x80000+GDT_SIZE : GDT
- # 0x81000 - 0x82000 : page_dir
- # 0x82000 - 0x83000 : page_table
- # initialize page_dir 0x81000 -> 0x82000
- movl $0x81000, %eax
- movl $0x82007, (%eax) # page_dir[0] 只用到这一项,其他都无效
- movl $1023, %ecx
- 1:
- addl $4, %eax
- movl $6, (%eax) # page_dir[1-1023] 无效
- decl %ecx
- jnz 1b
- # initialize page_table 0x82000 -> 0x83000 共表示4M
- movl $0x82000, %eax
- movl $0x0, %ebx
- movl $1024, %ecx
- next:
- movl %ebx, (%eax)
- addl $7, (%eax) # 加上权限就没有错误了。
- addl $4, %eax
- addl $0x1000, %ebx
- decl %ecx
- jnz next
- # enable cr3
- movl $0x81000, %eax
- movl %eax, %cr3
- movl %cr0, %eax
- orl $0x80000000, %eax
- movl %eax, %cr0
- loop:
- jmp loop
- /*
- .org 0x81000
- .long 0x82007 # 82000 | 7
- .rept 1023
- .long 6 # 00000 | 6
- .endr
- .org 0x82000
- .org 0x83000
- */
复制代码
Makefile:
- AS=as -Iinclude
- LD=ld
- .S.o:
- $(AS) $< -o $*.o
- all: Image
- Image: boot kernel
- cat boot kernel.o > Image
- boot: boot.o
- $(LD) --oformat binary -N -e _start -Ttext 0x0000 -o boot $<
- kernel: kernel.o
- $(LD) --oformat binary -N -e _start -Ttext 0x0000 -o $@ $<
- clean:
- rm -f Image boot boot.o kernel kernel.o
复制代码
[ 本帖最后由 anhongkui 于 2007-6-20 15:12 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论