Page 1 of 1
Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 4:14 am
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
Is this because I didn't set gdt correctly?
Here is my code
http://www.websamba.com/huanggao
Thanks
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 4:29 am
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
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)?
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 4:55 am
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.
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 5:40 am
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?
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 6:30 am
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.
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 7:33 am
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?
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 8:08 am
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.
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 4:24 pm
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]
Re:Error occur as soon as paging bit set
Posted: Tue Jan 24, 2006 8:13 pm
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.
Re:Error occur as soon as paging bit set
Posted: Wed Jan 25, 2006 2:44 am
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.
Re:Error occur as soon as paging bit set
Posted: Wed Jan 25, 2006 3:23 am
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).
Re:Error occur as soon as paging bit set
Posted: Fri Jan 27, 2006 1:38 am
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.