【问题标题】:Linking first and second stage bootloader链接第一阶段和第二阶段引导加载程序
【发布时间】:2019-08-24 12:47:42
【问题描述】:

我正在编写一个两阶段引导加载程序 这是我的 boot.asm

[org 0x7c00]
[bits 16]
xor ax, ax
mov ds, ax
mov es, ax
xor bx, bx
mov ah, 0x0E
mov al, 'A'
int 0x10
jmp 0x8000
cli
hlt
times 510 - ($-$$) db 0
dw 0xAA55

还有 boot2.asm

[org 0x8000]
[bits 16]
xor ax, ax
mov ds, ax
mov es, ax
xor bx, bx
mov ah, 0x0E
mov al, 'B'
int 0x10

我使用它编译它

nasm -f bin -o boot.bin boot.asm
nasm -f bin -o boot2.bin boot2.asm

它编译时没有任何错误或警告。 但是我将如何将 stage 2 放在 0x8000 并将 stage1 和 stage2 链接到一起工作?

【问题讨论】:

  • 根据您的代码 stage2 是 0x7e00 而不是 0x8000。您的第一阶段必须使用 Int 13/ah=2 之类的方式将第二阶段读入内存
  • 没关系,但我将如何链接它们
  • 这是一个第一阶段读取第二阶段并使用 NASM 生成 1.44MB 磁盘映像的示例:stackoverflow.com/a/54894586/3857942
  • 您是在 Windows 上进行开发吗? Linux? macOS?
  • 哦,我正在安卓手机上开发!!!您一定会感到惊讶,但这是真的,我是一个使用 termux 的安卓终端模拟器。

标签: assembly nasm x86-16 bootloader stage


【解决方案1】:

您可能会问如何将第一阶段和第二阶段合并到一个文件中。如果是这样:
开启 Linux:

cat boot.bin boot2.bin > final_file.file_format

开启 Windows:

copy /b boot.bin+boot2.bin  final_file.file_format

要从引导加载程序加载第二阶段,您可以使用以下代码:

mov ah, 0x02      ; Read disk BIOS call 
mov cl, 0x02      ; sector to start reading from
mov al, 1         ; number of sectors that will be read (modify if your second stage grows)
mov ch, 0x00      ; cylinder number
mov dh, 0x00      ; head number
xor bx, bx
mov es, bx        ; ES=0x0000
mov bx, 0x8000    ; ES:BX(0x0000:0x8000) forms complete address to read sectors to
; DL should contain the boot disk number passed to the bootloader by the BIOS
int 0x13          ; Make BIOS disk services call (Int 0x13/AH=2) to read sectors
; For simplicity assume the disk read was successful
jmp 0x0000:0x8000 ; FAR JMP to second stage and ensure CS=0x0000
                  ; since CS is not guaranteed to be 0x0000 when control is transferred
                  ; to our bootloader

【讨论】:

    【解决方案2】:

    但是我如何将阶段 2 放在 0x8000 ...

    不幸的是,我不使用“masm”,而是使用其他汇编程序。但我希望您必须将[org 0x7e00] 更改为[org 0x8000]

    ...并链接stage1和stage2一起工作?

    这并不像你想象的那么容易:

    BIOS 会将一个扇区(510 字节加上 2 字节0xAA55)加载到内存的 0x7C00。使用普通 BIOS,不可能加载更多数据!

    这 510 个字节(“阶段 1”)中的代码必须将“状态 2”加载到内存中:它可以使用函数 ah=2ah=0x42int 0x13 来这样做。

    如果你有自己的软盘格式,这很简单:

    你将“stage 2”存储在软盘的第二个扇区并加载第二个扇区。

    如果您想从文件系统(例如,从 FAT 格式磁盘中的文件)加载“阶段 2”,这就比较棘手了。

    【讨论】:

    • 没关系,但是我将如何做到这一点,例如 make.sh
    猜你喜欢
    • 2013-05-05
    • 2016-03-22
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2016-02-14
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多