System hangs when writing to address range
Re: System hangs when writing to address range
What kind of weird results are you getting?
[nx] kernel: http://github.com/zhiayang/nx
Re: System hangs when writing to address range
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?zhiayang wrote:What kind of weird results are you getting?
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.
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:
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.
so, your code is correct, insofar as it handles 4KB pages.
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:
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.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.
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.
[nx] kernel: http://github.com/zhiayang/nx
Re: System hangs when writing to address range
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.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.
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:
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.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.
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.