Error occur as soon as paging bit set

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
raywill

Error occur as soon as paging bit set

Post by raywill »

As soon as I turned on Paging bit in CR0 , Bochs told me "Invalid physical address" ,even if I execute a instruction like

Code: Select all

"mov eax,10" .
Is this because I didn't set gdt correctly?

Here is my code
http://www.websamba.com/huanggao

Thanks
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Error occur as soon as paging bit set

Post by Candy »

raywill wrote: As soon as I turned on Paging bit in CR0 , Bochs told me "Invalid physical address" ,even if I execute a instruction like

Code: Select all

"mov eax,10" .
Is this because I didn't set gdt correctly?
No.

It gives a paging error, since you get it after turning on paging. Paging errors could be anything in the paging setup at any point. It's pretty unlikely that it's your GDT that's causing trouble.

Did you identity-map the region you're in? Did you set up all paging stuff? Did you enable any specific feature thingy (PAE, global paging etc)?
raywill

Re:Error occur as soon as paging bit set

Post by raywill »

Candy wrote: Did you identity-map the region you're in? Did you set up all paging stuff? Did you enable any specific feature thingy (PAE, global paging etc)?
   

Code: Select all

%define _PAGE_OFFSET    0xC0000000      ;3G
   %define LOAD_BASE         0x90000            ;phy_addr where 


I want to map 0x90000(LOAD_BASE) to 0xC0000000(PAGE_OFFSET).
Here is how I set up page directory and page table.

Code: Select all

enable_paging:

   mov   dword [_page_directory+(_PAGE_OFFSET>>22)*4],_kernel_page_table+LOAD_BASE+7   

   mov eax,7+LOAD_BASE
   mov ebx,0
fill_page_table:   
   mov   dword [_kernel_page_table+ebx*4+0],   eax
   add eax,0x1000
   inc ebx
   cmp ebx,20
   jnz fill_page_table

   mov eax,_page_directory + LOAD_BASE
   mov   cr3,eax

reset_gdt:
   lgdt   [gdt_addr]   ;load GDT.Now will use kernel gdt.

   mov   eax,cr0
   or   eax,1<<31
   mov   cr0,eax
;*******************************************************************************
;***************Program dies here!!!!!!!!!!!!!!*********************************
;*******************************************************************************
   mov eax,1123

   jmp gdt_code_addr:reset_data_seg
reset_data_seg:
.........
here is the GDT:

Code: Select all

gdt:
 gdt_null:
   dd   0
   dd   0
 gdt_data_addr   equ $-gdt
 gdt_data:
    dw   0xffff
   dw   0x00
   db   0x00
   db   10010010b   ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,2:data seg,read and write.
   db   11001111b   ;(7)limit len,0:1 byte,1:4K,(6)B bit,control stack,B=1,use esp,B=0,use sp,(5-4) reserved,(3-0)seg limit 19-16.
   db   0xC0 ;(=1100 0000)
 gdt_code_addr   equ $-gdt
 gdt_code:
    dw   0xffff
   dw   0x00
   db   0x00
   db   10011010b   ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,10:code seg,execute and read.
   db   11001111b
   db   0xC0

gdt_end:
 gdt_addr:
    dw   gdt_end - gdt - 1   ;gdt total length,here it contains 3 item
   dd   gdt+LOAD_BASE      ;gdt start address
No specific feature things turned on.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Error occur as soon as paging bit set

Post by Candy »

raywill wrote:
Candy wrote: Did you identity-map the region you're in? Did you set up all paging stuff? Did you enable any specific feature thingy (PAE, global paging etc)?
???

Code: Select all

%define _PAGE_OFFSET ???0xC0000000??????;3G
???%define LOAD_BASE?????????0x90000????????????;phy_addr where 


I want to map 0x90000(LOAD_BASE) to 0xC0000000(PAGE_OFFSET).
Here is how I set up page directory and page table.
If you set up paging without identity-mapping the pages you're in the very next instruction will not be mapped. That causes an error. Even if you never intend to keep the mapping, you MUST (in 99% of all cases, and if you're the remaining 1% you should know as well as me or better than I do what to do) identity-map the pages that contain the paging-enable code. Where is this code executing and what is the mapping for that code?
raywill

Re:Error occur as soon as paging bit set

Post by raywill »

Candy wrote: you MUST (in 99% of all cases, and if you're the remaining 1% you should know as well as me or better than I do what to do) identity-map the pages that contain the paging-enable code. Where is this code executing and what is the mapping for that code?
I think I have mapped it.
ebx=20 ,so 20*4K bytes are mapped.The total size of the kernel image is 39K.
raywill

Re:Error occur as soon as paging bit set

Post by raywill »

This is something I seached from this forum just now.

Code: Select all

....unless I map the kernel's pagetables to where it is loaded in memory....
Is this true?
I must map my kernel's pagetable to where it is loaded in memory?
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:Error occur as soon as paging bit set

Post by Pype.Clicker »

well, let's put things differently: when enabling pmode, you're pretty free to do things before you jump to your new descriptor because the CPU is still using the old "realmode" descriptor until the segment is reloaded.

In contrast, enabling paging takes effect immediately. Even if you write your code so that it works fine before paging is enabled aswell as after paging is enabled, you cannot prevent eip from requesting instruction that are located in the "prior-paging" location unless a jump is taken.
I must map my kernel's pagetable to where it is loaded in memory?
You mean "having virtual address XXX mapping to physical address XXX if your pagetable is on physical address XXX" ? no, there's nothing that enforce you doing that.

Technically speaking, you could even not map your pagetables anywhere, but that wouldn't be convenient if you ever need to modify them.
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:Error occur as soon as paging bit set

Post by kataklinger »

Well, actually you do have to map 1:1 virtual memory to physical at very short period of time between you set PG flag in CR3 and the time oyu reload CS and DS registers.

If your kernel is at 0x100000 physical address and mapped to 0xc0000000 address, it means that your CS has base equals to 0x40100000. When you enable paging MMU unit first adds logical addres to segment base and then do virtual to physical translation. It means that paging unit will get address equal to physical address (until you reload CS) so you must map your kernel 1:1 ar first time

[tt]
add segment base CPU MMU unit(paging)
logical address -> linear address -> physical address
0xc0000000
+ 0x40100000
= 0x100000
mapped 1:1
= 0x100000
[/tt]
Phugoid

Re:Error occur as soon as paging bit set

Post by Phugoid »

Here is a simplified model:

By now you should know that the EIP register (which points to the next instruction) is simply a number. The interpretation of the number depends on the context: with paging disabled, it is a physical address. Otherwise, it is a virtual address.

So, right before the processor executes the instruction that sets the paging bit, EIP is a physical address. The CPU updates EIP, so that interpreted as a physical address, it would point to the next instruction. Then, it enables paging. Now, EIP is interpreted as a virtual address, but the number has not changed! In other words, it still contains the physical address of the next instruction in physical memory, but the CPU treats it as a virtual address.

One of the solutions is therefore to temporarily create a mapping for your kernel image such that the virtual addresses and the physical addresses are the same (an identity mapping). Then, it does not matter what kind of address EIP is interpreted as immediately after you set the paging bit. After doing this, the CPU can be told to jump to, say, 0xC0000000, and the temporary mapping can be removed.
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:Error occur as soon as paging bit set

Post by Pype.Clicker »

Phugoid wrote: Here is a simplified model:

By now you should know that the EIP register (which points to the next instruction) is simply a number. The interpretation of the number depends on the context: with paging disabled, it is a physical address. Otherwise, it is a virtual address.
quite true, yet a bit oversimplified. You never issue physical addresses directly. The content of EIP is always interpreted relatively to the code segment's base. In the case base is zero, well, the value is indeed a physical address.
So, right before the processor executes the instruction that sets the paging bit, EIP is a physical address. The CPU updates EIP, so that interpreted as a physical address, it would point to the next instruction. Then, it enables paging. Now, EIP is interpreted as a virtual address, but the number has not changed! In other words, it still contains the physical address of the next instruction in physical memory, but the CPU treats it as a virtual address.
yup.
One of the solutions is therefore to temporarily create a mapping for your kernel image such that the virtual addresses and the physical addresses are the same (an identity mapping). Then, it does not matter what kind of address EIP is interpreted as immediately after you set the paging bit. After doing this, the CPU can be told to jump to, say, 0xC0000000, and the temporary mapping can be removed.
yup too. the alternative would be to have a page fault handler ready that catch the "wrong page" for EIP and send you back to the new location.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Error occur as soon as paging bit set

Post by Candy »

Pype.Clicker wrote: yup too. the alternative would be to have a page fault handler ready that catch the "wrong page" for EIP and send you back to the new location.
Somehow I get the idea the thread starter is sure he doesn't have this problem and that we're thereby not helping.

Re-reading his posts confirms to me that he does have this.

In the map function, you loop through the page table to map 0x90000 to 0xC0000000. All very nice. You don't map the code you're in right now. So, the previous 5-10 posts were right, the eax instruction doesn't exist when you think it does. You (yes, I'm feeling like a network repeater) MUST identity-map the memory your code is in or you WILL crash. You are not the 1% of people who are knowledgeable enough to abuse page ends (you put the mov cr0, eax at the exact end of a page and map in the next of the code at the byte address after it - which probably doesn't work nicely on a p4 since it caches instruction lines and works ahead).
raywill

Re:Error occur as soon as paging bit set

Post by raywill »

Phugoid wrote: One of the solutions is therefore to temporarily create a mapping for your kernel image such that the virtual addresses and the physical addresses are the same (an identity mapping).

Thank you all.

Now I have understand it.
I did an identity mapping .
Everything is going OK now.
Post Reply