Hi, I'm having problems with the startup code for my toy kernel for amd64 that switches from 32bit mode to 64bit mode and I'm at a loss how to debug this. The code used to work last year (with qemu-kvm 0.14.0) but fails now with QEMU emulator version 1.1.0 (Debian 1.1.0+dfsg-1).
Has something been changed in the boot environment for the multiboot? When I start qemu I get the following: % qemu -s -m 64 -kernel loader -initrd "../../kernel/moose arg=arg" Could not open option rom 'kvmvapic.bin': No such file or directory Trying to execute code outside RAM or ROM at 0x001000c1 EAX=80000013 EBX=0010fc90 ECX=c0000080 EDX=00000000 ESI=00009500 EDI=00107000 EBP=0010b000 ESP=0010afb4 EIP=001000c1 EFL=00000002 [-------] 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= 00100dc8 00000028 IDT= 00000000 000003ff CR0=80000013 CR2=00000000 CR3=00101000 CR4=00000020 DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 DR6=ffff0ff0 DR7=00000400 CCS=00000000 CCD=00000000 CCO=SARL EFER=0000000000000000 FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80 FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000 XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000 XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000 XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000 zsh: abort qemu -s -m 64 -kernel loader -initrd "../../kernel/moose arg=arg" 0x001000c1 is the next instruction after the "movl %eax, %cr0" instruction that enables protected mode and paging. So how do I debug this? Can I tell qemu to go into monitor mode instead of quiting? Or can someone spot the problem from the source? MfG Goswin -- ---------------------------------------------------------------------- #define ASM 1 #include <multiboot.h> .text .globl start, _start .code32 start: _start: jmp multiboot_entry /* Align 32 bits boundary. */ .align 4 /* Multiboot header. */ multiboot_header: /* magic */ .long MULTIBOOT_HEADER_MAGIC /* flags */ .long MULTIBOOT_HEADER_FLAGS /* checksum */ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) #ifndef __ELF__ /* header_addr */ .long multiboot_header /* load_addr */ .long _start /* load_end_addr */ .long _edata /* bss_end_addr */ .long _end /* entry_addr */ .long multiboot_entry #endif /* ! __ELF__ */ multiboot_entry: /* Initialize the stack pointer. */ movl $(stack + STACK_SIZE), %esp /* Reset EFLAGS. */ pushl $0 popf /* Push the pointer to the Multiboot information structure. */ pushl %ebx /* Push the magic value. */ pushl %eax /* Enable PAE */ movl %cr4, %eax btsl $5, %eax movl %eax, %cr4 /* * Build early 4G boot pagetable */ /* Initialize Page tables to 0 */ leal pgtable, %edi xorl %eax, %eax movl $((4096*6)/4), %ecx rep stosl /* Build Level 4 */ leal pgtable + 0, %edi leal 0x1007 (%edi), %eax movl %eax, 0(%edi) /* Build Level 3 */ leal pgtable + 0x1000, %edi leal 0x1007(%edi), %eax movl $4, %ecx 1: movl %eax, 0x00(%edi) addl $0x00001000, %eax addl $8, %edi decl %ecx jnz 1b /* Build Level 2 */ leal pgtable + 0x2000, %edi movl $0x00000183, %eax movl $2048, %ecx 1: movl %eax, 0(%edi) addl $0x00200000, %eax addl $8, %edi decl %ecx jnz 1b /* Load gdt */ lgdt gdt /* Load Level 4 page table (page 128) */ leal pgtable, %eax movl %eax, %cr3 /* Enable long mode */ movl $0xc0000080, %ecx rdmsr btsl $8, %eax wrmsr /* enable paging to activate long mode */ movl %cr0, %eax btsl $1, %eax /* protected mode */ btsl $31, %eax /* paging */ movl %eax, %cr0 /* jump to 64bit mode */ pushl $0x8 movl $startup_64, %eax pushl %eax lret .code64 startup_64: _startup_64: loop4: // Dummy code that just twirls the first char on the screen addq $0x1,0xb8000 jmp loop4 /* Our stack area. */ .comm stack, STACK_SIZE .data gdt: .word gdt_end - gdt_base .long gdt_base .long 0 idt: .word idt_end - idt_base .long idt_base .long 0 .balign 8 .globl gdt_base gdt_base: .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x00af9a000000ffff /* __KERNEL_CS */ .quad 0x00cf92000000ffff /* __KERNEL_DS */ .quad 0x0080890000000000 /* TS descriptor */ .quad 0x0000000000000000 /* TS continued */ gdt_end: .balign 8 idt_base: .quad 0x0000000000000000 .quad 0x0000000000000000 idt_end: /* * Space for page tables (not in .bss so not zeroed) */ .bss .balign 4096 pgtable: .fill 6*4096, 1, 0