问题描述
我正在创建一个操作系统,我需要在实模式下调用 BIOS,我尝试了这段代码,但它有一个错误: boch 上的错误是
00002172825e[cpu0 ] check_cs: conforming code seg descriptor dpl > cpl
代码是:
global go16
;______________________________________________________________________________________________________
;Switch to 16-bit real Mode
;IN/OUT: nothing
go16:
[BITS 32]
cli ;Clear interrupts
pop edx ;save return location in edx
jmp 0x20:PM16 ;Load CS with selector 0x20
;For go to 16-bit real mode,first we have to go to 16-bit protected mode
[BITS 16]
PM16:
mov ax,0x28 ;0x28 is 16-bit protected mode selector.
mov ss,ax
mov ds,ax
mov es,ax
mov gs,ax
mov fs,ax
mov sp,0x7c00+0x200 ;Stack hase base at 0x7c00+0x200
mov eax,cr0
and eax,0xfffffffe ;Clear protected enable bit in cr0
mov cr0,eax
jmp 0x50:realMode ;Load CS and IP
realMode:
;Load segment registers with 16-bit Values.
mov ax,0x50
mov ds,ax
mov ax,0
mov ss,0
mov es,ax
hlt
mov sp,0x7c00+0x200
cli
lidt[.idtR] ;Load real mode interrupt vector table
sti
push 0x50 ;New CS
push dx ;New IP (saved in edx)
retf ;Load CS,IP and Start real mode
;Real mode interrupt vector table
.idtR:
dw 0xffff ;Limit
dd 0 ;Base
程序在 jmp 0x20:PM16 处停止
因为他不喜欢 0x20
我需要调用 bios 来切换图形模式,因为我无法在引导加载程序中执行此操作
谢谢您的回答
附注:
我的 gdt 是:
init_gdt_desc(0x0,0x0,&kgdt[0]);
init_gdt_desc(0x0,0xFFFFF,0x9B,0x0D,&kgdt[1]);
init_gdt_desc(0x0,0x93,&kgdt[2]);
init_gdt_desc(0x0,0x97,&kgdt[3]);
//user segment
init_gdt_desc(0x0,0xFF,&kgdt[4]); /* ucode */
init_gdt_desc(0x0,0xF3,&kgdt[5]); /* udata */
init_gdt_desc(0x0,0xF7,&kgdt[6]); /* ustack */
解决方法
对于不同段的 jmp
或 call
,您需要遵守以下特权规则之一:
- 目标 DPL 等于 CPL
- 目标 DPL 小于或等于 CPL,但设置了目标符合位
看看你的选择器,目标 DPL 是 3,CPL 是 0。
所以要使用jmp 0x20:PM16
,请更改
init_gdt_desc(0x0,0xFFFFF,0xFF,0x0D,&kgdt[4]); /* ucode */
进入
init_gdt_desc(0x0,0x9F,&kgdt[4]); /* ucode */
;Real mode interrupt vector table
.idtR:
dw 0xffff ;Limit
dd 0 ;Base
正确的限制是 0x03FF(十进制 1023)
[编辑]
由于目标是进入实模式,描述符中的 BIG 位应关闭以选择 16 位,GRANULARITY 位应关闭以限制内存访问仅 1MB。
init_gdt_desc(0x0,0xFFFF,0x9E,0x0,&kgdt[4]); /* ucode */
init_gdt_desc(0x0,0x92,&kgdt[5]); /* udata */
您当前程序中的顺序与here有关从保护模式切换到实模式的顺序不同。