Page 1 of 2
Paging
Posted: Sat Apr 26, 2003 11:42 am
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
Re:Paging
Posted: Sat Apr 26, 2003 12:18 pm
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
Re:Paging
Posted: Sat Apr 26, 2003 2:04 pm
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.
Re:Paging
Posted: Sat Apr 26, 2003 2:37 pm
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
Re:Paging
Posted: Sun Apr 27, 2003 5:43 am
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)?
Re:Paging
Posted: Sun Apr 27, 2003 6:08 am
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.
Re:Paging
Posted: Sun Apr 27, 2003 8:19 am
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]
Re:Paging
Posted: Sun Apr 27, 2003 8:20 am
by shad
The error message i get in bochs is page not present but i cant find my error in the mappings..
Re:Paging
Posted: Sun Apr 27, 2003 8:24 am
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)
Re:Paging
Posted: Sun Apr 27, 2003 8:32 am
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.
Re:Paging
Posted: Sun Apr 27, 2003 8:34 am
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!
Re:Paging
Posted: Sun Apr 27, 2003 10:46 am
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.
Re:Paging
Posted: Sun Apr 27, 2003 11:17 am
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.
Re:Paging
Posted: Sun Apr 27, 2003 11:30 am
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:
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!
Re:Paging
Posted: Sun Apr 27, 2003 3:37 pm
by shad
Yah it took me an hour and a calculator but i think im on to something...