4
我有一個玩具內核,我正在x86上運行bochs。當我啓用分頁時,bochs會重置三重錯誤。它似乎是觸發錯誤的每一個和任何內存訪問。所以,我假設我在設置分頁時出錯,而這個問題與我的中斷處理程序無關。這是代碼。如何設置x86分頁?獲取三重故障錯誤
paging.c
#include "paging.h"
#include "lib.h"
#include "screen.h"
#include "descriptor_tables.h"
typedef struct page_dir_entry_s{
bool present:1;
bool writeable:1;
bool user_access:1;
bool write_through:1;
bool cache_disabled:1;
bool accessed:1;
bool unused0:1;
bool use_mb:1;//makes pages 4MB not 4KB
bool unused1:4;
u32 frame:20;
} page_dir_entry_t;
typedef struct page_table_entry_s{
bool present:1;
bool writeable:1;
bool user_access:1;
bool write_through:1;
bool cache_disabled:1;
bool accessed:1;
bool dirty:1;
bool unused0:1;
bool global:1;
bool unused1:3;
u32 phys_page_addr:20;
} page_table_entry_t;
extern u32 end;//as declared in the linker script
static u32 next_addr=0;
static page_dir_entry_t* page_dir=NULL;
static page_table_entry_t* page_table=NULL;
extern void enable_paging(u32);
void InitPaging(){
next_addr=end;
while((next_addr%4096)!=0)
++next_addr;
page_dir=(void*)next_addr;
next_addr+=4*1024;
memset(page_dir,0,4*1024);
page_table=(void*)next_addr;
next_addr+=4;
u32 addr=0;
u32 i=0;
*(((u32*)page_table)+i)=0;//zero it out
while(addr<next_addr){
page_table[i].present=true;
page_table[i].writeable=true;
page_table[i].phys_page_addr=addr;
++i;
*(((u32*)page_table)+i)=0;//zero it out
addr+=(1024*4);//4KB
next_addr+=4;
}
page_dir[0].writeable=true;
page_dir[0].present=true;
page_dir[0].frame=(u32)page_table;
enable_paging((u32)page_dir);
}
paging_asm.s
[global enable_paging]
enable_paging:
mov eax,[esp+4]
mov cr3,eax
mov eax,cr0
or eax,0x80000000
mov cr0,eax
ret
你把你的堆棧放在內核之後嗎?如果是這樣,任何堆棧訪問都會導致此錯誤(三重錯誤,因爲如果沒有堆棧,則無法處理中斷)。如果您的bochs已啓用調試器,請使用show dbg-all來獲取有關原因的更多信息。另外,爲了循環next_addr而沒有循環:next_addr =(next_addr + 0xFFF)&0xFFFFF000' – ughoavgfhw
當我運行它時,next_addr = 0x250A8000和esp = 0x7FE2C,所以這不是問題。 – Maz
最小工作分頁示例:https://github.com/cirosantilli/x86-bare-metal-examples/blob/24988411adf10cf9f6afd1566e35472eb8ae771a/paging.S –