启用Long Mode导致Bootloader启动循环及GDT基址异常问题
保护模式转长模式时GDT基址无效、CR寄存器加载异常问题
保护模式代码可正常运行,但添加长模式设置后,GDT基址被分配为无效值,CR寄存器加载异常,设备陷入启动循环。尝试硬编码GDT描述符的正确地址,问题依旧。
项目详情
- 使用x86_64汇编
- 在QEMU中运行
- 二级Bootloader从扇区2加载
代码
BITS 16 org 0x7E00 cli jmp pm_setup ; Protected mode setup gdt_start: dq 0x0000000000000000 ; Null descriptor dq 0x00CF9A000000FFFF ; Code segment dq 0x00CF92000000FFFF ; Data segment dq 0x00AF9A000000FFFF gdt_end: gdt_descriptor: dw gdt_end - gdt_start - 1 ; Size dd gdt_start ; Base pm_setup: lgdt [gdt_descriptor] mov eax, cr0 or eax, 1 ; Change PE (Protection Enable) bit if 0 mov cr0, eax jmp 0x08:protected_mode [BITS 32] ; Registers are 16-bit and map to 32-bit addresses through GDT table protected_mode: mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ; Long mode setup jmp lm_setup align 4096 pml4_table: dq pdpt_table + 0x03 align 4096 pdpt_table: dq pd_table + 0x03 align 4096 pd_table: lm_setup: mov edi, pd_table ; Destination pointer xor eax, eax mov ecx, 8192 ; Entry count for 16gb .fill_loop: mov ebx, eax ; Current physical address or ebx, 0x83 ; Present + Writable + PS mov [edi], ebx add edi, 8 ; Next entry add eax, 0x200000 ; Next 2 MB page address loop .fill_loop mov eax, cr4 or eax, 1 << 5 ; Enables physical address extension (PAE) mov cr4, eax mov ecx, 0xC0000080 ; EFER MSR address rdmsr ; Read MSR into edx:eax or eax, 1 << 8 ; Set bit 8 wrmsr ; Write back mov eax, pml4_table mov cr3, eax mov eax, cr0 or eax, 1 << 31 ; Set paging bit (bit 31) mov cr0, eax jmp 0x18:long_mode [BITS 64] long_mode: mov rax, 0xB8000 mov word [rax], 0x0F4C ; white “L” on black screen jmp $
QEMU调试信息
CPU#0 EAX=000f4a0a EBX=06feb120 ECX=0000fc4e EDX=00000000 ESI=000d91f2 EDI=06ff0312 EBP=00014e40 ESP=00006f48 EIP=000e7aa4 EFL=00000016 [----AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] 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= 000f61e0 00000037 IDT= 000f621e 00000000 CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400 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=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000 XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000 XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000 XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
内容的提问来源于stack exchange,提问作者Adi Mehmedičević
相关产品推荐
相关产品推荐

