OSDev.org https://forum.osdev.org/ |
|
Bad Code After Enabling Paging https://forum.osdev.org/viewtopic.php?f=1&t=35989 |
Page 1 of 1 |
Author: | F4doraOfDoom [ Tue Nov 05, 2019 5:12 am ] |
Post subject: | Bad Code After Enabling Paging |
Hey, 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: 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: 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 Here is my code (some of my coding conventions may seem weird): Code: 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; } I've been searching for an explenation for this kind of mistake, but haven't found any. Could someone please help me with my error or point me as to how I might fix this? Thanks in advance! |
Author: | iansjack [ Tue Nov 05, 2019 5:17 am ] |
Post subject: | Re: Bad Code After Enabling Paging |
It looks like you haven't identity mapped the page(s) that your code is running in (or haven't done it correctly). So as soon as you enable paging you are pointing to a different physical address. You need to either (a) identity map the pages that the kernel occupies or (b) before paging copy the code to the pages that you have mapped its address range to. |
Author: | F4doraOfDoom [ Tue Nov 05, 2019 11:18 am ] |
Post subject: | Re: Bad Code After Enabling Paging |
iansjack wrote: It looks like you haven't identity mapped the page(s) that your code is running in (or haven't done it correctly). So as soon as you enable paging you are pointing to a different physical address. You need to either (a) identity map the pages that the kernel occupies or (b) before paging copy the code to the pages that you have mapped its address range to. Hey, I define my __kernel_heap like this: Code: uint32_t __kernel_heap = (uint32_t)&end; // this will be the beginning of the kernel's heap where "end" is defined by the linker like this: Code: ENTRY(_start) SECTIONS { .text 0x100000 : { code = .; _code = .; __code = .; *(.multiboot) *(.text) . = ALIGN(4096); } .data : { data = .; _data = .; __data = .; *(.data) *(.rodata) . = ALIGN(4096); } .bss : { bss = .; _bss = .; __bss = .; *(.bss) . = ALIGN(4096); } end = .; _end = .; __end = .; } Since I identity map all the way from 0 to __kernel_heap, shouldn't all of the program's code be identity mapped as well already? |
Author: | iansjack [ Tue Nov 05, 2019 12:03 pm ] |
Post subject: | Re: Bad Code After Enabling Paging |
You certainly map that address range, but I'm not convinced that you identity map it. I don't see enough of your code to be sure. The other possibility is that you clear a physical page when you allocate. Your best bet is to set a breakpoint just before you enable paging, then check the page table. |
Author: | F4doraOfDoom [ Sat Nov 09, 2019 6:27 am ] |
Post subject: | Re: Bad Code After Enabling Paging |
I fixed the problem! For future generations: I'm not exactly sure where I had it wrong, but I suspect it was with the frame allocations. I the paging with my own design and understanding of Paging (still heavily relying on the tutorial) and it worked! I used a normal boolean array instead of a BITSET. Now that I know it works, I'll be changing the implementation to use a bitset instead. |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |