Page 1 of 1

Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 5:54 am
by sebihepp
Hello,

I am already in PMode (Bochs) with no Interrupts working (I implement them in LongMode).
I tried to switch to long mode and want to use 1Gbyte Identitypaging the first GByte.
Therefore I need only one Entry in PML4 and PML3. Both are 4KByte aligned, thats
sure (tested with bochs debugger). The First Entry of the PML4 is (PML3 OR 0x07).
First Entry of PML3 is set to 0x87.

I followed the tutorial in the wiki to enable Long Mode and everytime I enable paging
(last step) I got a page fault. And Bochs say: Physical Address is not available for
linear 0x0000...00. I think I made a mistake with the PML Entries, but don't know wich.
PAE and PGE of EFER is enabled,
also LMA and LME of CR4,
and PG, CD, NW, ET and PE of CR0.

My Code assumes that a binary 64bit file is loaded as first module. Then it is copied
to 0x2000000 (32MByte).

Code: Select all


global start

MULTIBOOT_FLAGS equ 0x00
MULTIBOOT_MAGIC equ 0x1BADB002
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_FLAGS + MULTIBOOT_MAGIC)

START equ 0x1000000
DEST_ADDRESS equ 0x2000000
ADDRESS_PML4 equ 0x00000000
ADDRESS_PML3 equ 0x00000000
ADDRESS_PML2 equ 0x00000000
ADDRESS_PML1 equ 0x00000000

section .text
bits 32

align 4
Multiboot_Header:
	dd MULTIBOOT_MAGIC
	dd MULTIBOOT_FLAGS
	dd MULTIBOOT_CHECKSUM

start:
	mov esp, 0x900000
	push eax
	push ebx

	mov esi, ebx
	add esi, 0x14
	lodsd
	test eax, eax
	jnz test_long_mode

	jmp end

test_long_mode:
	mov eax, 0x80000000
	CPUID
	test eax, eax
	jnz .ext_test

	jmp end

.ext_test:
	mov eax, 0x80000001
	CPUID
	test edx, 0x20000000
	jnz copy_kernel2

	jmp end

copy_kernel2:
	call copy_kernel

init_paging:

	;1 GByte Pagesize
	;Identity first Gigabyte

	;Set First entry of PML4
	mov edi, PML4
	mov eax, PML3
	or eax, 0x07
	stosd
	xor eax, eax
	stosd

	;Set First entry of PML3
	mov edi, PML3
	mov eax, 0x87
	stosd
	xor eax, eax
	stosd

init_long_mode:
	mov eax, 0xA0
	mov cr4, eax

	mov eax, PML4
	mov cr3, eax

	mov ecx, 0xC0000080
	rdmsr
	or eax, 0x100
	wrmsr

	mov eax, cr0
	or eax, 0x80000000
	mov cr0, eax

	lgdt [GDT]

	mov ax, 0x20
	mov ds, ax
	mov es, ax
	mov gs, ax
	mov fs, ax
	mov ss, ax
	mov esp, 0x900000

	jmp 0x18:DEST_ADDRESS

end:
	hlt
	jmp end

copy_kernel:
	mov esi, [esi]
	lodsd
	mov ebx, [esi]
	mov edx, ebx
	sub edx, eax
	mov esi, ebx
	mov edi, DEST_ADDRESS
	add edi, edx
	mov ebx, eax
.loop:
	mov eax, [esi]
	mov [edi], eax
	sub esi, 4
	sub edi, 4
	cmp esi, ebx
	jae .loop
	ret


section .data
bits 32

GDT:
	dw GDT_END - GDT_NULL - 1
	dd GDT_NULL

GDT_NULL:
	dd 0x00000000
	dd 0x00000000
GDT_CODE32:
	dw 0xFFFF
	dw 0x0000
	db 0x00
	db 0x9A
	db 0xCF
	db 0x00
GDT_DATA32:
	dw 0xFFFF
	dw 0x0000
	db 0x00
	db 0x92
	db 0xCF
	db 0x00
GDT_CODE64:
	dw 0xFFFF
	dw 0x0000
	db 0x00
	db 0x9A
	db 0x8F
	db 0x00
GDT_DATA64:
	dw 0xFFFF
	dw 0x0000
	db 0x00
	db 0x92
	db 0x8F
	db 0x00
GDT_END:

section .page
PML4:
	TIMES 512 dq 0x00
PML3:
	TIMES 512 dq 0x00
Does anyone see my mistake?

TIA
Sebihepp

Re: Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 6:27 am
by Combuster
Are you sure your bochs has 1G paging compiled in? Could you also post the exact error messages?

Re: Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 6:30 am
by sebihepp
Damn sorry. I didn't know that Bochs must be compiled with that option. :oops:

Re: Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 6:58 am
by sebihepp
Okay, I did it. Now I can load my kernel. But another problem has occured.
After the far jump to 0x18:0x2000000 where my kernel is I got the message:
(0).[995345737] ??? (physical address not available)
and then it continues at 0x2000001, wich results in wrong opcodes.
Instead of mov rsp, 0x900000 | mov sp, 0x0000 is executed.
the error message also occur directly after enabling paging.

Sebihepp

Re: Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 7:56 am
by xenos
I guess you already checked that your simulated machine has more than 32MB RAM installed?

Re: Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 8:50 am
by sebihepp
This I will do later in the code. But I have checked Bochs settings are at 128 MByte RAM.

Re: Long Mode 1GByte Pagesize: Page Fault in Bochs!

Posted: Thu May 21, 2009 9:23 am
by stlw
sebihepp wrote:Okay, I did it. Now I can load my kernel. But another problem has occured.
After the far jump to 0x18:0x2000000 where my kernel is I got the message:
(0).[995345737] ??? (physical address not available)
and then it continues at 0x2000001, wich results in wrong opcodes.
Instead of mov rsp, 0x900000 | mov sp, 0x0000 is executed.
the error message also occur directly after enabling paging.

Sebihepp
You could try to enable memory access tracing (trace-mem on) and see where Bochs goes and what memory reads (including page walks) and see if page tables are reasonable.
BTW, CPUID bit for 1G paging didn't work in 2.4 - so CPUID will report 1G paging in release version.
I guess you don't check for CPUID before if you talking about 1G pages in Bochs. BTW, they are not compiled in by default - may be you not trying to access them even ?

Stanislav