You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 23:27:45