The problem for enabling Page
The problem for enabling Page
Now I just want to try the page feature of 80386 in Bochs-2.1, but I am very confused about that, I cannot figure out how to successfully enable page; following is my asm code, hope someone could give me some help
;I have already load the following code at 0x100000 physical
;addr, and in link command set 0xc0000000 as logic addr
;the link command included -Ttext 0xc0000000 -e _k_main
[bits 32] ; use NASM
[global start]
[extern _k_main]
sub esi,0xc0000000
lea eax,[page_dir + esi] ; physical adr of page_dir
lea ebx,[page_tab + esi] ; physical adr of page_table
mov dword [eax + 0xc], ebx ;Set page directory
add dword [eax + 0x8], 0x3
mov dword [ebx], 0x100023 ; Set page table
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
jmp 0x8:start ; in this instruction, error occur:
; physical addr not available
start:
nop
mov esp,0xffff
call _k_main ; jump to k_main() in kernel.c
hlt ; halt the cpu
[SECTION .bss]
[GLOBAL page_dir]
[GLOBAL page_tab]
page_dir:
resb 4096 ; the kernel page directory
page_tab:
resb 4096 ; __page_tab0
_
;I have already load the following code at 0x100000 physical
;addr, and in link command set 0xc0000000 as logic addr
;the link command included -Ttext 0xc0000000 -e _k_main
[bits 32] ; use NASM
[global start]
[extern _k_main]
sub esi,0xc0000000
lea eax,[page_dir + esi] ; physical adr of page_dir
lea ebx,[page_tab + esi] ; physical adr of page_table
mov dword [eax + 0xc], ebx ;Set page directory
add dword [eax + 0x8], 0x3
mov dword [ebx], 0x100023 ; Set page table
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
jmp 0x8:start ; in this instruction, error occur:
; physical addr not available
start:
nop
mov esp,0xffff
call _k_main ; jump to k_main() in kernel.c
hlt ; halt the cpu
[SECTION .bss]
[GLOBAL page_dir]
[GLOBAL page_tab]
page_dir:
resb 4096 ; the kernel page directory
page_tab:
resb 4096 ; __page_tab0
_
Re:The problem for enabling Page
Hi,
Your problem might be that you don't set the attributes for the page directory entry, for e.g.:
I think should be:
Does ESI contain a sane value on entry?
Both page_dir and page_tab are in the .bss section - is the .bss section filled full of zero's before you use it?
Also, are page_dir and page_tab aligned? They have to start on an address that is a multiple of 0x1000, and NASM's binary output format doesn't align the .bss to anything in particular (not sure about other output formats).
Cheers,
Brendan
Your problem might be that you don't set the attributes for the page directory entry, for e.g.:
Code: Select all
mov dword [eax + 0xc], ebx ;Set page directory
add dword [eax + 0x8], 0x3
Code: Select all
mov dword [eax + 0xc], ebx ;Set page directory
add dword [eax + 0xc], 0x3
Both page_dir and page_tab are in the .bss section - is the .bss section filled full of zero's before you use it?
Also, are page_dir and page_tab aligned? They have to start on an address that is a multiple of 0x1000, and NASM's binary output format doesn't align the .bss to anything in particular (not sure about other output formats).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:The problem for enabling Page
Thank you, i will try again, and i will tell the result as soon as possible
Re:The problem for enabling Page
I did check my code again, found that ESI is surely set 0x100000, and the page_dir is at 0x101000,page_table is at 0x102000, it seemed to be no problem, but i still cannot enable page. FAINT!!!
Re:The problem for enabling Page
Hi,
Cheers,
Brendan
Probably the easiest way to find your problem is to run it under Bochs debugger and put a endless loop just before paging is enabled. Then (with Bochs debugger) check to see if CR3, the page directory and the page table are all completely correct before paging is enabled.chen17981 wrote: I did check my code again, found that ESI is surely set 0x100000, and the page_dir is at 0x101000,page_table is at 0x102000, it seemed to be no problem, but i still cannot enable page. FAINT!!!
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:The problem for enabling Page
Thank you, Brendan.
Due to your suggestion, i found some clue to resolve my problem. But I still have some confusion.
Following is my code in NASM
****my bootloader ******
;do some initialization like setting the GDT,load my kernel to
;0x100000 physical addr
...............
jmp CODESEL:FLUSH ; set cs to CODESEL
[bits 32]
FLUSH:
;refresh all segment registers
mov eax,DATASEL
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax
mov esp,0xffff
;Initaile page
mov dword [ 0x9b000 + 0xc00 ], 0x9c003 ; set page dir,due
mov dword [ 0x9c000 ], 0x100003 ; to my kernel at
; logic addr
;0xc000,0000
; physical addr is
; 0x10,0000
mov eax, 0x9b000 ; so page dir is
mov cr3,eax ; at 0x9b000
mov eax,cr0 ; page table is
or eax,0x80000000 ; at 0x9c000
mov cr0,eax
jmp CODESEL:0xc0000000 ; Cannot jmp to
; 0xc0000000
hlt
TIMES 510-($-$$) DB 0
DW 0xAA55
***** my kernel at 0xc000,0000 *****
[bit 32]
start:
nop
***************************
But if i add following code in bootloader just before mov eax, 0x9b000
***** add code ****
mov dword [ 0x9b000 ],0x9c003 ; physical addr 0x100000
mov dword [ 0x9c000 ], 0x100003 ; is equal logic addr
and replace jmp CODESEL:0xc0000000 with
jmp CODESEL:0x100000
All is ok
And I use bochs-debug to check whether 0xc000,0000 is map to 0x10,0000 or not, the answer is YES.
So I am very confused about that. I will attach my image.
b.img is for original code
b1.img is for changed code
Hope some one could help me
Due to your suggestion, i found some clue to resolve my problem. But I still have some confusion.
Following is my code in NASM
****my bootloader ******
;do some initialization like setting the GDT,load my kernel to
;0x100000 physical addr
...............
jmp CODESEL:FLUSH ; set cs to CODESEL
[bits 32]
FLUSH:
;refresh all segment registers
mov eax,DATASEL
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax
mov esp,0xffff
;Initaile page
mov dword [ 0x9b000 + 0xc00 ], 0x9c003 ; set page dir,due
mov dword [ 0x9c000 ], 0x100003 ; to my kernel at
; logic addr
;0xc000,0000
; physical addr is
; 0x10,0000
mov eax, 0x9b000 ; so page dir is
mov cr3,eax ; at 0x9b000
mov eax,cr0 ; page table is
or eax,0x80000000 ; at 0x9c000
mov cr0,eax
jmp CODESEL:0xc0000000 ; Cannot jmp to
; 0xc0000000
hlt
TIMES 510-($-$$) DB 0
DW 0xAA55
***** my kernel at 0xc000,0000 *****
[bit 32]
start:
nop
***************************
But if i add following code in bootloader just before mov eax, 0x9b000
***** add code ****
mov dword [ 0x9b000 ],0x9c003 ; physical addr 0x100000
mov dword [ 0x9c000 ], 0x100003 ; is equal logic addr
and replace jmp CODESEL:0xc0000000 with
jmp CODESEL:0x100000
All is ok
And I use bochs-debug to check whether 0xc000,0000 is map to 0x10,0000 or not, the answer is YES.
So I am very confused about that. I will attach my image.
b.img is for original code
b1.img is for changed code
Hope some one could help me
Re:The problem for enabling Page
>>mov dword [ 0x9b000 ],0x9c003 ; physical addr 0x100000
>>mov dword [ 0x9c000 ], 0x100003 ; is equal logic addr
-> You need to set this Page Entry in your code as EIP is in this page when you enable paging.
and replace jmp CODESEL:0xc0000000 with
jmp CODESEL:0x100000
-> You should now be able to jump to 0xc0000000
hope this helps
pkd.
>>mov dword [ 0x9c000 ], 0x100003 ; is equal logic addr
-> You need to set this Page Entry in your code as EIP is in this page when you enable paging.
and replace jmp CODESEL:0xc0000000 with
jmp CODESEL:0x100000
-> You should now be able to jump to 0xc0000000
hope this helps
pkd.
Re:The problem for enabling Page
Thank you, pkd. Surely, I did not set the page entry in my code as EIP is in the page.Following is my corrected code.
;Initaile page
mov dword [ 0x9b000 ], 0x9c003
mov dword [ 0x9b000 + 0xc00 ], 0x9d003 ;0xc0000000 map
dword [ 0x9d000 ], 0x100003 ; to 0x100000
mov dword [ 0x9c000 + 0x1c ], 0x7003 ;make the logic addr
; same as EIP
mov eax, 0x9b000
mov cr3,eax
mov eax,cr0
or eax,0x80000000
mov cr0,eax
nop ;This instruction is to verify Page
;Enable
jmp 0xc0000000 ; Jump to my kernel
******* all is ok *******
But I have another question, if I use
jmp CODESEL:0xc0000000
replace jmp 0xc0000000
an error will open, I cannot jump to my kernel, I don't know why.
Hope someone could help me.
Thanks in advance.
;Initaile page
mov dword [ 0x9b000 ], 0x9c003
mov dword [ 0x9b000 + 0xc00 ], 0x9d003 ;0xc0000000 map
dword [ 0x9d000 ], 0x100003 ; to 0x100000
mov dword [ 0x9c000 + 0x1c ], 0x7003 ;make the logic addr
; same as EIP
mov eax, 0x9b000
mov cr3,eax
mov eax,cr0
or eax,0x80000000
mov cr0,eax
nop ;This instruction is to verify Page
;Enable
jmp 0xc0000000 ; Jump to my kernel
******* all is ok *******
But I have another question, if I use
jmp CODESEL:0xc0000000
replace jmp 0xc0000000
an error will open, I cannot jump to my kernel, I don't know why.
Hope someone could help me.
Thanks in advance.
Re:The problem for enabling Page
Hi,
If you don't change to a protected mode code segment, the CS remains setup for real mode (operands and addressing as default), so when you try "jmp 0xc0000000" the CPU refuses because 0xc0000000 is above the 64 Kb limit, and if it did work the CPU wouldn't be expecting 32 bit code, which would cause more problems.
In general when you switch to protected mode you should reload ALL segment registers (or at least before you use them for anything). For e.g.:
Cheers,
Brendan
When you first enable protected mode the CPU is still using the old (real mode) values for CS (ie. the old base and limit). By using "jmp CODESEL:0xc0000000" you start using a protected mode code segment, which would tell the CPU to expect 32 bit operands and addressing as default and allow access to offsets above 64 Kb.chen17981 wrote: mov eax,cr0
or eax,0x80000000
mov cr0,eax
jmp CODESEL:0xc0000000
replace jmp 0xc0000000
If you don't change to a protected mode code segment, the CS remains setup for real mode (operands and addressing as default), so when you try "jmp 0xc0000000" the CPU refuses because 0xc0000000 is above the 64 Kb limit, and if it did work the CPU wouldn't be expecting 32 bit code, which would cause more problems.
In general when you switch to protected mode you should reload ALL segment registers (or at least before you use them for anything). For e.g.:
Code: Select all
mov bx,DATASEL
cli
mov eax,cr0
or eax,0x80000000
mov cr0,eax
mov ds,bx
mov es,bx
mov fs,bx
mov gs,bx
mov ss,bx
mov esp,32BIT_STACK_TOP
jmp CODESEL:0xc0000000
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:The problem for enabling Page
Hi, Brendan, thank you first. But I think you misunderstand me.
In my situation, when I use
*** page has been enabled, and i am in PMode ****
jmp CODESEL:0xc0000000 ; Jump to my kernel
an error occur, and I cannot jump to my kernel.
But when I use
jmp 0xc000,0000
all is ok, and I can jump to my kernel.
So I am very confused about that. In my opinion the instruction jmp CODESEL:0xc000,0000 should be able to work.
Besides, after I enabled page, if I use jmp CODESEL:addr, I always get an error.
who knows why?
In my situation, when I use
*** page has been enabled, and i am in PMode ****
jmp CODESEL:0xc0000000 ; Jump to my kernel
an error occur, and I cannot jump to my kernel.
But when I use
jmp 0xc000,0000
all is ok, and I can jump to my kernel.
So I am very confused about that. In my opinion the instruction jmp CODESEL:0xc000,0000 should be able to work.
Besides, after I enabled page, if I use jmp CODESEL:addr, I always get an error.
who knows why?
Re:The problem for enabling Page
Hi,
Cheers,
Brendan
Sorry - too many late nights ::).chen17981 wrote: Hi, Brendan, thank you first. But I think you misunderstand me.
So really CS would have been using CODESEL before paging was enabled, so "jmp CODESEL:addr" shouldn't have any effect? In this case perhaps something has happened to the GDT since CODESEL was used last?chen17981 wrote: But when I use
jmp 0xc0000000
all is ok, and I can jump to my kernel.
So I am very confused about that. In my opinion the instruction jmp CODESEL:0xc0000000 should be able to work.
Besides, after I enabled page, if I use jmp CODESEL:addr, I always get an error.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:The problem for enabling Page
Hi Brendan, it is sure that CS has been using CODESEL before paging was enabled.
So I want to know what has happened to the GDT since CODESEL was used last and why this would happen while I did not do anything to GDT.In this case perhaps something has happened to the GDT since CODESEL was used last?
Re:The problem for enabling Page
Hi,
It wouldn't be too hard to add this code:
through your code to see where the GDT gets messed up.
The "not identity mapped" possibility would make the GDT unusable after paging is enabled even though the physical memory that it's stored in hasn't changed..
Cheers,
Brendan
The GDT is in linear memory, so it's possible that it's not identity mapped when paging is setup. Otherwise it could have been accidentally overwritten with something.chen17981 wrote: So I want to know what has happened to the GDT since CODESEL was used last and why this would happen while I did not do anything to GDT.
It wouldn't be too hard to add this code:
Code: Select all
jmp CODESEL:.here
.here:
The "not identity mapped" possibility would make the GDT unusable after paging is enabled even though the physical memory that it's stored in hasn't changed..
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:The problem for enabling Page
Hi, Brendan, you are right. The jmp CODESEL:ADDR could not be used, because I did not map the physical addr where the GDT was located.
In my opinion, the memory management in 80386 is segment and page combined. Now when GDT is not useable, the page mechanism still could work, it is so weird.
In my opinion, the memory management in 80386 is segment and page combined. Now when GDT is not useable, the page mechanism still could work, it is so weird.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:The problem for enabling Page
indeed, the paging stuff can still work (and thus if you had a NOP before the jump, it would not hang on the NOP), but as soon as you need to lookup the GDT, it'll fail ...