A20 + GDT + Paging = mess
Posted: Mon Aug 15, 2005 12:08 pm
hi all, ok, i used the gdt trick to get my kernel to think it is a 0xc0000000, it starts fine but when i set a20 or paging, EIP goes to 0xFFFFFFFF??? my a20 is:
and my paging is:
and bochs says:
i have no clue, any thing obvious?, thx
Code: Select all
a20:
call empty
mov al, 0xd1
out 0x64,al
call empty
mov al, 0xdf
out 0x60,al
call empty
jmp gdt
empty:
call delay
in al, 0x64
test al, 2
jnz empty
ret
delay:
nop
ret
Code: Select all
#define nonsuplev 4
#define read_write 2
#define present 1
unsigned long page_directory[1024];
unsigned long page_table[1024];
unsigned long page_table2[1024];
int read_cr0()
{
int cr0;
asm("movl %%cr0, %0":"=r"(cr0));
return cr0;
}
void write_cr0(int cr0)
{
asm("movl %0, %%cr0"::"r"(cr0));
}
int read_cr3()
{
int cr3;
asm("movl %%cr3, %0":"=r"(cr3));
return cr3;
}
void write_cr3(int cr3)
{
asm("movl %0, %%cr3"::"r"(cr3));
}
void idpage(unsigned long *ptable, unsigned long from, int size)
{
from = from & 0xfffff000;
for(; size; from += 4096, ptable++, size--)
*ptable = from | read_write | present; // mark page present.
}
void set_paging()
{
int x;
unsigned long physaddr = 0x0;
idpage(page_table, physaddr, 1024);
for(x = 0; x < 1024; x++) // fill directory with nonpresent pages
{
page_directory[x] = 0 | read_write;
}
page_directory[0x0] = (int)page_table | read_write | present; // set test table to 0x0 in directory
page_directory[0x300] = (int)page_table | read_write | present; // set test table to 0xC0000000 in directory
write_cr3((int)0x9D000); // write pointer to cr3
write_cr0(read_cr0() | 0x80000000); // set paging bit
}
Code: Select all
00002419057i[CPU ] write_virtual_checks(): write beyond limit, r/w
00002419057e[CPU ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting