OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 8:18 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 19 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: System hangs when writing to address range
PostPosted: Fri Feb 15, 2019 12:08 am 
Offline
Member
Member
User avatar

Joined: Tue Dec 27, 2011 7:57 am
Posts: 368
What kind of weird results are you getting?

_________________
[nx] kernel: http://github.com/zhiayang/nx


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Fri Feb 15, 2019 7:18 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 23
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?

_________________
NekOS: https://hg.sr.ht/~scoopta/NekOS


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 17, 2019 7:03 am 
Offline
Member
Member
User avatar

Joined: Tue Dec 27, 2011 7:57 am
Posts: 368
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.

_________________
[nx] kernel: http://github.com/zhiayang/nx


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 17, 2019 6:22 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 23
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.

_________________
NekOS: https://hg.sr.ht/~scoopta/NekOS


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page Previous  1, 2

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 51 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group