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.
pskyboy

Paging

Post by pskyboy »

i know have a kernel which thinks its at 3Gb and is actually at 1Mb. My question is i am now enabling paging and was wondering when i shoudl switch the GDT back so that its base is 0. The way i see it is im in a no win situation as if i don't do it before i enabel paging it seems to crash and if i do it before i enable it it will no longer be able to get access to the instructions.

Peter
Tim

Re:Paging

Post by Tim »

Definitely. Otherwise things will get very confusing very quickly.

What you should do is:
1. Map the bottom 4MB virtual to the bottom 4MB physical
2. Map C000_0000 virtual to the bottom 4MB physical
3. Make sure flat code and data descriptors exist in the GDT
4. Enable paging
5. JMP FAR flat_code_selector:some_address_in_kernel
6. Reload the data segment registers
7. Discard or re-use the based code and data descriptors
shad

Re:Paging

Post by shad »

I think its funny that you and i seem to go through the same ordeals at the same time... although i got so frustrated with that i just linked my kernel at 0x100000 and put the user stuff high up.
pskyboy

Re:Paging

Post by pskyboy »

LOL, i had my kernel working when it was linked at 0x100000 and had paging enabled but then decided i wanted my user space from 0 up so had to go through this hugh mess.

Peter
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Paging

Post by distantvoices »

hugh ... said winnetou the master of apaches ... and after mentioned something about a HUGE mess of things *ssssfffgg*

regarding to paging:

@point 5 of tims response:
After enabling Paging, you jump to an adress in PAGED adress space, say, if you have kernel linked to c0000000 virtually,y0u jump to an adress say c00023af and forget this adress correction (pointer mangling or gdt trick)?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Tim

Re:Paging

Post by Tim »

Right. You jump to a high address (e.g. C000_1234) with a descriptor whose base is 0 and limit is 4GB. After paging is enabled and the high addresses are mapped, you can forget about pointer manging and carry on as normal.

Currently I enable paging in the assembly-language startup code and leave it enabled. So the only place I have to worry about mangling is in that one assembly routine.
shad

Re:Paging

Post by shad »

Someone please tell me whats going on here, this code is linked at 0xC000_0000, and loaded at 0x100000 (its linked to the kernel as the entry point). Anyway as soon as it does that jmp.... boom. (its not using the GDT base trick, as i found it not necessary for this method).

[attachment deleted by admin]
shad

Re:Paging

Post by shad »

The error message i get in bochs is page not present but i cant find my error in the mappings..
Tim

Re:Paging

Post by Tim »

Things to check:
-- Mappings are correct at the address where you enable paging (near 0010_0000)
-- Mappings are correct around main (near C000_0000)
-- Page directory and page table addresses are page-aligned
-- PDE and PTE bits are set correctly (probably want to set these to 7)
shad

Re:Paging

Post by shad »

Do you think you could take a look at the source? I cant find whats going on and ive been stuck on this for a month.
shad

Re:Paging

Post by shad »

WAIT!!! I THINK I FOUND IT!! [eax + 768], its the 768th entry, but you have to mul that by 4 to get the correct offset!
shad

Re:Paging

Post by shad »

Just want to let everyone know i have successfully linked my kernel to 0xC000_0000. *sigh* bliss. The one thing im having alot of trouble with now that i am trying to write a vmm is the physical address of page tables..
How can u create a new table and load it in the directory with a physical address if all you are using is virtual addresses? I know Tim went over this in his tutorial i just wish the "mapping it into itself" was explained a little more.
Tim

Re:Paging

Post by Tim »

There are two ways you can use the self-mapping trick:

1. Just accept it. Copy and paste these macros and carry on:

Code: Select all

#define PAGETABLE_MAP      (0xffc00000)
#define PAGEDIRECTORY_MAP  (0xffc00000 + (PAGETABLE_MAP / (1024)))
#define ADDR_TO_PDE(v)     (addr_t*)(PAGEDIRECTORY_MAP + \
                                (((addr_t) (v) / (1024 * 1024))&(~0x3)))
#define ADDR_TO_PTE(v)     (addr_t*)(PAGETABLE_MAP + ((((addr_t) (v) / 1024))&(~0x3)))
2. Sit down with a pencil and paper, draw everything, and figure it out. It's pretty hard to explain here but if you think it through you should get it.
Whatever5k

Re:Paging

Post by Whatever5k »

This works, too. Selfmapping is not *that* hard too understand. It's a technique where you map the page directory into itself. The 1023 (last) entry of the page directory points to the page directory itself:

Code: Select all

pdir[1023] = (int) pdir | ATTR;
So it means that you the page directory and page tables are loacted in the upper 4MB of the virtual address space.

This works for getting virtual address for PDE and PTE:

Code: Select all

#define PTE_SIZE 4
#define PDE_SIZE 4

#define PG_DIR_START 0xFFFFF000 /* because of */
#define PG_TABLE_START 0xFFC00000 /* the selfmapping trick */

#define ADDR_TO_PDE(virt) (PG_DIR_START + (virt >> 22) * PDE_SIZE)
#define ADDR_TO_PTE(virt) (PG_TABLE_START + (virt >> 12) * PTE_SIZE)
Good luck!
shad

Re:Paging

Post by shad »

Yah it took me an hour and a calculator but i think im on to something...
Post Reply