Question about paging

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.
Post Reply
Avery

Question about paging

Post by Avery »

First of all, I'm loading my kernel from GRUB at 0x00100000. My entry point is some assembly which basically sets up a stack and calls main(). I've finally gotten to the point where my kernel does a few interesting things so I want to get paging working. My question is this:

Without setting up the page table for the kernel to map virtual addresses 0x00100000 -> whatever to those physical pages, how do I keep things working after enabling paging? Can I relocate the kernel's addresses on the fly (I'm guessing no here)? How do other kernel's do this? (I know, I know look at the source, but all of the kernel's I can read and understand fairly quickly either don't use paging or don't do what I want to do)
Curufir

Re:Question about paging

Post by Curufir »

As far as I know you have to set up your page tables, set up the page directory and load cr3 before enabling paging.

Curufir
PlayOS

Re:Question about paging

Post by PlayOS »

Here is the code that I came up with when I was learning paging, this was just to get into a paging environment, there is alot to be done after this however it was what I got done, I am not ready to fully implement paging in my OS so I have never taken this code further. This code will Identity Map the first 12MB of RAM, when the Kernel goes into paging mode it must be running at a physical address that has the same linear address. I hope you can understand this, I cannot explain it very well, it took me about a week to work it out and get it actually working, that was spending at least 4 hours a day on it aswell.

Anyway here it is, I hope it helps you.

Code: Select all

; ===================================================
; Initialize Paging
; ===================================================
; Page Directory Address = 0x300000
; Page Table 0           = 0x301000
; Page Table 1           = 0x302000
; Page Table 2           = 0x303000
; ===================================================

; Format Page Directory Area
   mov      ax, 0x10               ; Load the Data Segment
   mov      es, ax                  ; Load the Segment Descriptor into ES
   xor      edi, edi               ; Clear EDI
   mov      edi, 0x300000            ; Starting Offset = 4MB
   mov      eax, 0x00000002            ; Table Address = 0, Supervisor, Read/Write, Not Present
   mov      cx, 0x400               ; Store 1024 DWORDs (EAX)
   cld                           ; Force EDI to be Incremented
   rep      stosd                  ; Store the Data

; Setup the Page Directory
   mov      dword [0x300000], 0x301003   ; Store Table0 Address, Supervisor, Read/Write, Present
   mov      dword [0x300004], 0x302003   ; Store Table1 Address, Supervisor, Read/Write, Present
   mov      dword [0x300008], 0x303003   ; Store Table2 Address, Supervisor, Read/Write, Present

; Indentity Map (0MB - 12MB)
   xor      edi, edi               ; Clear EDI
   mov      edi, 0x301000            ; Table0 Absolute Address
   mov      eax, 0x00000003            ; Starting Base Address = 0, Supervisor, Read/Write, Present
   mov      cx, 0xC00               ; Store 3072 DWORDs (EAX)
   cld                           ; Force EDI to be Incremented
Map12MB:
   stosd                        ; EAX -> ES:EDI
   add      eax, 0x1000               ; Next Page Base Address
   loop   Map12MB                  ; Do Next Store

; Install the Page Directory
    mov      eax, 0x300000
    mov      cr3, eax

; Turn Paging On
    mov      eax, cr0
    or      eax, 0x80000000
    mov      cr0, eax

; Jump into Paging Environment
    jmp      Paging
Paging:
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Question about paging

Post by Pype.Clicker »

why do you pretend to have "starting offset = 4MB" while you initialise your table with 0x300000 ?
PlayOS

Re:Question about paging

Post by PlayOS »

Because memory is zero based, the first megabyte starts at 0, the 2nd at 0x100000, the 3rd at 0x200000 and the 4th at 0x300000, no pretending, just saying what I am doing.

Sorry for the confusion.
Avery

Re:Question about paging

Post by Avery »

Curufir wrote: As far as I know you have to set up your page tables, set up the page directory and load cr3 before enabling paging.

Curufir
I can set up the pagetables fine, but after enabling paging all of the addresses will be different (and therefore not work) unless I map the kernel's pagetables to where it is loaded in memory. I'm trying to avoid this because it sort of limits where I can have the kernel mapped into address spaces. There must be a way around too because Linux for example maps the kernel into the upper 2G of address space. I'm wondering how they do this.

Avery
Avery

Re:Question about paging

Post by Avery »

PlayOS wrote: Here is the code that I came up with when I was learning paging, this was just to get into a paging environment, there is alot to be done after this however it was what I got done, I am not ready to fully implement paging in my OS so I have never taken this code further. This code will Identity Map the first 12MB of RAM, when the Kernel goes into paging mode it must be running at a physical address that has the same linear address. I hope you can understand this, I cannot explain it very well, it took me about a week to work it out and get it actually working, that was spending at least 4 hours a day on it aswell.

Anyway here it is, I hope it helps you.
I completely understand what you're saying, but it's exactly what I'm trying to avoid. I don't want the kernel's pagetables to correspond to where it's loaded in physical memory (ie I want the pre-MMU addresses to be different from the post-MMU addresses). The problem is that I need my kernel to run fine both before and after enabling paging. How would I do this?

Avery
Curufir

Re:Question about paging

Post by Curufir »

Copy the kernel to it's eventual resting place in physical memory before you setup the tables probably (If you're moving it around then you should could do this as you load it in after Pmode anyway). Then setup the virtual->physical page tables and go from there. So long as the virtual addresses match what the kernel code is expecting there's no problem.

There's probably a large number of ways to do this, I'd imagine linux just links the kernel's memory references (Isn't it an elf file?) to the upper 2GB on the fly, or something similar.

Curufir
Curufir

Re:Question about paging

Post by Curufir »

Just had another thought on this, and I'm not sure it would actually work (Maybe someone else with a bit more knowledge could say).

For a really simple relocation couldn't you have a variable tucked away in memory at a predefined physical address that points to the base address of the kernel code. Then simply have all memory references, jumps, calls etc add this variable before performing the operation. I'd imagine it would slow your code down horribly because of the extra additions (And I've no idea how you'd pull it off in C), but I think in theory you might be able to get away with doing it like that if you wanted a quick hack in assembly.

Err...of course I could be overcomplicating here :-[. Is there some reason you can't use a selector with its base set to 2gb? The internal addresses of the kernel code would be using offsets, the processor first translates the selector:offset into a linear address which then gets sent to the paging unit. So you'd end up using addresses offset to 2gb which your page tables would translate to physical addresses and everything would (Unless I'm completely wrong...and I'm not confident I'm not :)) keep working just fine after you switch the selectors. So you'd set up directories, page tables, cr3, turn on paging, do a far jump to your new cs:eip, load the new selectors, and carry on running.

Curufir
PlayOS

Re:Question about paging

Post by PlayOS »

Just go and check out Tim Robinsons memory management tutorials, he addresses this and provides a simple solution.

http://www.cyberscriptorium.com/osjourn ... ic&topic=2

hope this helps.
Avery

Re:Question about paging

Post by Avery »

PlayOS wrote: Just go and check out Tim Robinsons memory management tutorials, he addresses this and provides a simple solution.

http://www.cyberscriptorium.com/osjourn ... ic&topic=2

hope this helps.
Thanks. That's exactly what I was looking for. Now, hopefully I'll be able to implement it correctly.

Avery
Post Reply