Page 1 of 1

Paging not working, despite memory looking fine

Posted: Wed Dec 30, 2020 9:15 pm
by j4cobgarby
I'm trying to set up virtual memory in my operating system, and have code to set up a page directory, as well as all of the pages within the first table in the directory. The problem is, after setting up these tables, as soon as I enable the paging bit in CR0, I get a triple fault on the very next instruction. I can't work out why this is though, since as far as I can tell, I have all of: CR3, the page directory which CR3 points to, and page table #0 in that page directory. (I've only set the first page table (4MB) in memory because, for now, I'm not using any more than that, my kernel begins at 1MB.)

I'll show the state of various parts of the computer at the moment that I enable paging with the paging bit in CR0.

First, the value of CR3 is: 0x1000. This is where my page directory is.

The memory at 0x1000 begins:

Code: Select all

0x00001000:    03 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00
So the first DWORD of this is: 0x02000003, which represents a page directory entry referring to a page table with physical address of 0x2000, correct? So, the memory at 0x2000 (this page table) begins:

Code: Select all

0x00002000:    03 00 00 00 03 00 00 01 03 00 00 02 03 00 00 03
...
So for example, taking the first entry in this page table (0x00000003), that page maps to frame 0, correct?

So first of all, after enabling the paging bit in this state, I use bochs's feature of viewing the page table, but when I do so, it shows a blank table, which makes me think my page table isn't loaded correctly somehow.

Does any of this look incorrect? I've been through the relevant parts of the intel developer manual in depth, and can't find anything wrong with what I've done.

Re: Paging not working, despite memory looking fine

Posted: Wed Dec 30, 2020 9:23 pm
by Octocontrabass
j4cobgarby wrote:So the first DWORD of this is: 0x02000003, which represents a page directory entry referring to a page table with physical address of 0x2000, correct?
No, it represents a page table with a physical address of 0x02000000. It looks like all of your physical addresses are shifted to the left by 12 bits.

Re: Paging not working, despite memory looking fine

Posted: Wed Dec 30, 2020 9:48 pm
by j4cobgarby
Octocontrabass wrote:
j4cobgarby wrote:So the first DWORD of this is: 0x02000003, which represents a page directory entry referring to a page table with physical address of 0x2000, correct?
No, it represents a page table with a physical address of 0x02000000. It looks like all of your physical addresses are shifted to the left by 12 bits.
Oh, that explains that then... So, the address in a page directory entry is actually (address of the page table) >> 12, then?

Re: Paging not working, despite memory looking fine

Posted: Wed Dec 30, 2020 10:02 pm
by sj95126
j4cobgarby wrote:Oh, that explains that then... So, the address in a page directory entry is actually (address of the page table) >> 12, then?
No, the address is just the actual physical address of the table, but the lower 12 bits aren't used, because a) page tables must be 4k aligned (the lower 12 bits would all be zeros), so b) those bits are used for flags.

Re: Paging not working, despite memory looking fine

Posted: Thu Dec 31, 2020 7:55 am
by billw22
So the first DWORD of this is: 0x02000003, which represents a page directory entry referring to a page table with physical address of 0x2000, correct?
No, it represents a page table with a physical address of 0x02000000. It looks like all of your physical addresses are shifted to the left by 12 bits.
I apologize for rather obvious question but where did you find the info about 12 bits?

Re: Paging not working, despite memory looking fine

Posted: Thu Dec 31, 2020 7:21 pm
by Octocontrabass
The 12-bit shift is the difference between the intended address and the actual address encoded in the page directory entry.

You can decode page tables using information from Intel's SDM, AMD's APM, or sandpile.org.

Re: Paging not working, despite memory looking fine

Posted: Fri Jan 01, 2021 8:08 pm
by linguofreak
j4cobgarby wrote:
Octocontrabass wrote:
j4cobgarby wrote:So the first DWORD of this is: 0x02000003, which represents a page directory entry referring to a page table with physical address of 0x2000, correct?
No, it represents a page table with a physical address of 0x02000000. It looks like all of your physical addresses are shifted to the left by 12 bits.
Oh, that explains that then... So, the address in a page directory entry is actually (address of the page table) >> 12, then?
You could look at it that way, but since, on x86, the width of a page (12 bits) is equal to the number of flag bits in a PTE/PDE (12 bits), it's best to view a PTE/PDE as a 32-bit address anded with 0xfffff000, then ored with the flag bits, or, equivalently, as a 32-bit address aligned to a multiple of 0x1000, then ored with the flag bits. To find the address that the PTE/PDE points to, you just and the PTE/PDE with 0xfffff000. Another equivalent statement is that the address field of a PTE/PDE is the upper 20 bits of a 32-bit address.

In principal, you could have an architecture where the width of a page was different from the number of flag bits, or where the flag bits were in the most significant bits of the paging structure entry, or some other weird thing, and on such an architecture viewing the address field of a paging structure entry as the upper bits of an address, as on x86, wouldn't work as well and your way of looking at it, as the address shifted by some number of bits, would be more natural.