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.
Rukog
Member
Posts: 51 Joined: Sun Aug 01, 2021 5:24 pm
Post
by Rukog » Wed Aug 18, 2021 2:24 pm
I don't know what is wrong since this code update isn't working, ive maybe missed something in intel docs.
Code: Select all
; Setup paging
;{
; Linear-Address Translation to a 1-GByte Page using 4-Level Paging
;{
; Format of a Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page
;{
%define PG_FLAG_P(bit) (bit << 0) ; 0: Page not Present 1: Page Present
%define PG_FLAG_RW(bit) (bit << 1) ; 0: Read-only 1: Read Write
%define PG_FLAG_US(bit) (bit << 2) ; 0: Supervisor Mode 1: User Mode
%define PG_FLAG_PWT(bit) (bit << 3) ; 0: Page-level write-through 1: Page-level write-through
%define PG_FLAG_PCD(bit) (bit << 4) ; 0: Page-level cache disable 1: Page-level cache disable
%define PG_FLAG_A(bit) (bit << 5) ; 0: Accessed 1: Accessed
%define PG_FLAG_D(bit) (bit << 6) ; 0: Dirty 1: Dirty
%define PG_FLAG_PS(bit) (bit << 7) ; 0: Refer a Page Directory 1: Refer a 1-GByte Page
%define PG_FLAG_G(bit) (bit << 8) ; 0: Global 1: Global
%define PG_FLAG_PAT(bit) (bit << 12) ; 0: Paging and Memory Typing 1: Paging and Memory Typing
mov eax, PG_FLAG_P(1) + PG_FLAG_RW(1) + PG_FLAG_US(0) + PG_FLAG_A(1) + PG_FLAG_D(1)+ PG_FLAG_PS(1)
mov [PagingTable.PML4], dword PagingTable.PDPT
or [PagingTable.PML4], eax
; Build the Page-Directory-Pointer Table
mov ecx, 4 ; 4 GB
mov edi, PagingTable.PDPT
.SetNextEntry:
;{
mov [edi], eax ; Set page entry
add eax, 0x4000_0000 ; Next 1-GB page
add edi, 8 ; Next PDPT entry
loop .SetNextEntry
;}
;}
;}
;}
Last edited by
Rukog on Thu Aug 19, 2021 11:48 am, edited 2 times in total.
iansjack
Member
Posts: 4703 Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK
Post
by iansjack » Wed Aug 18, 2021 2:57 pm
You don't say what your problem is. But what you may have missed s that not all processors support 1GB pages.
Octocontrabass
Member
Posts: 5567 Joined: Mon Mar 25, 2013 7:01 pm
Post
by Octocontrabass » Wed Aug 18, 2021 3:00 pm
You're setting the page size bit in your PML4E, not your PDPTEs. The page size bit is not valid in a PML4E.
You're not setting the present bit or the page size bit in your PDPTEs. You need both of those to get 1GB pages. You probably want to set a few other bits too.
The behavior of large pages that cross effective memory type boundaries is undefined. Before using large pages, you must read the MTRRs and verify that the effective memory type will be the same across the entire page. (See Intel SDM 3A 11.11.9 for details.)
And, of course, you have to make sure your CPU supports 1GB pages.
Rukog
Member
Posts: 51 Joined: Sun Aug 01, 2021 5:24 pm
Post
by Rukog » Wed Aug 18, 2021 3:52 pm
The original code reset the CPU constantly, so I think my CPU does support the 1 GB Page, it does looping with that code.
Code: Select all
Yes:
mov eax, 0x80000001
cpuid
mov eax, edx
or eax, 1 << 26
cmp edx, eax
je Yes
And you are right about the PS thus here's an update of the code.
Code: Select all
; Setup paging
;{
; Paging Structures in the Different Paging Modes
; Linear-Address Translation to a 1-GByte Page using 4-Level Paging
;{
; Format of a PML4 Entry (PML4E) that References a Page-Directory-Pointer Table
;{
%define PG_FLAG_P(bit) (bit << 0) ; 0: Page not Present 1: Page Present
%define PG_FLAG_RW(bit) (bit << 1) ; 0: Read-only 1: Read Write
%define PG_FLAG_US(bit) (bit << 2) ; 0: Supervisor Mode 1: User Mode
%define PG_FLAG_PWT(bit) (bit << 3) ; 0: Page-level write-through 1: Page-level write-through
%define PG_FLAG_PCD(bit) (bit << 4) ; 0: Page-level cache disable 1: Page-level cache disable
%define PG_FLAG_A(bit) (bit << 5) ; 0: Accessed 1: Accessed
%define PG_FLAG_PS(bit) (bit << 7) ; Reserved (must be 0)
mov eax, PG_FLAG_P(1) + PG_FLAG_RW(1) + PG_FLAG_US(0) + PG_FLAG_A(1) + PG_FLAG_PS(0)
; Build the PML4 Table
mov [PagingTable.PML4], dword PagingTable.PDPT
or [PagingTable.PML4], eax
;}
; Format of a Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page
;{
%define PG_FLAG_P(bit) (bit << 0) ; 0: Page not Present 1: Page Present
%define PG_FLAG_RW(bit) (bit << 1) ; 0: Read-only 1: Read Write
%define PG_FLAG_US(bit) (bit << 2) ; 0: Supervisor Mode 1: User Mode
%define PG_FLAG_PWT(bit) (bit << 3) ; 0: Page-level write-through 1: Page-level write-through
%define PG_FLAG_PCD(bit) (bit << 4) ; 0: Page-level cache disable 1: Page-level cache disable
%define PG_FLAG_A(bit) (bit << 5) ; 0: Accessed 1: Accessed
%define PG_FLAG_D(bit) (bit << 6) ; 0: Dirty 1: Dirty
%define PG_FLAG_PS(bit) (bit << 7) ; 0: Refer a Page Directory 1: Refer a 1-GByte Page
%define PG_FLAG_G(bit) (bit << 8) ; 0: Global 1: Global
%define PG_FLAG_PAT(bit) (bit << 12) ; 0: Paging and Memory Typing 1: Paging and Memory Typing
mov eax, PG_FLAG_P(1) + PG_FLAG_RW(1) + PG_FLAG_US(0) + PG_FLAG_A(1) + PG_FLAG_D(1)+ PG_FLAG_PS(1)
; Build the Page-Directory-Pointer-Table
mov ecx, 4 ; 512 entries max
mov edi, PagingTable.PDPT
.SetNextEntry:
;{
mov [edi], eax ; Set new PDPT Entry
add eax, 0x4000_0000 ; Next 1-GB page
add edi, 8 ; Next PDPT Entry
loop .SetNextEntry
;}
;}
;}
;}
And Qemu does boot this but not my real machine.
Octocontrabass
Member
Posts: 5567 Joined: Mon Mar 25, 2013 7:01 pm
Post
by Octocontrabass » Wed Aug 18, 2021 4:23 pm
It's hard to say what else could be wrong, especially when it only fails on hardware.
You made sure the rest of your PML4 and PDPT is cleared to zero, right?
Rukog
Member
Posts: 51 Joined: Sun Aug 01, 2021 5:24 pm
Post
by Rukog » Wed Aug 18, 2021 4:52 pm
Octocontrabass wrote: It's hard to say what else could be wrong, especially when it only fails on hardware.
You made sure the rest of your PML4 and PDPT is cleared to zero, right?
Yep, I am using the same paging table of my previous 4 KB pages mapping.
Code: Select all
PagingTable: ; 512 address of 64-bit
;{
.PML5: times 512 dq 0 ; Page Map Level 5
.PML4: times 512 dq 0 ; Page Map Level 4
.PDPT: times 512 dq 0 ; Page Directory Pointer Table
.PD: times 512 dq 0 ; Page Directory
.PT: times 512 dq 0 ; Page Table
;}
EndPagingTable:
nexos
Member
Posts: 1081 Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos
Post
by nexos » Thu Aug 19, 2021 8:44 am
Are you trying to use 5 level paging? It looks that way as, you have a PML5 in your code. 5 level paging hasn't been released by Intel yet
. It only works on QEMU.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects:
NexNix |
libnex |
nnpkg
Rukog
Member
Posts: 51 Joined: Sun Aug 01, 2021 5:24 pm
Post
by Rukog » Thu Aug 19, 2021 11:40 am
nexos wrote: Are you trying to use 5 level paging? It looks that way as, you have a PML5 in your code. 5 level paging hasn't been released by Intel yet
. It only works on QEMU.
I found the bug and it was the enable of PCIDE in cr4 that caused problem.
I thought I needed that flag for the 1 GB page mapping
Code: Select all
mov eax, cr4
or eax, 1 << 5
; or eax, 1 << 17 ; PCIDE
mov cr4, eax