从汇编语言引导加载程序检查软盘是不是可用

Posted

技术标签:

【中文标题】从汇编语言引导加载程序检查软盘是不是可用【英文标题】:Check if floppydisk is available or not from an assembly language bootloader从汇编语言引导加载程序检查软盘是否可用 【发布时间】:2016-01-16 05:54:37 【问题描述】:

我有一个关于如何使用汇编语言检查软盘驱动器是否可用的问题。我检查了 RAM 内存是否足够,但我不知道如何检查软盘驱动器是否可用。我试过这个:CMP AH,0JNE disk_error,但是当我把它放在检查内存之后,什么都没有发生。当我输入 continueToLoad:CMP AX,0JNE fatal_disk_error 时,它工作正常,但加载栏后出现错误消息。 Loader 我需要在加载栏之前显示该错误消息。 Error

main:
    MOV DS,AX 
    PUSH CS
    POP DS
    MOV AH,0x00 
    MOV AL,0x03
    INT 0x10    
    CALL ClearScreen

    MOV BL,1010b        
    MOV BP,StrLoadKernel    
    MOV CX,length   
    MOV DH,13       
    MOV DL,30           
    CALL PrintString

    MOV BL,1010b        
    MOV BP,StrReboot    
    MOV CX,length2      
    MOV DH,14       
    MOV DL,30           
    CALL PrintString

readKeys:
    CALL PressKey
    CMP AL,00011011b ; ESC binary code
    JE Reboot
    CMP AL,00001101b ; ENTER binary code
        
    CALL ClearScreen
        
    MOV BL,1010b        
    MOV BP,StrLoading   
    MOV CX,length4      
    MOV DH,14       
    MOV DL,35           
    CALL PrintString    
      
    JE LoadKernel
    loop readKeys

    jmp $

LoadKernel:
    ;CHECK IF RAM MEMORY > 64MB
    MOV AH,0x88
    INT 0x15            
    CLC  
    CMP AX,0xFA00  
    MOV BL,0011b                         
    JNC printLoader
     CALL ClearScreen 
        MOV BL,1100b        
        MOV BP,StrErrorRAM  
        MOV CX,length3      
        MOV DH,13       
        MOV DL,25               
        CALL PrintString  
        
        MOV BL,1100b        
        MOV BP,press_key    
        MOV CX,length6      
        MOV DH,14       
        MOV DL,25                  
        CALL PrintString
        
        CALL PressKey
        CALL Reboot     
      JMP readKeys 
    JMP printLoader 

changeToBlue: 
MOV BL,1001b    

JMP printLoader

changeToGreen:
MOV BL,1010b    
    
JMP printLoader

changeToRed:
MOV BL,0100b    
    
JMP printLoader

continueToLoad: 
        MOV AX,0
        MOV DL,0
        INT 0x13         
        
    ;load kernel
        MOV AX,kernel 
        MOV ES,AX
        MOV BX,0        
        
        MOV AH,02h 
        MOV AL,01h 
        MOV CH,0h  
        MOV CL,02  
        MOV DH,0   
        MOV DL,0   
        INT 0x13   
           
        CMP AH, 0                     
        jne fatal_disk_error

jmp kernel:0

RET

CALL printLoader

printLoader:   
        MOV BP,symbol       ; stringul care dorim sa il afisam
        MOV CX,symbolLength ; marimea stringului
        MOV DH,16       ; randul (x)
        MOV DL,[count]      ; coloana (y)
        
        CALL PrintString
        
        INC DL
        INC DL
        INC DL
        MOV [count],DL
        
        CALL wait2sec
        
        MOV AL,[pas]
        INC AL
        MOV [pas],AL

        CMP AL,3
        JE changeToBlue
    
        CMP AL,6
        JE changeToGreen

        CMP AL,9
        JE changeToRed 
                
        CMP AL,10
        JE continueToLoad

    loop printLoader

ClearScreen:
    MOV AX,0600h 
    MOV CX,0000h
    MOV BH,0Ah
    MOV DX,1850h
    int 0x10    
RET

PressKey:
    ;read a key
    MOV AH,0
    INT 0x16
RET

PrintString:
    MOV AH, 0x13
    MOV AL,0
    MOV BH,0    
    INT 0x10
    ; hide cursor
    mov AH,0x01
    MOV CX,2607h
    INT 0x10
RET

Reboot:
    db 0x0ea
    dw 0x0000
    dw 0xffff
RET

wait2sec:
    MOV AH,0x86
    MOV CX,0008h
    MOV DX,6480h
    int 0x15
RET

fatal_disk_error:
    CALL ClearScreen 
    MOV AX,0  
    MOV ES,AX 
    
    MOV BL,1100b        
    MOV BP,disk_error   
    MOV CX,length5      
    MOV DH,16       
    MOV DL,30
    call PrintString
    CALL wait2sec
    CALL PressKey
    CMP AL,00011011b ; ESC binary code
    jmp Reboot
RET

StrLoadKernel: db "Press ENTER to load the KERNEL "
length equ $-StrLoadKernel

StrReboot: db "Press ESC to restart "
length2 equ $-StrReboot
                                                        
StrErrorRAM: db "Loading cancelled! ERROR : RAM < 64mb."
length3 equ $-StrErrorRAM    

StrLoading: db "Loading... "
length4 equ $-StrLoading  

disk_error: db "Floppy error! Press any key... "
length5 equ $-disk_error   

press_key: db "Press any key to restart!" 
length6 equ $-press_key

kernel equ 1000h

symbol: db 219 
symbolLength equ $-symbol

count db 25

pas  db 0

 510-($-$$) db 0

DW 0xAA55

【问题讨论】:

wiki.osdev.org/CMOS#Register_0x10 我认为您可以检查端口以了解驱动器 IIRC 的可用性。 我如何检查 IIRC?一些链接? 嗨,cad。我尝试了 cmp AH,0 JNE fatal_disk_error,但我需要在加载栏之前出现该消息错误。 你不能只移动一行来做到这一点。您不能仅通过剪切和粘贴代码来使用汇编语言进行编程。您将不得不学习如何实际使用汇编语言进行编程。很遗憾,我们无法为您提供帮助。 【参考方案1】:

您不需要知道是否存在软盘驱动器。

您只需要知道设备 0(或者可能是 Bios 告诉您从中引导的设备)是否像软盘驱动器那样运行;如果设备碰巧是(例如)USB 闪存或模拟软盘驱动器的 CD/DVD,那很好。为此,请使用int 0x13, ah = 0x08, Get Drive Parameters 并检查结果。

如果您确实需要知道是否存在软盘驱动器;那么整个世界都是痛苦的。 BIOS 可能配置错误(其 CMOS 错误),可能存在 BIOS 不知道和/或什至不支持的 USB 软盘驱动器,等等。

【讨论】:

【参考方案2】:

要确定您是否有软盘驱动器,请使用 GetEquipmentStatus BIOS 功能。

int 11h

它在 AX 寄存器中返回一个值。第 6 位和第 7 位一起告诉您有多少软盘驱动器连接到系统。

00 = 1 drive
01 = 2 drives
10 = 3 drives
11 = 4 drives

仅使用位 6 和 7 如果位 0 为 ON

另一种方法是通过int 13h的BIOS函数01h查看是否可以成功获取软驱的状态。

mov dl, 0
mov ah, 01h
int 13h
cmp ah, 0
jne disk_error

请查阅 DiskControllerStatusBits 的完整列表,因为仅仅cmp ah, 0 可能会被证明有点简单。

【讨论】:

【参考方案3】:

除了@user3144770 提到的GetEquipmentStatus BIOS 功能外,您还可以使用另一个BIOS 功能GetDiskType

mov dl, 0
mov ah, 15h
int 13h

如果设置了进位标志,则会出现错误。 (AH中的状态) 如果进位标志被清除,您将在 AH 中获得一个值,该值通知您在 DL 参数中指定的驱动器。

AH=0 no drive
AH=1 floppy without change-line support
AH=2 floppy with change-line support
AH=3 hard disk

【讨论】:

以上是关于从汇编语言引导加载程序检查软盘是不是可用的主要内容,如果未能解决你的问题,请参考以下文章

将引导加载程序和内核制作成iso? [关闭]

如何以编程方式创建可引导 CD?

如何制作可引导的iso(不是cd或flash驱动器)来测试自己的引导加载程序?

如何检查 Twitter 引导程序是不是已加载?

第六课 突破512字节的限制 上

引导程序未以刀片语言加载