OSDev.org

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

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: [SOLVED] Paging 1-GByte Page
PostPosted: Wed Aug 18, 2021 2:24 pm 
Offline
Member
Member

Joined: Sun Aug 01, 2021 5:24 pm
Posts: 51
I don't know what is wrong since this code update isn't working, ive maybe missed something in intel docs.

Image
Image

Code:
    ; 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.

Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Wed Aug 18, 2021 2:57 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
You don't say what your problem is. But what you may have missed s that not all processors support 1GB pages.


Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Wed Aug 18, 2021 3:00 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
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.


Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Wed Aug 18, 2021 3:52 pm 
Offline
Member
Member

Joined: Sun Aug 01, 2021 5:24 pm
Posts: 51
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:
    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:
    ; 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.


Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Wed Aug 18, 2021 4:23 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
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?


Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Wed Aug 18, 2021 4:52 pm 
Offline
Member
Member

Joined: Sun Aug 01, 2021 5:24 pm
Posts: 51
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:
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:


Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Thu Aug 19, 2021 8:44 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
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


Top
 Profile  
 
 Post subject: Re: Paging 1-GByte Page
PostPosted: Thu Aug 19, 2021 11:40 am 
Offline
Member
Member

Joined: Sun Aug 01, 2021 5:24 pm
Posts: 51
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 :shock:

Code:
mov     eax, cr4
or      eax, 1 << 5
; or      eax, 1 << 17    ; PCIDE
mov     cr4, eax


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 78 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