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:
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