Page 2 of 3

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 4:16 pm
by BluCode
Thanks for clarifying, but that still doesn't solve the problem, which is still an issue if I set the R/W bits of the page table entries. Also could you explain how virtual address are translated into physical ones, as I don't quite understand the diagrams I've seen.

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 4:32 pm
by iocoder
If you still don't understand the multi-level nature of page table hierarchy in x86, refer to this section on wikipedia: (https://en.wikipedia.org/wiki/Page_tabl ... page_table).

Say, for example, your program is going to access the logical address 0x00002ABC. Several calculations are handled first:
page index = 0x00002ABC>>12 = 0x00002.
DIR PAGE ENTRY INDX = 0x00002/1024 = 0
PG TBL ENTRY INDX = 0x00002%1024 = 2

Next, the i386 CPU turns attention to your page directory (which is stored at 0xD000 in your case). Entry i of the page directory gives us information about the page tables that covers the (i+1)th 4MB of logical memory. According to the calculations above, we should look at DIR PAGE ENTRY INDX 0, which contains 0x0000F007 in your case. This means that the page table that covers this part of memory exists at physical address 0x0000F000.

Finally, the i386 loads the addressed page table in TLB (if not loaded) and reads the desired PG TBL ENTRY from it. In our case, we want the entry that is located at index 2. This page table entry stores the value of 0x00002005, indicating that the physical address of the required page is 0x00002000, and hence the translation process would yield 0x00002ABC.

So, as you can see, translation is done over multiple stages. You can refer to section 5.2 of the manual for more illustration. The figures shall help you.

Best of luck!

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 4:37 pm
by BluCode
Ah I see, that you very much. Do you have any ideas as to what could be causing the reboot cycle?

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 4:39 pm
by iocoder
If you put a halting jump (asm("jmp .") as iansjack has suggested) just after you set the PE flag of cr0, what happens?

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 4:51 pm
by BluCode
I see no change whatsoever, it still goes into the infinite reboot.

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 4:56 pm
by iocoder
OK could you please show us a summary of the state of your registers just before you set the PE flags? you can use qemu's 'info registers' command for this purpose.

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 5:10 pm
by BluCode
Here are the register values before enabling paging:

Code: Select all

EAX=00000011 EBX=00007d3c ECX=0000f000 EDX=0000830d
ESI=00000000 EDI=00000000 EBP=0008ffa0 ESP=0008ff90
EIP=00008505 EFL=00000286 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     0000b060 00000027
IDT=     0000b0a0 000007ff
CR0=00000011 CR2=00000000 CR3=0000d000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
I could not figure out how to scroll the QEMU monitor, as ctrl+alt+pgup/pgdown didn't work, so I redirected it, but any input there would help as well.

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 5:18 pm
by iocoder
BluCode wrote:Here are the register values before enabling paging:

Code: Select all

EAX=00000011 EBX=00007d3c ECX=0000f000 EDX=0000830d
ESI=00000000 EDI=00000000 EBP=0008ffa0 ESP=0008ff90
EIP=00008505 EFL=00000286 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     0000b060 00000027
IDT=     0000b0a0 000007ff
CR0=00000011 CR2=00000000 CR3=0000d000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
I could not figure out how to scroll the QEMU monitor, as ctrl+alt+pgup/pgdown didn't work, so I redirected it, but any input there would help as well.
Thank you. Our first note here is the values of EBP and ESP. Do your identity page tables cover memory up to 0x8XXXX (above 512KB)?

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 5:34 pm
by BluCode
Given that my first (and only) page table only has 16 frames, I would think not.

Code: Select all

(gdb) x 0xD000
0xd000: 0x0000f007
(gdb) x 0xf000
0xf000: 0x00000007
(gdb) x 0xf03c
0xf03c: 0x0000f007
(gdb) x 0xf040
0xf040: 0x00000000
I set up the stack to be very far from the kernel, and therefore very far from placement_address (_end from the linker). Is that good or bad, and why?

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 5:43 pm
by iocoder
BluCode wrote:Given that my first (and only) page table only has 16 frames, I would think not.

Code: Select all

(gdb) x 0xD000
0xd000: 0x0000f007
(gdb) x 0xf000
0xf000: 0x00000007
(gdb) x 0xf03c
0xf03c: 0x0000f007
(gdb) x 0xf040
0xf040: 0x00000000
I set up the stack to be very far from the kernel, and therefore very far from placement_address (_end from the linker). Is that good or bad, and why?
The way you allocate your stack depends on your design philosophy, which is very subjective by its nature. But anyway, the problem here is that it is assigned a memory range that is higher than placement_address, in which case a PAGE FAULT will happen whenever your CPU tries to access the stack. Your identity maps should cover the stack as well, not just the kernel code and data.
Furthermore, could you please show me the code at which you use __asm__("jmp ."); after setting PE? what about this one:

Code: Select all

void switch_page_directory(page_directory_t *dir)
{
   current_directory = dir;
   asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
   u32int cr0;
   asm volatile("mov %%cr0, %0": "=r"(cr0));
   cr0 |= 0x80000000; // Enable paging!
   asm volatile("mov %0, %%cr0; jmp .":: "r"(cr0)); // <-- can you see it? :D
}

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 5:53 pm
by BluCode
I see. Yes I do my jump there, just in a new asm call. I'll probably not be able to try that change today as I am busy, but we'll see.

Re: OS crashes on paging enable

Posted: Sat Jun 03, 2017 6:02 pm
by iocoder
Take your time. I also forgot to mention that asynchronous interrupt requests that are issued by hardware in the background could also be fatal, since they make use of the stack.... which is actually not mapped. The result is that you end up with an infinite recursive page fault. You may want to disable interrupts before setting the PE flag, then enter the halting jump and see the results.

Code: Select all

void switch_page_directory(page_directory_t *dir)
{
   current_directory = dir;
   asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
   u32int cr0;
   asm volatile("mov %%cr0, %0": "=r"(cr0));
   cr0 |= 0x80000000; // Enable paging!
   asm volatile("cli; mov %0, %%cr0; jmp .":: "r"(cr0)); // <-- disable interrupts; store cr0, then jmp forever.
}
As you can see, there are a lot of things to try out. Good luck with your debugging :D

Re: OS crashes on paging enable

Posted: Sun Jun 04, 2017 7:48 am
by BluCode
It works! Turns out I just wasn't mapping enough of ram, even though the stack is under the kernel, and so was mapped. I tried disabling interrupts before enabling and that worked, but then I re-looked over my code and it turned out that my stack was at 7BFF and my kernel started at 7E00. Anyways I just identity mapped up to 16MB and now its working. Thanks for all your help!

Re: OS crashes on paging enable

Posted: Sun Jun 04, 2017 8:12 am
by iocoder
BluCode wrote:It works! Turns out I just wasn't mapping enough of ram, even though the stack is under the kernel, and so was mapped. I tried disabling interrupts before enabling and that worked, but then I re-looked over my code and it turned out that my stack was at 7BFF and my kernel started at 7E00. Anyways I just identity mapped up to 16MB and now its working. Thanks for all your help!
According to the values of EBP and ESP, it seems that the stack (at the moment of setting cr0) is at 0x8FFFF, not at 0x7BFF. I suggest you check it out. We can conclude now that infinitely recursive page fault (IRPF) leads to CPU reset. However, I am still not sure about it. Needs more digging.

Re: [Solved] OS crashes on paging enable

Posted: Sun Jun 04, 2017 9:27 am
by BluCode
It turns out that I didn't set esp and ebp in pm, just sp and bp in real mode. I set them in pm and now all is well, although ebp is slightly lower than I set it to, which is weird. (0x7bf3 instead of 0x7bff).