如何使用笔式驱动器测试自制的引导加载程序?

时间:2016-02-17 16:34:13

标签: assembly x86 boot bootloader dd

我和朋友一直在做一个OS项目。我们正在关注此Broken Thorn tutorial。我们正在使用Kali Linux来构建我们的操作系统。目前我们正在使用 QEMU PC仿真器来测试我们的启动加载程序。

这是我们的引导加载程序文件Boot1.asm

;*********************************************
;   Boot1.asm
;       - A Simple Bootloader
;
;   Operating Systems Development Tutorial
;*********************************************

bits    16                          ; We are still in 16 bit Real Mode

org     0x7c00                      ; We are loaded by BIOS at 0x7C00

start:          jmp loader                  ; jump over OEM block

;*************************************************;
;   OEM Parameter block
;*************************************************;

; Error Fix 2 - Removing the ugly TIMES directive -------------------------------------

;;  TIMES 0Bh-$+start DB 0                  ; The OEM Parameter Block is exactally 3 bytes
                                ; from where we are loaded at. This fills in those
                                ; 3 bytes, along with 8 more. Why?

bpbOEM          db "My OS   "               ; This member must be exactally 8 bytes. It is just
                                ; the name of your OS :) Everything else remains the same.

bpbBytesPerSector:      DW 512
bpbSectorsPerCluster:   DB 1
bpbReservedSectors:     DW 1
bpbNumberOfFATs:        DB 2
bpbRootEntries:         DW 224
bpbTotalSectors:        DW 2880
bpbMedia:               DB 0xF0
bpbSectorsPerFAT:       DW 9
bpbSectorsPerTrack:     DW 18
bpbHeadsPerCylinder:    DW 2
bpbHiddenSectors:       DD 0
bpbTotalSectorsBig:     DD 0
bsDriveNumber:          DB 0
bsUnused:               DB 0
bsExtBootSignature:     DB 0x29
bsSerialNumber:         DD 0xa0a1a2a3
bsVolumeLabel:          DB "MOS FLOPPY "
bsFileSystem:           DB "FAT12   "

msg db  "Welcome to My Operating System!", 0        ; the string to print

;***************************************
;   Prints a string
;   DS=>SI: 0 terminated string
;***************************************

Print:
            lodsb                   ; load next byte from string from SI to AL
            or          al, al      ; Does AL=0?
            jz          PrintDone   ; Yep, null terminator found-bail out
            mov         ah, 0eh ; Nope-Print the character
            int         10h
            jmp         Print       ; Repeat until null terminator found
PrintDone:
            ret                 ; we are done, so return

;*************************************************;
;   Bootloader Entry Point
;*************************************************;

loader:

    xor ax, ax      ; Setup segments to insure they are 0. Remember that
    mov ds, ax      ; we have ORG 0x7c00. This means all addresses are based
    mov es, ax      ; from 0x7c00:0. Because the data segments are within the same
                ; code segment, null em.

    mov si, msg                     ; our message to print
    call    Print                       ; call our print function

    xor ax, ax                      ; clear ax
    int 0x12                        ; get the amount of KB from the BIOS

    cli                         ; Clear all Interrupts
    hlt                         ; halt the system

times 510 - ($-$$) db 0                     ; We have to be 512 bytes. Clear the rest of the bytes with 0

dw 0xAA55                           ; Boot Signiture

要编译我们的引导加载程序并使用 QEMU 进行测试,我们使用以下命令:

nasm -f bin -o Boot1.bin Boot1.asm
dd if=Boot1.bin of=floppyImage.flp bs=512 count=1
qemu-system-x86_64 floppyImage.flp

我们希望使用我们的笔式驱动器在真正的PC上测试上述代码。我们有一台旧的无用的台式电脑,一直在收集灰尘。我们该怎么做呢?我们尝试将dd命令更改为以下内容:

dd if=Boot1.bin of=/dev/sdc1 bs=512 count=1

不幸的是,这失败了。

有什么问题,我们如何解决这个问题?

1 个答案:

答案 0 :(得分:-1)

为了将来的参考,我回答了我自己的问题:

;*********************************************
;   Boot1.asm
;       - A Simple Bootloader
;
;   Operating Systems Development Tutorial
;*********************************************

bits    16                          ; We are still in 16 bit Real Mode

org     0x7c00  ; We are loaded by BIOS at 0x7C00

jmp start                       ;FAT file system boot loader should start with a valid x86 instruction.
                                ;It is Generally a JUMP instruction at offset 0x00 and acquires 3 bytes.
                                ;or a JUMP SHORT followed by a NOP.


start:          jmp loader                  ; jump over OEM block

;*************************************************;
;   OEM Parameter block
;*************************************************;

; Error Fix 2 - Removing the ugly TIMES directive -------------------------------------

;;  TIMES 0Bh-$+start DB 0                  ; The OEM Parameter Block is exactally 3 bytes
                                ; from where we are loaded at. This fills in those
                                ; 3 bytes, along with 8 more. Why?

bpbOEM          db "My OS   "               ; This member must be exactally 8 bytes. It is just
                                ; the name of your OS :) Everything else remains the same.

bpbBytesPerSector:      DW 512
bpbSectorsPerCluster:   DB 1
bpbReservedSectors:     DW 1
bpbNumberOfFATs:        DB 2
bpbRootEntries:         DW 224
bpbTotalSectors:        DW 2880
bpbMedia:               DB 0xF0
bpbSectorsPerFAT:       DW 9
bpbSectorsPerTrack:     DW 18
bpbHeadsPerCylinder:    DW 2
bpbHiddenSectors:       DD 0
bpbTotalSectorsBig:     DD 0
bsDriveNumber:          DB 0
bsUnused:               DB 0
bsExtBootSignature:     DB 0x29
bsSerialNumber:         DD 0xa0a1a2a3
bsVolumeLabel:          DB "MOS FLOPPY "
bsFileSystem:           DB "FAT12   "

msg db  "Welcome to My Operating System!", 0        ; the string to print

;***************************************
;   Prints a string
;   DS=>SI: 0 terminated string
;***************************************

Print:
            lodsb                   ; load next byte from string from SI to AL
            or          al, al      ; Does AL=0?
            jz          PrintDone   ; Yep, null terminator found-bail out
            mov         ah, 0eh ; Nope-Print the character
            int         10h
            jmp         Print       ; Repeat until null terminator found
PrintDone:
            ret                 ; we are done, so return

;*************************************************;
;   Bootloader Entry Point
;*************************************************;

loader:

    xor ax, ax      ; Setup segments to insure they are 0. Remember that
    mov ds, ax      ; we have ORG 0x7c00. This means all addresses are based
    mov es, ax      ; from 0x7c00:0. Because the data segments are within the same
                ; code segment, null em.

    mov si, msg                     ; our message to print
    call    Print                       ; call our print function

    xor ax, ax                      ; clear ax
    int 0x12                        ; get the amount of KB from the BIOS

    cli                         ; Clear all Interrupts
    hlt                         ; halt the system

times 510 - ($-$$) db 0                     ; We have to be 512 bytes. Clear the rest of the bytes with 0

dw 0xAA55                           ; Boot Signiture

以上修改过的代码使用以下dd命令解决了这个问题:

dd if=Boot1.bin of=/dev/sdb1 bs=512 count=1