启动分页功能机器就重启,各位大虾请帮忙看看
启动分页功能后的第一条指令就失败bosch日志
00009487429i Booting from 0000:7c00
00022352092i CPU is in protected mode (active)
00022352092i CS.d_b = 16 bit
00022352092i SS.d_b = 16 bit
00022352092i EFER= 0x00000000
00022352092i ¦ RAX=0000000080000011RBX=0000000000000010
00022352092i ¦ RCX=0000000000000000RDX=0000000000000001
00022352092i ¦ RSP=0000000000000000RBP=0000000000000912
00022352092i ¦ RSI=0000000000000026RDI=0000000000002000
00022352092i ¦R8=0000000000000000R9=0000000000000000
00022352092i ¦ R10=0000000000000000R11=0000000000000000
00022352092i ¦ R12=0000000000000000R13=0000000000000000
00022352092i ¦ R14=0000000000000000R15=0000000000000000
00022352092i ¦ IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf
00022352092i ¦ SEG selector base limit G D
00022352092i ¦ SEG sltr(index ¦ti ¦rpl) base limit G D
00022352092i ¦CS:0008( 0001 ¦ 0 ¦0) 000174d0 000000b3 0 0
00022352092i ¦DS:174d( 0005 ¦ 0 ¦0) 000174d0 0000ffff 0 0
00022352092i ¦SS:174d( 0005 ¦ 0 ¦0) 000174d0 0000ffff 0 0
00022352092i ¦ES:0018( 0003 ¦ 0 ¦0) 00000000 000fffff 1 0
00022352092i ¦FS:0000( 0005 ¦ 0 ¦0) 00000000 0000ffff 0 0
00022352092i ¦GS:0000( 0005 ¦ 0 ¦0) 00000000 0000ffff 0 0
00022352092i ¦MSR_FS_BASE:0000000000000000
00022352092i ¦MSR_GS_BASE:0000000000000000
00022352092i ¦ RIP=00000000000000b1 (00000000000000b1)
00022352092i ¦ CR0=0x80000011 CR1=0x0 CR2=0x0000000000000040
00022352092i ¦ CR3=0x00100000 CR4=0x00000000
00022352092i (instruction unavailable) page not present
00022352092e exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00022352092i bx_pc_system_c::Reset(SOFTWARE) called
00022352092i cpu software reset
从错误日志看,是我的分页不对,但我对比了多次了,我的第1条页目录所对应的页表映射4M的空间,我的程序因为在这个范围内呀。
编译命令:
D:\asm\source>nasm -f obj d.asm
D:\asm\source>alink d
ALINK v1.6 (C) Copyright 1998-9 Anthony A.J. Williams.
All Rights Reserved
Loading file d.obj
matched Externs
matched ComDefs
Warning - no stack
源代码:
;存储段描述符类型值说明
;----------------------------------------------------------------------------
ATDR equ 90h ;存在的只读数据段类型值
ATDW equ 92h ;存在的可读写数据段属性值
ATDWA equ 93h ;存在的已访问可读写数据段类型值
ATCE equ 98h ;存在的只执行代码段属性值
ATCER equ 9ah ;存在的可执行可读代码段属性值
ATCCO equ 9ch ;存在的只执行一致代码段属性值
ATCCOR equ 9eh ;存在的可执行可读一致代码段属性值
;----------------------------------------------------------------------------
;其它常量值说明
;----------------------------------------------------------------------------
GL equ 80h ;段界限以4K为单位标志
;----------------------------------------------------------------------------
;分页机制使用的常量说明
;----------------------------------------------------------------------------
PL equ 1 ;页存在属性位
RWR equ 0 ;R/W属性位值,读/执行
RWW equ 2 ;R/W属性位值,读/写/执行
USS equ 0 ;U/S属性位值,系统级
USU equ 4 ;U/S属性位值,用户级
segment a
desc_null:
dw 0;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db 0;Attributes(m+5)
db 0;Attributes(m+6)
db 0;Base(31...24)
desc_code:
dw a_end;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db ATCER;Attributes(m+5)
db 0;Attributes(m+6)
db 0;Base(31...24)
desc_data:
dw a_end;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db ATDWA;Attributes(m+5)
db 0;Attributes(m+6)
db 0;Base(31...24)
desc_line:
dw 0xffff;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db ATDWA;Attributes(m+5)
db 0xf + GL;Attributes(m+6)
db 0;Base(31...24)
sel_code equ desc_code - desc_null
sel_data equ desc_data - desc_null
sel_line equ desc_line - desc_null
vgdt:
dw 0xffff
dd 0
..start:
mov ax,a
mov ds,ax
mov bx,16
mul bx
mov ,ax
mov ,ax
mov ,dl
mov ,dl
mov ,dh
mov ,dh
mov ,ax
mov ,dx
cli
lgdt
mov eax,cr0
or eax,1
mov cr0,eax
jmp sel_code:do
real:
mov ax,4c00h
int 21h
do:
;初始化页目录表
mov ax,sel_line
mov es,ax
;初始化两个页目录表
mov dword,0x00001000+USU+RWW+PL
;初始化第一个页目录表项的页表项
mov ax,sel_line
mov es,ax
mov edi,0x00001000
mov cx,1024
xor eax,eax
or eax,USU+RWW+PL
loop1:stosd
add eax,0x1000
loop loop1
;切换
mov eax,0x00100000
mov cr3,eax
mov eax,cr0
or eax,80000000h
mov cr0,eax
jmp $ ;就这里出错了
a_end: haha
见笑了! 页结构没设置好 上面的代码由问题。
用下面的代码替换相应部分是可以的。页目录地址在0处
;初始化页目录表
mov ax,sel_line
mov es,ax
;初始化两个页目录表
mov dword,0x00001000+USU+RWW+PL
;初始化第一个页目录表项的页表项
mov ax,sel_line
mov es,ax
mov edi,0x00001000
mov cx,1024
xor eax,eax
or eax,USU+RWW+PL
loop1:stosd
add eax,0x1000
loop loop1
;切换
mov eax,0x00000000
mov cr3,eax
mov eax,cr0
or eax,80000000h
mov cr0,eax
jmp $
但是如果页目录地址在1M处就不行。不知道为什么
相关部分代码
mov ax,sel_line
mov es,ax
;初始化两个页目录表
mov dword,0x00101000+USU+RWW+PL
;初始化第一个页目录表项的页表项
mov ax,sel_line
mov es,ax
mov edi,0x00101000
mov cx,1024
xor eax,eax
or eax,USU+RWW+PL
loop1:stosd
add eax,0x1000
loop loop1
;切换
mov eax,0x00100000
mov cr3,eax
mov eax,cr0
or eax,80000000h
mov cr0,eax
jmp $ CR3=0x00100000
A20没打开吧 开启了,问题依旧。新的代码如下:
如果PAGE_DIR_ADDR=0x0,则运行正常;如果改为0x00100000,则在JMP $时,重启
;存储段描述符类型值说明
;----------------------------------------------------------------------------
ATDR equ 90h ;存在的只读数据段类型值
ATDW equ 92h ;存在的可读写数据段属性值
ATDWA equ 93h ;存在的已访问可读写数据段类型值
ATCE equ 98h ;存在的只执行代码段属性值
ATCER equ 9ah ;存在的可执行可读代码段属性值
ATCCO equ 9ch ;存在的只执行一致代码段属性值
ATCCOR equ 9eh ;存在的可执行可读一致代码段属性值
;----------------------------------------------------------------------------
;其它常量值说明
;----------------------------------------------------------------------------
GL equ 80h ;段界限以4K为单位标志
;----------------------------------------------------------------------------
;分页机制使用的常量说明
;----------------------------------------------------------------------------
PL equ 1 ;页存在属性位
RWR equ 0 ;R/W属性位值,读/执行
RWW equ 2 ;R/W属性位值,读/写/执行
USS equ 0 ;U/S属性位值,系统级
USU equ 4 ;U/S属性位值,用户级
PAGE_DIR_ADDR equ 0x00100000 ;U/S属性位值,用户级
segment a
desc_null:
dw 0;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db 0;Attributes(m+5)
db 0;Attributes(m+6)
db 0;Base(31...24)
desc_code:
dw a_end;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db ATCER;Attributes(m+5)
db 0;Attributes(m+6)
db 0;Base(31...24)
desc_data:
dw a_end;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db ATDWA;Attributes(m+5)
db 0;Attributes(m+6)
db 0;Base(31...24)
desc_line:
dw 0xffff;Segment Limite
dw 0;Segment Base(15...0)
db 0;Segment Base(23...16)
db ATDWA;Attributes(m+5)
db 0xf + GL;Attributes(m+6)
db 0;Base(31...24)
sel_code equ desc_code - desc_null
sel_data equ desc_data - desc_null
sel_line equ desc_line - desc_null
vgdt:
dw 0xffff
dd 0
..start:
mov ax,a
mov ds,ax
mov bx,16
mul bx
mov ,ax
mov ,ax
mov ,dl
mov ,dl
mov ,dh
mov ,dh
mov ,ax
mov ,dx
;打开A20地址线
push ax
in al,92h
or al,00000010b
out 92h,al
pop ax
cli
lgdt
mov eax,cr0
or eax,1
mov cr0,eax
jmp sel_code:do
real:
mov ax,4c00h
int 21h
do:
;初始化页目录表
mov ax,sel_line
mov es,ax
;初始化两个页目录表
mov dword,PAGE_DIR_ADDR + 0x00001000 +USU+RWW+PL
;初始化第一个页目录表项的页表项
mov ax,sel_line
mov es,ax
mov edi,0x00101000
mov cx,1024
xor eax,eax
or eax,USU+RWW+PL
loop1:stosd
add eax,0x1000
loop loop1
;切换
mov eax,PAGE_DIR_ADDR
mov cr3,eax
mov eax,cr0
or eax,80000000h
mov cr0,eax
jmp $
a_end: ??
不会没有大虾知道吧!!
页:
[1]