Greetings all,
I am writting a small boot loader to enable long mode and jump to some 64 bit code.
However I've hit a problem when enabling paging, I am getting the following messages from bochs:
00119797160i[CPU0 ] compatibility mode
00119797160i[CPU0 ] CS.d_b = 32 bit
00119797160i[CPU0 ] SS.d_b = 32 bit
00119797160i[CPU0 ] EFER = 0x00000500
00119797160i[CPU0 ] | RAX=0000000080000011 RBX=0000000000000000
00119797160i[CPU0 ] | RCX=00000000c0000080 RDX=0000000000000000
00119797160i[CPU0 ] | RSP=0000000000067ed4 RBP=0000000000067ee4
00119797160i[CPU0 ] | RSI=000000000002cb3f RDI=000000000002cb40
00119797160i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00119797160i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00119797160i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00119797160i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00119797160i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf ZF af PF cf
00119797160i[CPU0 ] | SEG selector base limit G D
00119797160i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00119797160i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00119797160i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00119797160i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00119797160i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00119797160i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00119797160i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00119797160i[CPU0 ] | MSR_FS_BASE:0000000000000000
00119797160i[CPU0 ] | MSR_GS_BASE:0000000000000000
00119797160i[CPU0 ] | RIP=00000000001000b8 (00000000001000b8)
00119797160i[CPU0 ] | CR0=0x80000011 CR1=0x0 CR2=0x0000000000000080
00119797160i[CPU0 ] | CR3=0x0000000000101010 CR4=0x00000020
00119797160i[CPU0 ] (instruction unavailable) page not present
I have attached my bootloader code. I suspect the page table setup I doing in loader_pae.c is wrong, but I've tried quite a few things
HELP ! Paging problems switching to long mode
Re:HELP ! Paging problems switching to long mode
Hmm, just a moment, you are doing:
AFAICS, pae_pde is in global memory, and I assume it is correctly aligned. Then you put a pointer to pae_pde into the first entry of pae_pdp, right so far. But while you do so, you are shifting the pointer 12 bits to the left, this is wrong, The pointer will go to a completely wrong location then.
Since the pointer to the page directory is aligned on a 4kb boundary, the least significant 12 bits are zero anyway, therefore they are used to put your flags (FIELD_P, FIELD_RW) in there. I guess it's the same with the above values (which you are shifting 21 bits to the left). Just remove the shifting operations, and it *should* work.
cheers Joe
Code: Select all
...
pae_pde[3] = (uint64)(0x600000) << 21;
pae_pde[3] |= (FIELD_P | FIELD_RW | FIELD_PS);
pae_pdp[0] = (uint64)(pae_pde) << 12;
pae_pdp[0] |= (FIELD_P | FIELD_RW);
...
Since the pointer to the page directory is aligned on a 4kb boundary, the least significant 12 bits are zero anyway, therefore they are used to put your flags (FIELD_P, FIELD_RW) in there. I guess it's the same with the above values (which you are shifting 21 bits to the left). Just remove the shifting operations, and it *should* work.
cheers Joe
Re:HELP ! Paging problems switching to long mode
Thanks!, the note about alignment was the real cause of my problems. I orginally did not have the bit shifts in there.
In the end I gave up using C code. I was strugling to get the linker to have the memory as part of the kernel image and have it 4k alligned.
So just I used some ASM code and put the page tables after the end of the kernel image.
kernel_end comes from my linker script:
Now I get into compatibilty mode, little more work and I should be able to get into long mode.
In the end I gave up using C code. I was strugling to get the linker to have the memory as part of the kernel image and have it 4k alligned.
So just I used some ASM code and put the page tables after the end of the kernel image.
Code: Select all
PAE_PML4 equ (kernel_end)
PAE_PDP equ (PAE_PML4 + 0x1000)
PAE_PDE equ (PAE_PDP + 0x1000)
; setup first pml4 entry.
mov eax, dword PAE_PDP ; address of first pdp entry.
or eax, 3 ; set presnt, r/w, u/s bits
mov [PAE_PML4], eax
mov [PAE_PML4 + 4], dword 0x0
; setup first PDP entry.
mov eax, dword PAE_PDE ; address of first pde entry.
or eax, 3 ; set presnt, r/w, u/s bits
mov [PAE_PDP], eax
mov [PAE_PDP + 4], dword 0x0
; setup first PDE entry - size flag set, so maps first 2mb of memory
mov eax, dword 0x0 ; base address of PDE entry.
or eax, 131 ; set size, presnt, r/w, u/s bits
mov [PAE_PDE], eax
mov [PAE_PDE + 4], dword 0x0
; set CR3 to point to PML4 table (PT4)
mov eax, PAE_PML4 ; Pointer to PML4 table (<4GB).
mov cr3, eax ; Initialize CR3 with PML4 base.
Code: Select all
{
..... .text, .data, .bss sections go here ....
/* symbols to mark end of kernel */
kernel_end = .; _end = .;
}
Re:HELP ! Paging problems switching to long mode
Great!
I'd like to ask you something different however: Do you have any good links about OS development in long mode, besides some threads here in the forum and the MT OSFAQ? I've only seen the AMD docs so far, not much more...
cheers Joe
I'd like to ask you something different however: Do you have any good links about OS development in long mode, besides some threads here in the forum and the MT OSFAQ? I've only seen the AMD docs so far, not much more...
cheers Joe
Re:HELP ! Paging problems switching to long mode
there is a developers message board over at AMD website (cannot remember the URL atm, but search this board for a thread by brandon (i think) where he talks about skipping PMode on LMode initialization and he had a link to it there
and there is of course the Intel docs also (though they arn't much different from the info you have in the AMD docs, sometimes it helps to have multiple references, because they say it a little differently, it may give a different POV, increasing your understanding)
and there is of course the Intel docs also (though they arn't much different from the info you have in the AMD docs, sometimes it helps to have multiple references, because they say it a little differently, it may give a different POV, increasing your understanding)
Re:HELP ! Paging problems switching to long mode
Anoher document I find useful is the overview document, titled "AMD 64-Bit Technology" "The AMD x86-64 Architecture Overview" doc no. 24108C.
It gets the nitty gritty stuff about long mode & compatiabily mode without all the stuff about the older modes.
The only problem is it assumes in some places pior knowledge of Pmode, but theres pretty of non-reference material & example source code around the web to look .
I still haven't had a chance at getting into long mode proper, my aim is at least to be able to get into some 64bit C code and print "hello world!"
It gets the nitty gritty stuff about long mode & compatiabily mode without all the stuff about the older modes.
The only problem is it assumes in some places pior knowledge of Pmode, but theres pretty of non-reference material & example source code around the web to look .
I still haven't had a chance at getting into long mode proper, my aim is at least to be able to get into some 64bit C code and print "hello world!"