OSDev.org
https://forum.osdev.org/

System hangs when writing to address range
https://forum.osdev.org/viewtopic.php?f=1&t=33481
Page 2 of 2

Author:  zhiayang [ Fri Feb 15, 2019 12:08 am ]
Post subject:  Re: System hangs when writing to address range

What kind of weird results are you getting?

Author:  Scoopta [ Fri Feb 15, 2019 7:18 pm ]
Post subject:  Re: System hangs when writing to address range

zhiayang wrote:
What kind of weird results are you getting?

Using the code I linked previously I'm reading pd[504] and all other structures(pml4, pdp, and pt) with index 0. That should be the entry for 0x3F000000. Thing is when reading the pt entry for it the present bit is set to 0 as well as the read/write bit. Shouldn't the present bit be 1 since the page is present? Furthermore if I for example use index 0 for all structures which should be the entry for address 0x0 it also has present and read/write set to 0 yet based on the memory map both of these regions should exist and I can write to 0x0(that's where I'm placing my gdt descriptor) without an issue while 0x3F000000 causes a page fault. Am I misunderstanding something, is my code wrong, or is this as weird as I think it is?

Author:  zhiayang [ Sun Feb 17, 2019 7:03 am ]
Post subject:  Re: System hangs when writing to address range

Hey, apologies for the delay. Not sure if you've figured this out already, but in case you haven't:

so, your code is correct, insofar as it handles 4KB pages. :D

however, (unless you removed experimental code) you don't support some of the flags -- notably, the "size" flag of the page table. I personally don't use bitfields to do this but rather bitmasks, and so inspecting the raw value in the page directory entry, i saw "0xE3" -- which is Present (0x1), Read/Write (0x2), Accessed (0x20), and also Dirty (0x40) and Large(0x80). (in your structs you marked them as "padding1").

From the AMD manual:

Quote:
Dirty (D) Bit. Bit 6. This bit is only present in the lowest level of the page-translation hierarchy
...
Page Size (PS) Bit. Bit 7. This bit is present in page-directory entries and long-mode page-directory-pointer entries. When the PS bit is set in the page-directory-pointer entry (PDPE) or page-directory entry (PDE), that entry is the lowest level of the page-translation hierarchy.


So, to conclude, the firmware has used 2MB pages to map some of the address space, which might line up with why you're getting "strange" results. If you continued to try and read a page table entry (as you do), you'd read memory from page 0, which explains why seemingly none of the bit flags are set.

It kinda makes sense that UEFI would use large pages (who knows, you might find 1GB pages possibly?), because they require identity mapping the entirety of physical memory -- that'd be done a lot more efficiently with large or even huge pages.

Author:  Scoopta [ Sun Feb 17, 2019 6:22 pm ]
Post subject:  Re: System hangs when writing to address range

zhiayang wrote:
Hey, apologies for the delay. Not sure if you've figured this out already, but in case you haven't:

so, your code is correct, insofar as it handles 4KB pages. :D

however, (unless you removed experimental code) you don't support some of the flags -- notably, the "size" flag of the page table. I personally don't use bitfields to do this but rather bitmasks, and so inspecting the raw value in the page directory entry, i saw "0xE3" -- which is Present (0x1), Read/Write (0x2), Accessed (0x20), and also Dirty (0x40) and Large(0x80). (in your structs you marked them as "padding1").

From the AMD manual:

Quote:
Dirty (D) Bit. Bit 6. This bit is only present in the lowest level of the page-translation hierarchy
...
Page Size (PS) Bit. Bit 7. This bit is present in page-directory entries and long-mode page-directory-pointer entries. When the PS bit is set in the page-directory-pointer entry (PDPE) or page-directory entry (PDE), that entry is the lowest level of the page-translation hierarchy.


So, to conclude, the firmware has used 2MB pages to map some of the address space, which might line up with why you're getting "strange" results. If you continued to try and read a page table entry (as you do), you'd read memory from page 0, which explains why seemingly none of the bit flags are set.

It kinda makes sense that UEFI would use large pages (who knows, you might find 1GB pages possibly?), because they require identity mapping the entirety of physical memory -- that'd be done a lot more efficiently with large or even huge pages.

They're marked as padding in my code because I was only intending on supporting 4K pages in my kernel for the time being. Those structs were written with my kernel in mind but since I already had them I figured I'd make use of them to more easily read the UEFI page structures. I didn't think about the fact that the UEFI might not be using 4K pages. I guess it'd just be best to support any page size.

Page 2 of 2 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/