Paging
Paging
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
Peter
Re:Paging
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
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
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Paging
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)?
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
BlueillusionOS iso image
Re:Paging
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.
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.
Re:Paging
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]
[attachment deleted by admin]
Re:Paging
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.
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.
Re:Paging
There are two ways you can use the self-mapping trick:
1. Just accept it. Copy and paste these macros and carry on:
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.
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)))
Re:Paging
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:
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:
Good luck!
Code: Select all
pdir[1023] = (int) pdir | ATTR;
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)