Page 1 of 1

The problem for enabling Page

Posted: Thu Sep 16, 2004 9:34 am
by chen17981
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
   

_

Re:The problem for enabling Page

Posted: Thu Sep 16, 2004 11:11 pm
by Brendan
Hi,

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
I think should be:

Code: Select all

mov dword [eax + 0xc], ebx  ;Set page directory
add dword [eax + 0xc], 0x3
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

Re:The problem for enabling Page

Posted: Fri Sep 17, 2004 9:14 pm
by chen17981
Thank you, i will try again, and i will tell the result as soon as possible

Re:The problem for enabling Page

Posted: Sat Sep 18, 2004 8:43 am
by chen17981
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

Posted: Sun Sep 19, 2004 8:23 am
by Brendan
Hi,
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!!!
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.


Cheers,

Brendan

Re:The problem for enabling Page

Posted: Mon Sep 20, 2004 10:17 pm
by chen17981
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

Re:The problem for enabling Page

Posted: Tue Sep 21, 2004 6:13 am
by pkd
>>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.

Re:The problem for enabling Page

Posted: Tue Sep 21, 2004 10:47 pm
by chen17981
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.

Re:The problem for enabling Page

Posted: Wed Sep 22, 2004 12:57 am
by Brendan
Hi,
chen17981 wrote: mov eax,cr0
or eax,0x80000000
mov cr0,eax

jmp CODESEL:0xc0000000
replace jmp 0xc0000000
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.

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

Re:The problem for enabling Page

Posted: Wed Sep 22, 2004 3:13 am
by chen17981
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?

Re:The problem for enabling Page

Posted: Wed Sep 22, 2004 10:31 am
by Brendan
Hi,
chen17981 wrote: Hi, Brendan, thank you first. But I think you misunderstand me.
Sorry - too many late nights ::).
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.
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?


Cheers,

Brendan

Re:The problem for enabling Page

Posted: Wed Sep 22, 2004 8:21 pm
by chen17981
Hi Brendan, it is sure that CS has been using CODESEL before paging was enabled.
In this case perhaps something has happened to the GDT since CODESEL was used last?
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.

Re:The problem for enabling Page

Posted: Thu Sep 23, 2004 5:06 am
by Brendan
Hi,
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.
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.

It wouldn't be too hard to add this code:

Code: Select all

   jmp CODESEL:.here
.here:
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

Re:The problem for enabling Page

Posted: Thu Sep 23, 2004 7:53 pm
by chen17981
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.

Re:The problem for enabling Page

Posted: Fri Sep 24, 2004 5:57 am
by Pype.Clicker
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 ...