Code: Select all
"mov eax,10" .
Here is my code
http://www.websamba.com/huanggao
Thanks
Code: Select all
"mov eax,10" .
No.raywill wrote: As soon as I turned on Paging bit in CR0 , Bochs told me "Invalid physical address" ,even if I execute a instruction likeIs this because I didn't set gdt correctly?Code: Select all
"mov eax,10" .
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
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:
.........
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
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 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.
I think I have mapped it.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?
Code: Select all
....unless I map the kernel's pagetables 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.I must map my kernel's pagetable to where it is loaded in memory?
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.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.
yup.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 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.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.
Somehow I get the idea the thread starter is sure he doesn't have this problem and that we're thereby not helping.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.
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).