Page 1 of 1

Long mode can't page above 4 GB

Posted: Sun Jun 07, 2020 7:50 pm
by Je06
I'm currently developing a C++ kernel using bochs. I managed to setup Long mode, and have a working GDT and paging. The problem I'm running into is that when I try to add anything to virtual memory above 4GB, entry 4+ in the PDP, it doesn't show up when I look at my pages. I've tried 1GB, 2MB, and 4KB pages. Nothing works.

Code: Select all

this->kb_page = 3;
this->mb_pages = 5;
this->kernel_pages = 4;

// Setup PML4, PDP, PD, and KB page tables
this->pages[0][0] = (uint64_t)this->pages[1] | 3;
this->pages[1][0] = (uint64_t)this->pages[2] | 3;
this->pages[2][0] = (uint64_t)this->pages[3] | 3;
    
// Setup Kernel map
this->pages[1][3] = (uint64_t)this->pages[this->kernel_pages] | 3;

// Kernel code/data
this->pages[this->kernel_pages][0] = this->kinfo->kernel_addr | 0x83;
this->pages[this->kernel_pages][1] = this->kinfo->kernel_addr + 0x100000 | 0x83;
    
// Kernel heap
this->pages[this->kernel_pages][2] = 0x200083;
this->pages[this->kernel_pages][3] = 0x400083;
this->pages[this->kernel_pages][4] = 0xa00083;
this->pages[this->kernel_pages][5] = 0xc00083;

// Setup heap
//for (size_t i = 0; i < 64; i++) {
//    this->pages[1][4+i] = (uint64_t)this->pages[this->mb_pages+i] | 3;
//}

this->pages[1][4] = (uint64_t)this->pages[this->mb_pages] | 3;
this->pages[1][5] = 0x83;
with the pages defined as

Code: Select all

typedef uint64_t PageEntry;
typedef PageEntry PageTable[512];
PageTable *pages;
The pages structure is 4KB aligned
And finaly

Code: Select all

set_paging(this->pages[0]);

global set_paging
set_paging:
    mov cr3, rdi
    ret

Re: Long mode can't page above 4 GB

Posted: Sun Jun 07, 2020 9:13 pm
by nullplan
My glass ball is in the wash right now, and with the info you provided I cannot be certain, since there is no link to the source code anywhere, nor enough information to make such a determination. However, I bet you cast an address to int at some point, not realizing that this is too small a type.

Re: Long mode can't page above 4 GB

Posted: Sun Jun 07, 2020 10:50 pm
by Je06
nullplan wrote:My glass ball is in the wash right now, and with the info you provided I cannot be certain, since there is no link to the source code anywhere, nor enough information to make such a determination. However, I bet you cast an address to int at some point, not realizing that this is too small a type.
I'm so sorry! I forgot to add relevant code! I have fixed that, and have added the code to the post. As you can see, I use uint64_t, so I'm using an appropriate data type

Re: Long mode can't page above 4 GB

Posted: Mon Jun 08, 2020 12:43 am
by iansjack
1. Are you sure that you are in Long Mode? Does gdb show 64-bit registers when you do "info registers"?

2. What do you mean by "it doesn't show up when I look at my pages". How are you "looking" at your pages? What does the qemu monitor show when you do "info mem"?

Re: Long mode can't page above 4 GB

Posted: Mon Jun 08, 2020 12:51 am
by Je06
iansjack wrote:1. Are you sure that you are in Long Mode? Does gdb show 64-bit registers when you do "info registers"?

2. What do you mean by "it doesn't show up when I look at my pages". How are you "looking" at your pages? What does the qemu monitor show when you do "info mem"?
As I said, I'm using bochs. Bochs tells me that I'm in Long mode and shows Long mode registers. I'm looking at my page table in the page table output provided by bochs.

Re: Long mode can't page above 4 GB

Posted: Mon Jun 08, 2020 2:09 am
by MichaelPetch
It is a limitation in BOCHS. It just doesn't show mappings above 4gb unless you patch the source. We have touched on this issue previously: viewtopic.php?f=1&t=27650

Re: Long mode can't page above 4 GB

Posted: Mon Jun 08, 2020 12:48 pm
by Je06
MichaelPetch wrote:It is a limitation in BOCHS. It just doesn't show mappings above 4gb unless you patch the source. We have touched on this issue previously: viewtopic.php?f=1&t=27650
Thanks. I guest that's my issue