Paging not working, despite memory looking fine

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
j4cobgarby
Member
Member
Posts: 64
Joined: Fri Jan 26, 2018 11:43 am

Paging not working, despite memory looking fine

Post 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.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Paging not working, despite memory looking fine

Post 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.
j4cobgarby
Member
Member
Posts: 64
Joined: Fri Jan 26, 2018 11:43 am

Re: Paging not working, despite memory looking fine

Post 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?
sj95126
Member
Member
Posts: 151
Joined: Tue Aug 11, 2020 12:14 pm

Re: Paging not working, despite memory looking fine

Post 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.
billw22
Posts: 1
Joined: Tue Dec 22, 2020 5:21 am

Re: Paging not working, despite memory looking fine

Post 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?
You will find help with your homework at https://justdomyhomework.com/ service
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Paging not working, despite memory looking fine

Post 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.
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: Paging not working, despite memory looking fine

Post 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.
Post Reply