写了个操作系统从实模式跳转到保护模式的过程,不知道对不对
1.在一个固定地址处处创建GDT,设置堆栈积存器地址
2.读取硬盘中的load.s到0x0处
3.打开A20地址线,设置积存器PE位,进入保护模式
4.跳转到0x0处执行load.s
注:设load.s为内核程序
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
1.在一个固定地址处处创建GDT,设置堆栈积存器地址
2.读取硬盘中的load.s到0x0处
3.打开A20地址线,设置积存器PE位,进入保护模式
4.跳转到0x0处执行load.s
注:设load.s为内核程序
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
进入保护模式之前,要先为保护模式建立必要的环境。GDT 是其中一个,另一个是 IDT
我怎么感觉IDT并不是必须的呢?
关了中断就可以不用idt,但这样比较无趣。
请问我可不可以在启动的时候(跳入保护模式之前)把内核加载到0X0000位置呢?我尝试着这么做了但好象不行,是不是必须关中断才行?
在pc中,0x0000处存放中断向量表,不能加载到那里,建议先在google上搜一下bios初始化完成后的内存布局
什么叫保护模式,要理解它的真正意义才行呀。当然,你直接将 CR0.PE 直接置 1 可以让处理器处于 Protected mode,但这样是不能正常工作的。描述符表及描述符的意义在于处理器可以提供别代码的几个该问权限级别。
从物理上来说,在 protected mode 下,执行 int 指令必须经过 IDT 该问中断例程。你的系统从来绝对不执行 INT 么?
我还是把代码贴上来吧
boot.s
.text
.globl start
.set CODE_SEL, 0x08
.set DATA_SEL, 0x10
.set IDT_ADDR, 0x80000
.set IDT_SIZE, (256*
.set GDT_ADDR, (IDT_ADDR+IDT_SIZE)
.set GDT_ENTRIES, 5
.set GDT_SIZE, (8*GDT_ENTRIES)
.set KERNEL_SECT, 2
.set STACK_BOT, 0xa0000
.code16
start:
jmp code
gdt:
.quad 0x0000000000000000
.quad 0x00cf9a000000ffff
.quad 0x00cf92000000ffff
.quad 0x0000000000000000
.quad 0x0000000000000000
gdt_48:
.word .-gdt-1
.long GDT_ADDR
code:
xorw %ax, %ax
movw %ax, %ds
movw %ax, %ss
movw $0x1000,%sp
movw $0x0000,%ax
movw %ax, %es
xorw %bx, %bx
movw $KERNEL_SECT,%cx
movw $1, %si
rd_kern:
call read_sect
addw $512, %bx
incw %si
loop rd_kern
cli
cld
xorw %ax, %ax
movw %ax, %ds
movw $GDT_ADDR>>4,%ax
movw %ax, %es
movw $gdt, %si
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
movl %cr0, %eax
orl $0x1, %eax
movl %eax, %cr0
ljmp $CODE_SEL, $0x0
read_sect:
pushw %ax
pushw %cx
pushw %dx
pushw %bx
movw %si, %ax
xorw %dx, %dx
movw $18, %bx
divw %bx
incw %dx
movb %dl, %cl
xorw %dx, %dx
movw $2, %bx
divw %bx
movb %dl, %dh
xorb %dl, %dl
movb %al, %ch
popw %bx
rp_read:
movb $0x1, %al
movb $0x2, %ah
int $0x13
jc rp_read
popw %dx
popw %cx
popw %ax
ret
.org 0x1fe, 0x90
.word 0xaa55
load.s
a.text
.globl pm_mode
.org 0
pm_mode:
movl $0x10, %eax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl $0xa0000, %esp
cld
movb $0x07, %al
movl $msg, %esi
movl $0xb8000,%edi
1:
cmp $0, (%esi)
je 1f
movsb
stosb
jmp 1b
1: jmp 1b
msg:
.string "Hello World!\x0"
我在进入保护模式之后只是让他打印了一个HELLO WORLD,没有用INT
但是我现在这段程序就是运行不起来,不知道怎么搞的
终于找到原因了,是因为我把0X0000处的BIOS中断表给覆盖了,改了加载地址和GDT地址,下面把测试通过的代码贴上来,请指教
boot.s
复制代码
load.s
复制代码
as -o boot.o boot.s
ld --oformat binary -N -e start -Ttext 0x7c00 -o boot.img boot.o
as -o load.o load.s
ld --oformat binary -N -e pm_mode -Ttext 0x10000 -o load.img load.o
cat boot.img load.img > final.img
用VMWARE加载 final.img 即可
[ 本帖最后由 shineyear 于 2007-5-30 11:13 编辑 ]