OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 16, 2024 9:57 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Initializing Paging from within the kernel
PostPosted: Fri Apr 18, 2003 4:09 pm 
Can I initialize paging after my C kernel has started, and been linked at 0x100000? Or do i have to initialize it before and link it to a virtual address. Also, ive written a working physical memory allocator with the help of Tim's tutorial, what i dont understand is, once paging is enabled, how does the physical allocator work? Wont the addresses all be virtual?


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Fri Apr 18, 2003 4:29 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
It is possible to handle the paging initialization either before or within the "C" part of the kernel. However, when paging is enabled within the C kernel, it is preferable to keep the kernel region identically mapped (so that you can still use the same logical addresses for the kernel with or without paging).

If you want to load your kernel in high addresses like 0xC000.0000 .. 0xFFFF.FFFF like Linux does, it is probably easier to initialize paging before you execute the kernel - as these addresses are unlikely to be valid memory without paging...

If you see nothing wrong with having your kernel located in the low memory range (either real mode area or just starting at 1Mb), then you can just keep the same mapping.

As people might want to keep 1MB area free for the use of VM86 programs, the "kernel in low area" seems not to be in the mood.

What you could also do is
1. load your kernel in physical memory starting at 1MB.
2. have no paging at start-up, but a kernel code & data segment that have a base such as 1MB == 3GB (0xC000.0000)
3. Enable paging mapping logical linear address 0xC000.0000 -> ... to physical addresses 0x0010.0000 -> ...)
4. Reset the base of kernel code & data segment so that you have a flat-mode kernel.

From a "programming" point of view, everything remains at the same address and using the same physical memory. You just played on the 2 aspects of the MMU to keep the same translation before and after paging enabling.

Keeping cs.base!=0 is not wishable as it usually prevent the use of fast system calls, etc.

may the CR3 be with You, Use it wisely :)

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Fri Apr 18, 2003 4:36 pm 
ok i get it


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Fri Apr 18, 2003 5:05 pm 
If paging is enabled before the IDT is loaded, should it be loaded with a virtual address or a physical one?


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Sat Apr 19, 2003 5:56 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
IDTR.base should always be loaded with a physical address, as GDTR.base and CR3 ...

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Sun Apr 20, 2003 8:35 am 
Im sure it says in the intel manuals that the GDT and IDT use virtual addresses to find there locations?

Peter


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Sun Apr 20, 2003 9:07 am 
pskyboy wrote:
Im sure it says in the intel manuals that the GDT and IDT use virtual addresses to find there locations?

Peter


Nope, it's physical, plain and simple. That's why there is no selector associated with the GDT/IDT registers.

Think of it logically. If the base is a virtual address then how can you load the GDT/IDT register in pmode without a GDT already being present, there would be nowhere to lookup a selector.


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Sun Apr 20, 2003 3:03 pm 
Offline
Member
Member

Joined: Wed Oct 18, 2006 11:59 am
Posts: 1600
Location: Vienna/Austria
*where are lizards? ... ah there is one sofa lizard*

GDT/IDT registers have to be provided with PHYSICAL Adresses. Everything clear?

Prior to enabling paging, it is very wise to have idt up and running - with exception handlers installed.

_________________
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image


Top
 Profile  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Tue Apr 22, 2003 12:44 pm 
Not physical -- linear. If you use LGDT or LIDT with paging enabled, you must use a virtual address. Paging applies to LGDT and LIDT but segment base addresses don't.


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Tue Apr 22, 2003 3:35 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
Tim Robinson wrote:
Not physical -- linear. If you use LGDT or LIDT with paging enabled, you must use a virtual address. Paging applies to LGDT and LIDT but segment base addresses don't.

woow ? so if i enable paging and if i don't have identity mapping for the pages where GDT and IDT are, i must reload GDTR and IDTR in order to have the new virtual address (still referring to the same old physical address) loaded ?

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Tue Apr 22, 2003 4:24 pm 
I'm not sure on this.

This works:
  • Set up GDT and switch to protected mode
  • Enable paging
  • Reload segment registers

And so does this:
  • Enable pmode, paging, etc.
  • Set up a new GDT (e.g. replacing the old one GRUB set up)
  • Use LGDT with virtual (paged) address

This doesn't:
  • Enable pmode, paging, etc.
  • Set up a new GDT
  • Use LGDT with physical (RAM) address

I had this situation when I started enabling paging in the assembly code stub of my kernel. It surprised me at the time until I figured out that LGDT was subject to page translation. I haven't looked it up in the Intel manuals but this sounds like the correct explanation. I guess LGDT caches the 'real' (physical) base address.


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Tue Apr 22, 2003 7:05 pm 
Hmm, actually things get kinda odd once you start using paging and thinking about these instructions.

The intel manuals specificly state that GDTR/IDTR contain a linear base address and a limit.

Now without paging that's quite simple, linear = physical.

With paging enabled linear != physical though.

LGDT and LIDT also use a linear address, not logical. So they skip the selector:offset translation step.

Now with paging enabled those linear addresses get translated into physical via the page tables. So changing the page tables would screw up the GDT, which obviously doesn't happen.

Guess Tim's right and the physical address is cached in GDTR/IDTR, not the linear address.

Very confusing little area, and the manual isn't exactly transparent on the subject.

BTW, am I the only one confused by this. I always thought memory translation went:
Logical -> Linear -> Physical

So when people are using the term virtual do they mean linear?


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Wed Apr 23, 2003 12:38 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
Tim Robinson wrote:
I guess LGDT caches the 'real' (physical) base address.


I don't feel so ... the GDT can span accross several pages, and i don't remember to have seen any constraints like "all the pages of the GDT must be physically contiguous in memory", which advocates for a paging-translated access to the GDT.

There is of course a cache of the physical base address ... but in the Translation Lookaside Buffers ...

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Wed Apr 23, 2003 10:06 am 
No way Pype, I just don't buy it.

Let's say your kernel reallocates the page the GDT was contained in, changing linear->physical address calculation. Now that would break your GDT/IDT completely because it would be being translated to the wrong physical address. Then there's the simple cost of translation (Why bother with it if you don't need it?) and for selector loading you simply don't need it.

Guess the only way to know about this for sure is to get paging working properly, load a new gdt, remap the page tables and flush the TLBs. I'm just not convinced that the GDT relies on that base address translation remaining valid after loading.


Top
  
 
 Post subject: Re:Initializing Paging from within the kernel
PostPosted: Wed Apr 23, 2003 1:02 pm 
Tim Robinson wrote:
Not physical -- linear. If you use LGDT or LIDT with paging enabled, you must use a virtual address. Paging applies to LGDT and LIDT but segment base addresses don't.

That's true! I do it... I load my GDT & IDT after enbling paging with:

__asm__ __volatile__ ("lgdtl (%0)" : : "r"((dword)&gdt_ptr));

__asm__("lidtl (%0)" : : "r"((dword)&idt_ptr));

...where &gdt_ptr and &idt_ptr are virtual addresses.


Top
  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: 0xY, Bing [Bot], MichaelPetch, osdev199 and 768 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