LongMode - Strange Jump address after Paging Initialization

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ciaala
Posts: 2
Joined: Sat Apr 18, 2009 9:44 am

LongMode - Strange Jump address after Paging Initialization

Post by ciaala »

Hi,
I'm Francesco from italy.
I'm trying to activate the long mode and reach longmode c code.
QEmu has a strange behaviour and I guess, I miss something.

1) I have included the source code of the boot entry point (multiboot grub2)
2) qemu-monitor: dumps of the cpu registers.
3) qemu-monitor: dump of the "page frames" i guess.
4) objdump disassemble

Code: Select all

// Virtual Address of the Kernel Base
#define kernel_VMA_BASE (0xffffc0000000)
// Linear Address of the Kernel Base
#define kernel_LMA_BASE (0x100000)

#define CR4_PAE 	0x0020
#define CR4_PSE 	0x0010
#define EFER_LME 	0x0100
#define MSR_EFER	0xc0000080
// paging
#define CR0_PG		0x80000000
// protected environment
#define CR0_PE		0x00000001

Code: Select all

_entry:
	/** disable the interrupts */
	/** setup the 32bit stack with 32bit physical address*/
	movl $entry_stack, %esp
	pushl $0
	pushl $0
	movl %esp, %ebp
	/** save the bootloader information stored in eax e ebx */
	movl %ebx, %esi
	movl %eax, %edi
	/** prepare the call to console_reset */
	movl %esp, %ebp
	movl $0xb8000, %eax
	movl %eax, base
	call console_reset
	/** print a welcome message */
	s_print(s_OS_VERSION)
	s_println(s_COMPILE_TIME)

pae:
	movl %cr4, %eax
	orl $(CR4_PAE| CR4_PSE), %eax
	movl %eax, %cr4
	s_print(s_PAE)

efer_lme:
	cli
	movl $MSR_EFER, %ecx
	rdmsr
	//Attenzione orl usa %eax come destinazione.
	orl $EFER_LME, %eax
	wrmsr
	s_print(s_EFER_LME)


	/** setup page table in cr3 the page table is at the 32bit address, we copied only 32bit address of the page table. we will need a 64bit page table */
prepare_paging:
	/** prepare the page table */
	call mm_setup_identity_map
	s_print(s_IDENTITYMAP)

	movl mm_main_paging_table, %eax
	movl %eax, %cr3

	/** activate paging */
activate_paging:
	movl %cr0, %eax
	orl $(CR0_PG | CR0_PE ), %eax
	movl %eax, %cr0
/**
 * Flush the instruction prefetch with the shortest jump ever.
 */
	jmp prepare_longmode_jump

[color=#0000FF]/**
 * We are in compatibility mode
 * We need to do a jump to switch to long mode
 * The jump should use a Code Segment marked as a 64bit code segment
 */[/color]
prepare_longmode_jump:
	movl $gdt64,%eax
	lgdt (%eax)
	movl $farjump64bit, %eax
	ljmp *(%eax)

/**
 * First bytes of 64bit code
 * we are in long mode,
 * we prepare the jump to the C kernel entry point
 */
.code64
prepare_main_jump:
	movabsq main64, %rax
	jmpq *%rax

farjump64bit:
	.long prepare_main_jump
	.word 0x8
.globl gdt64
gdt64:
	.word gdt64_table_end - gdt64_table_start 
	.long gdt64_table_start
	.long 0x0
	
.align 64
gdt64_table_start:
	.quad 0x0 // null descriptor
	.quad 0x00af9a000000ffff
	.quad 0x00cf92000000ffff
gdt64_table_end:
The Emulator switch to an Execution address that i cannot understand.
Breakpoint 1, 0x00000000001000a8 in activate_paging ()
(gdb) si
0x00000000001000ab in activate_paging ()
(gdb) si
0x00000000001000b0 in activate_paging ()
(gdb) si
Cannot access memory at address 0x1000a8
(gdb) si
0x000000000000e05b in ?? ()
(gdb)
0x00000000001000b0 in activate_paging () wrote: (qemu) info registers
info registers
EAX=e0000011 EBX=0022300c ECX=0010eff8 EDX=0000005d
ESI=0022300c EDI=2badb002 EBP=00109072 ESP=00109072
EIP=001000b0 EFL=00200086 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 00008340 00000027
IDT= 00000000 000003ff
CR0=60000011 CR2=00000000 CR3=0010b007 CR4=00000030
Cannot access memory at address 0x1000a8 wrote: EAX=e0000011 EBX=0022300c ECX=0010eff8 EDX=0000005d
ESI=0022300c EDI=2badb002 EBP=00109072 ESP=00109072
EIP=001000b3 EFL=00200086 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 0000000000008340 00000027
IDT= 0000000000000000 000003ff
CR0=e0000011 CR2=0000000000000000 CR3=000000000010b007 CR4=00000030

(qemu) info mem
info mem
00000000-00001000 00001000 urw
00002000-00003000 00001000 urw
00004000-00005000 00001000 urw
00006000-00007000 00001000 urw
....
003f8000-003f9000 00001000 urw
003fa000-003fb000 00001000 urw
003fc000-003fd000 00001000 urw
003fe000-003ff000 00001000 urw
0x000000000000e05b in ?? () wrote: EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000623
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000e05b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =f000 000f0000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 0000ffff
IDT= 00000000 0000ffff
CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
000000000010008e <prepare_paging>:
10008e: e8 5a 0c 02 00 callq 120ced <mm_setup_identity_map>
100093: a1 e4 09 12 00 89 04 mov 0xe8240489001209e4,%eax
10009a: 24 e8
10009c: 70 00 jo 10009e <prepare_paging+0x10>
10009e: 02 00 add (%rax),%al
1000a0: a1 00 a0 10 00 0f 22 mov 0xfd8220f0010a000,%eax
1000a7: d8 0f

00000000001000a8 <activate_paging>:
1000a8: 0f 20 c0 mov %cr0,%rax
1000ab: 0d 01 00 00 80 or $0x80000001,%eax
1000b0: 0f 22 c0 mov %rax,%cr0
1000b3: eb 00 jmp 1000b5 <prepare_longmode_jump>

00000000001000b5 <prepare_longmode_jump>:
1000b5: b8 00 10 10 00 mov $0x101000,%eax
1000ba: 0f 01 10 lgdt (%rax)
1000bd: b8 d2 00 10 00 mov $0x1000d2,%eax
1000c2: ff 28 ljmpq *(%rax)

00000000001000c4 <prepare_main_jump>:
1000c4: 48 a1 c8 1d 12 c0 ff mov 0xffffc0121dc8,%rax
1000cb: ff 00 00
1000ce: ff e0 jmpq *%rax
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: LongMode - Strange Jump address after Paging Initialization

Post by Combuster »

Your paging tables are off. There is no mapping for the page at 0x00000000 00100000, so it runs into nothingness when you enable the paging bit, causing an exception and a changed address.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
ciaala
Posts: 2
Joined: Sat Apr 18, 2009 9:44 am

Re: LongMode - Strange Jump address after Paging Initialization

Post by ciaala »

Thanks for the replay Combuster,
QEmu-monitor gives me a dump of the page frames i have created.
I have setup a page frame of 2MB size but the tool dumps them as a 4KB pages, and if i try to setup the 1GB page frame it replays that 4MB Page table are up.
I think qemu-monitor thinks about the page frames as they were for 32bit.
I set 512 page frames from 0 to 1GB in 64bit mode, 2MB Page frame size.
If they are misinterpreted as 4KB they will have holes between.
As soon i will home i will prepare a memory dump of the tables I create, and i will also try to move the kernel in one of such strange 4kb page frame.
(qemu) info mem
info mem
00000000-00001000 00001000 urw
00002000-00003000 00001000 urw
00004000-00005000 00001000 urw
00006000-00007000 00001000 urw
....
003f8000-003f9000 00001000 urw
003fa000-003fb000 00001000 urw
003fc000-003fd000 00001000 urw
003fe000-003ff000 00001000 urw
Post Reply