OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:53 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: OSDev Wiki paging code
PostPosted: Fri May 05, 2017 11:22 pm 
Offline
Member
Member
User avatar

Joined: Sun Nov 20, 2016 7:26 am
Posts: 155
Location: Somewhere
Hello.

There's a strange thing in the Paging wiki page code in the "Manipulation" section. (http://wiki.osdev.org/Paging#Manipulation)

Quote:
The CR3 value, that is, the value containing the address of the page directory, is in physical form. Once, then, the computer is in paging mode, only recognizing those virtual addresses mapped into the paging tables, how can the tables be edited and dynamically changed?
Many prefer to map the last PDE to itself. The page directory will look like a page table to the system. To get the physical address of any virtual address in the range 0x00000000-0xFFFFF000 is then just a matter of:

Code:
void * get_physaddr(void * virtualaddr)
{
    unsigned long pdindex = (unsigned long)virtualaddr >> 22;
    unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;

    unsigned long * pd = (unsigned long *)0xFFFFF000;
    // Here you need to check whether the PD entry is present.

    unsigned long * pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
    // Here you need to check whether the PT entry is present.

    return (void *)((pt[ptindex] & ~0xFFF) + ((unsigned long)virtualaddr & 0xFFF));
}


To map a virtual address to a physical address can be done as follows:

Code:
void map_page(void * physaddr, void * virtualaddr, unsigned int flags)
{
    // Make sure that both addresses are page-aligned.

    unsigned long pdindex = (unsigned long)virtualaddr >> 22;
    unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;

    unsigned long * pd = (unsigned long *)0xFFFFF000;
    // Here you need to check whether the PD entry is present.
    // When it is not present, you need to create a new empty PT and
    // adjust the PDE accordingly.

    unsigned long * pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
    // Here you need to check whether the PT entry is present.
    // When it is, then there is already a mapping present. What do you do now?

    pt[ptindex] = ((unsigned long)physaddr) | (flags & 0xFFF) | 0x01; // Present

    // Now you need to flush the entry in the TLB
    // or you might not notice the change.
}


Unmapping an entry is essentially the same as above, but instead of assigning the pt[ptindex] a value, you set it to 0x00000000 (i.e. not present). When the entire page table is empty, you may want to remove it and mark the page directory entry 'not present'. Of course you don't need the 'flags' or 'physaddr' for unmapping.


Code:
unsigned long * pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);


Isn't that calculation wrong? I thought (0x400 * pdindex) should be (0x1000 * pdindex) because each page table is one page long in that mapping.

Also it gives wrong addresses. The last page table's address is in this calculation:
0xFFC00000 + (0x400 * 1023) = 0xFFCFFC00

Using 0x1000 instead of 0x400 gives the correct address:
0xFFC00000 + (0x1000 * 1023) = 0xFFFFF000

If it's correct, could you explain why the calculation is (0x400 * pdindex), please?

Thanks in advance.

Edit: I forgot taking care about (unsigned long*), fixed.
A really noobish mistake, maybe I should sleep more :|

_________________
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.


Last edited by Agola on Fri May 05, 2017 11:54 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: OSDev Wiki paging code
PostPosted: Fri May 05, 2017 11:47 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
https://www.tutorialspoint.com/cprogram ... hmetic.htm


Top
 Profile  
 
 Post subject: Re: OSDev Wiki paging code
PostPosted: Fri May 05, 2017 11:52 pm 
Offline
Member
Member
User avatar

Joined: Sun Nov 20, 2016 7:26 am
Posts: 155
Location: Somewhere
iansjack wrote:
https://www.tutorialspoint.com/cprogramming/c_pointer_arithmetic.htm

Code:
((unsigned long*) 0xFFC00000) + (0x400 * pdindex);


Ah, I forgot taking care about (unsigned long*) before calculating. Such a noobish mistake. Maybe I should sleep more.
Even after thinking this about 2 hours, how couldn't I see it.

That code in my os is like:
Code:
(uint32_t*) (0xFFC00000 + (0x1000 * pdindex))
Probably that's why I couldn't see it :|

_________________
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.


Top
 Profile  
 
 Post subject: Re: OSDev Wiki paging code
PostPosted: Sat May 06, 2017 12:24 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
I think it's a mistake that catches everyone out from time to time. It's certainly bitten me a few times.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 56 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