OSDev.org https://forum.osdev.org/ |
|
Switching CR3 to new page directory triple faults https://forum.osdev.org/viewtopic.php?f=1&t=56014 |
Page 1 of 1 |
Author: | sed4906h [ Thu Dec 02, 2021 7:56 pm ] |
Post subject: | Switching CR3 to new page directory triple faults |
I've made a function to create a new page directory, but switching to it causes a triple fault. I copy entry 0 (and 1022) from the original, and set entry 1023 to recursive page at the copy. Somehow this doesn't work. The code in question Code: uint32_t mkpdir() { uint32_t pd = phys_zalloc_start(); if(!pd) return 0; ((uint32_t*)TEMP_ADDR)[0] = (*MAKE_PGD_ADDR(PGD_RECURSE,0) & 0xfffff000) | 3; ((uint32_t*)TEMP_ADDR)[PGD_TEMP] = (*MAKE_PGD_ADDR(PGD_RECURSE,PGD_TEMP) & 0xfffff000) | 3; ((uint32_t*)TEMP_ADDR)[PGD_RECURSE] = pd | 3; asm("" ::: "memory"); phys_zalloc_end(); return pd; } The other functions and macros Code: #define PGD_TEMP 1022
#define PGD_RECURSE 1023 #define MAKE_PGD_ADDR(pgi, pti) ((uint32_t*)(PGD_RECURSE << 22 | pgi << 12 | pti << 2)) #define TEMP_ADDR ((void*)(PGD_TEMP << 22)) #define PAGE_SIZE 4096 uint32_t phys_zalloc_start() { uint32_t pg = phys_alloc(); if (!pg) return 0; *MAKE_PGD_ADDR(PGD_TEMP, 0) = pg | 3; memset(TEMP_ADDR, 0, PAGE_SIZE); return pg; } void phys_zalloc_end() { *MAKE_PGD_ADDR(PGD_TEMP, 0) = 0; uint32_t ta=(uint32_t)TEMP_ADDR; asm("invlpg %0" :: "m"(ta) : "memory"); } |
Author: | sed4906h [ Fri Dec 03, 2021 8:15 am ] |
Post subject: | Re: Switching CR3 to new page directory triple faults |
I peeked at the memory at TEMP_ADDR, and it never got written to? I know I needed to have that asm("" ::: "memory") because GCC was reordering the statements below phys_zalloc_end(), but it looks like those statements still have no effect. They should, here's GDB's disassembly. Code: 0x100640 <mkpdir>: sub $0x1c,%esp
0x100643 <mkpdir+3>: call 0x100220 <phys_zalloc_start> 0x100648 <mkpdir+8>: test %eax,%eax 0x10064a <mkpdir+10>: je 0x100698 <mkpdir+88> 0x10064c <mkpdir+12>: mov 0xfffff000,%edx 0x100652 <mkpdir+18>: and $0xfffff000,%edx 0x100658 <mkpdir+24>: or $0x3,%edx 0x10065b <mkpdir+27>: mov %edx,0xff800000 0x100661 <mkpdir+33>: mov 0xfffffff8,%edx 0x100667 <mkpdir+39>: and $0xfffff000,%edx 0x10066d <mkpdir+45>: or $0x3,%edx 0x100670 <mkpdir+48>: mov %edx,0xff800ff8 0x100676 <mkpdir+54>: mov %eax,%edx 0x100678 <mkpdir+56>: or $0x3,%edx 0x10067b <mkpdir+59>: mov %edx,0xff800ffc 0x100681 <mkpdir+65>: movl $0x0,0xffffe000 0x10068b <mkpdir+75>: movl $0xff800000,0xc(%esp) 0x100693 <mkpdir+83>: invlpg 0xc(%esp) 0x100698 <mkpdir+88>: add $0x1c,%esp 0x10069b <mkpdir+91>: ret |
Author: | neon [ Fri Dec 03, 2021 11:20 am ] |
Post subject: | Re: Switching CR3 to new page directory triple faults |
Hi, Are we to assume then based on previous posts that this question is for switching to a new task address space and that the initial paging setup code is fine now and kernel space is in place? Or is this post still about setting up kernel space initially and paging is disabled? |
Author: | sed4906h [ Fri Dec 03, 2021 11:52 am ] |
Post subject: | Re: Switching CR3 to new page directory triple faults |
Yes, this is about switching to a new task address space, and paging is enabled. |
Author: | Octocontrabass [ Mon Dec 06, 2021 1:58 am ] |
Post subject: | Re: Switching CR3 to new page directory triple faults |
sed4906h wrote: Code: 0x100693 <mkpdir+83>: invlpg 0xc(%esp) That doesn't look right. Try this instead: Code: asm("invlpg %0" :: "m"(*(char *)TEMP_ADDR) : "memory");
|
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |