X86 Bootloader在Thinkpad T400真机启动时出现磁盘读取错误0x0880
真机(Thinkpad T400)启动X86 Bootloader时出现0x0880磁盘读取错误
我开发X86 Bootloader已有一段时间,已验证其可在Bochs、QEMU及VMware中正常运行,但在Thinkpad T400真机上启动时出现错误码为0x0880的磁盘读取错误。
[bits 16] [extern kernel] [global isr_stub_table] [global IDT_load] [extern FortressLoader_IdtInit] [extern FortressLoader_ChecmMemMap] [extern X86TTY_Init] [extern X86TTY_Clear] [extern printf] [global FortressLoader_HeapStart] [global FortressLoader_HeapEnd] [global startKernel] section .boot global boot KERNEL_SIZE_SECTORS equ 128 jmp boot TIMES 3-($-$$) DB 0x90 OEMname: db "mkfs.fat" bytesPerSector: dw 512 sectPerCluster: db 1 reservedSectors: dw 1 numFAT: db 2 numRootDirEntries: dw 224 numSectors: dw 2880 mediaType: db 0xf0 numFATsectors: dw 9 sectorsPerTrack: dw 18 numHeads: dw 2 numHiddenSectors: dd 0 numSectorsHuge: dd 0 driveNum: db 0 reserved: db 0 signature: db 0x65 volumeID: dd 0x2d7e5a1a volumeLabel: db "NO NAME " fileSysType: db "FAT12 " boot: cld ;Clear direction flag xor ax, ax mov ds, ax mov es, ax mov ss, ax mov fs, ax mov gs, ax mov sp, 0x7c00 mov di, 0x7c00 cli mov ah, 0x41 ;Check to make sure 13h extensions mov bx, 55AAh ;CONT: are enabled by the BIOS int 0x13 ;Call the disky wisky interrupt 🥺 jc dskDrvNope ;Print no disk support msg cmp bx, 0xAA55 ;Check if 13h supported by BIOS jnz dskDrvNoExtAtALl mov bx, diskNoError ; call print mov [disk], dl mov ax, 0x2401 int 0x15 mov ax, 0x3 ;Set the VGA mode, unknown at boot int 0x10 mov ah, 42h mov dl, [disk] mov si, dap int 0x13 jc disk_err ;Jump if disk read error jmp disk_target ; dskDrvNope: mov bx, disk_no_extensions call print hlt dskDrvNoExtAtALl: mov bx, disk_no_extatall call print hlt print: pusha start: mov al, [bx] cmp al, 0 je done mov ah, 0x0e int 0x10 add bx, 1 jmp start done: popa ret print_nl: pusha mov ah, 0x0e mov al, 0x0a int 0x10 mov al, 0x0d int 0x10 popa ret print_hex: pusha mov cx, 0 hex_loop: cmp cx, 4 je end mov ax, dx and ax, 0x000f add al, 0x30 cmp al, 0x39 jle step2 add al, 7 step2: mov bx, HEX_OUT + 5 sub bx, cx mov [bx], al ror dx, 4 add cx, 1 jmp hex_loop end: mov bx, HEX_OUT call print popa ret disk_err: ;Label for any disk errors mov bx, disk_read_error ;Print the disk error call print call print_nl mov dh, ah ;Load error code in ah register call print_hex jmp $ disk: db 0x0 dap: db 0x10 db 0 dw KERNEL_SIZE_SECTORS dw 0 ; dw 0x07e0 ;value recommended by a friend dq 1 ;start second sector read HEX_OUT: db '0x0000',0 disk_read_error: db "Disk read error!", 0 disk_no_extensions: db "no disk ah=42h", 0 disk_no_extatall: db "no bios ah=42h", 0 diskNoError: db "Using bios extensions", 0 times 510 - ($-$$) db 0 dw 0xAA55 %include "./fortressloader/memory.asm" %include "./fortressloader/memmap.asm" %include "./fortressloader/multiboot.asm" GDT_START: dq 0x0 GDT_CODE: dw 0xffff dw 0x0 db 0x0 db 10011010b db 11001111b db 0x0 GDT_DATA: dw 0xFFFF dw 0x0 db 0x0 db 10010010b db 11001111b db 0x0 GDT_END: GDT_POINTER dw GDT_END - GDT_START - 1 dd GDT_START CODE_SEG equ GDT_CODE - GDT_START DATA_SEG equ GDT_DATA - GDT_START disk_target call BiosGetMemorySize64MB ;Load the memory size mov [mbInfo+mbInfo.memoryHi], bx mov [mbInfo+mbInfo.memoryLo], ax mov word [mbInfo+mbInfo.bootDevice], 0x0 mov edi, 0x2000 call BiosGetMemoryMap mov word [mbInfo+mbInfo.mmap_length], ax mov word [mbInfo+mbInfo.mmap_addr], 0x2000 cli ;Clear the interrupts lgdt [GDT_POINTER] ;Load the GDT using a gdt pointer mov eax, cr0 or eax, 0x1 mov cr0, eax jmp CODE_SEG:boot2 [bits 32] startKernel: boot2: mov ax, DATA_SEG mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov esi, loaded_msg mov ebx, 0xb8000 .loop: ;Print a message using a loop lodsb or al, al jz load_kernel ;Load kernel when msg finished or eax,0x0F00 mov word [ebx], ax add ebx,2 jmp .loop load_kernel: mov esp, kernel_stack_top ;Load the stack to call C functions call X86TTY_Init ;Initialize the TTY call X86TTY_Clear ;Clear everything on the screen call FortressLoader_IdtInit ;Initialize the IDT mov eax, 0x1BADB002 ;Multiboot magic number mov ebx, mbInfo mov ebx, 0 push eax push ebx call kernel ;Call the actual kernel halt: cli hlt loaded_msg:db "Operating system loaded",0 ;Message here to verify disk read section .bss align 4 kernel_stack_bottom: equ $ ;equ the current address for the stack resb 16384 ;Use 16kb for stack size kernel_stack_top: ;Top of the stack section .text
我原本认为错误原因是BIOS不支持int 0x13 ah=42h扩展,因为听说部分BIOS不支持该磁盘扩展,需改用CHS方法(我倾向于不使用CHS)。但添加ah=42h读取支持检查后,情况未改变,说明BIOS确实支持该扩展。
我也已排查代码在真机上不工作的常见原因并逐一修正(如确保DS为0、清除方向标志等),希望能获得一些修复该问题的建议。
内容的提问来源于stack exchange,提问作者bsdsylvia
相关产品推荐
相关产品推荐

