I'm following James Molloy's OS Development tutorial.
I'm in Paging chapter, and I'm having trouble getting it to work.
I use QEMU to run the ISO and GDB to debug the code.
Everything works until I reach the enablePaging function (xor cr0 with 0x80000000), and afterwards the code that starts executing is garbage.
(In GDB)
Code before enabling paging:
Code: Select all
0x101438 <_enable_paging+1>: mov ebp,esp
0x10143a <_enable_paging+3>: mov eax,cr0
0x10143d <_enable_paging+6>: or eax,0x80000000
=> 0x101442 <_enable_paging+11>: mov cr0,eax
0x101445 <_enable_paging+14>: mov esp,ebp
0x101447 <_enable_paging+16>: pop ebp
0x101448 <_enable_paging+17>: ret
0x101449 <gdt_dump>: mov eax,DWORD PTR [esp+0x4]
Registers:
eax 0x80000011 0x80000011
ecx 0xb8000 0xb8000
edx 0x10077c 0x10077c
ebx 0x10000 0x10000
esp 0x107c38 0x107c38
ebp 0x107c38 0x107c38
esi 0x0 0x0
edi 0x0 0x0
eip 0x101442 0x101442 <_enable_paging+11>
eflags 0x286 [ PF SF IF ]
cs 0x8 0x8
ss 0x10 0x10
ds 0x10 0x10
es 0x10 0x10
fs 0x10 0x10
gs 0x10 0x10
After (one single step):
Code: Select all
0x10143f <_enable_paging+8>: add BYTE PTR [eax],al
0x101441 <_enable_paging+10>: add BYTE PTR [eax],al
0x101443 <_enable_paging+12>: add BYTE PTR [eax],al
=> 0x101445 <_enable_paging+14>: add BYTE PTR [eax],al
0x101447 <_enable_paging+16>: add BYTE PTR [eax],al
0x101449 <gdt_dump>: add BYTE PTR [eax],al
0x10144b <gdt_dump+2>: add BYTE PTR [eax],al
0x10144d <gdt_dump+4>: add BYTE PTR [eax],al
Registers:
eax 0x80000011 0x80000011
ecx 0xb8000 0xb8000
edx 0x10077c 0x10077c
ebx 0x10000 0x10000
esp 0x107c38 0x107c38
ebp 0x107c38 0x107c38
esi 0x0 0x0
edi 0x0 0x0
eip 0x101445 0x101445 <_enable_paging+14>
eflags 0x286 [ PF SF IF ]
cs 0x8 0x8
ss 0x10 0x10
ds 0x10 0x10
es 0x10 0x10
fs 0x10 0x10
gs 0x10 0x10
Code: Select all
void kernel::paging::start()
{
// allocate array of frame indexes
nframes = (K_PHYSICAL_MEM_SIZE / K_PAGE_SIZE);
frames = (uint32_t*)heap::allocate(INDEX_FROM_BIT(nframes), false);
memset(frames, 0, INDEX_FROM_BIT(nframes));
// TODO: When I implement new, change this to calling the constrcutor of page_directory_t
kernel_directory = (page_directory_t*)heap::allocate(sizeof(page_directory_t));
memset(kernel_directory, 0, sizeof(page_directory_t));
// we are currently using this directory
current_directory = kernel_directory;
// identity map the kernel
uint32_t i = 0;
while(i < __kernel_heap)
{
frame::alloc(get_page(
i,
kernel_directory,
true
), // we want to create all pages in directory
false, // this directory is the kernel's
false // kernel directory is1 not writeable from user space
);
i += PAGE_SIZE;
printf("loop %d\n", i);
}
interrupts::set_handler((uint32_t)InterruptList::PageFault, __page_fault_handler);
// this will enable paging
set_directory(kernel_directory);
paging::enable(); // just calls _enable_paging
}
void kernel::paging::set_directory(page_directory_t* dir)
{
current_directory = dir;
_load_page_directory((uint32_t*)&dir->tables_physical);
}
page_t* kernel::paging::get_page(uint32_t address, page_directory_t* dir, bool create)
{
address /= PAGE_SIZE;
uint32_t table_idx = address / 1024;
// if we find an existing table, return it
if (dir->tables[table_idx] != nullptr)
{
return &dir->tables[table_idx]->pages[address%1024];
}
// if no, create one and return it
if (create)
{
uint32_t table_ptr = 0;
dir->tables[table_idx] = (page_table_t*)heap::allocate_p(
sizeof(page_directory_t),
&table_ptr // save the physical address
);
memset(dir->tables[table_idx], 0, PAGE_SIZE);
dir->tables_physical[table_idx] = table_ptr | 0x7; // PRESENT, RW, US
return &dir->tables[table_idx]->pages[address%1024];
}
return (page_t*)PAGE_NOT_FOUND;
}
Could someone please help me with my error or point me as to how I might fix this?
Thanks in advance!