【发布时间】:2019-09-29 22:31:52
【问题描述】:
我想从头开始做一个简单的引导加载程序。我希望它能够在最近的笔记本电脑上通过 USB 启动,这意味着它具有 UEFI 启动但理论上它支持 Legacy 启动。
所以我写了一小段汇编代码,它只打印“hello world”,然后用 nasm -f bin boot.asm -o boot.com 编译它 然后我用 dd 从二进制文件构建了软盘。 该软盘在 qemu-system-x86_64 上运行良好。我使用 dd if=boot.bin of=/dev/sda 将其传输到格式化为 FAT32 的 U 盘的 MBR。 但是当用我最近的电脑启动它时,USB 没有出现在可启动设备中。
我试图: - 在 Qemu 上成功启动它(使用 qemu-system-x86_64 -hdb /dev/sda) - 在具有英特尔奔腾 4 处理器的非常旧的计算机上启动它,一切都按预期工作。 - 在 BIOS 选项中启用传统模式 - 禁用安全启动 - 在另一台计算机上启动它,USB 棒显示在可启动设备中,但没有打印任何内容。
我在网上找到的,所以组装应该是正确的
;; A tiny, working bootloader for x86 PCs. Has a few subroutines
;; so it's slightly less useless than just printing "hello world".
;;
;; writeup here: http://joebergeron.io/posts/post_two.html
;;
;; Joe Bergeron, 2016.
;;
bits 16
mov ax, 07C0h
mov ds, ax
mov ax, 07E0h ; 07E0h = (07C00h+200h)/10h, beginning of stack segment.
mov ss, ax
mov sp, 2000h ; 8k of stack space.
call clearscreen
push 0000h
call movecursor
add sp, 2
push msg
call print
add sp, 2
cli
hlt
clearscreen:
push bp
mov bp, sp
pusha
mov ah, 07h ; tells BIOS to scroll down window
mov al, 00h ; clear entire window
mov bh, 07h ; white on black
mov cx, 00h ; specifies top left of screen as (0,0)
mov dh, 18h ; 18h = 24 rows of chars
mov dl, 4fh ; 4fh = 79 cols of chars
int 10h ; calls video interrupt
popa
mov sp, bp
pop bp
ret
movecursor:
push bp
mov bp, sp
pusha
mov dx, [bp+4] ; get the argument from the stack. |bp| = 2, |arg| = 2
mov ah, 02h ; set cursor position
mov bh, 00h ; page 0 - doesn't matter, we're not using double-buffering
int 10h
popa
mov sp, bp
pop bp
ret
print:
push bp
mov bp, sp
pusha
mov si, [bp+4] ; grab the pointer to the data
mov bh, 00h ; page number, 0 again
mov bl, 00h ; foreground color, irrelevant - in text mode
mov ah, 0Eh ; print character to TTY
.char:
mov al, [si] ; get the current char from our pointer position
add si, 1 ; keep incrementing si until we see a null char
or al, 0
je .return ; end if the string is done
int 10h ; print the character if we're not done
jmp .char ; keep looping
.return:
popa
mov sp, bp
pop bp
ret
msg: db "Oh boy do I sure love assembly!", 0
times 510-($-$$) db 0
dw 0xAA55
我希望能够在我最近的计算机上启动 USB,运行 i7-8550U 处理器和 UEFI/Legacy 兼容。 目前,USB 记忆棒并未出现在可启动设备中。
编辑: 谢谢您的回复 ! 我尝试通过添加这段代码来设置 Bios 参数块 (BPB):
ORG 0
BITS 16
jmp near start
db "MYBOOT "
dw 512
db 1
dw 1
db 2
dw 512
dw 65535
db 0xf8
dw 20
dw 63
dw 16
dd 0
dd 0
db 0x29
dd 0xffff
db 0
db 0
db "NO NAME "
db "FAT32 "
start:
blablabla (see above)
USB 棒现在出现在 ubuntu 桌面上(我注意到如果我使用“jmp near start”以外的其他东西,比如“jmp short start”,它就会消失) 但它仍然不想出现在我的 BIOS 启动菜单中。 我真的不知道为什么它现在不想看到它。 我有 F.23 版的 Bios,也许这个 bios 有什么特殊的方法可以做到这一点?
【问题讨论】:
-
并非您在 Internet 上找到的所有内容都是正确的 :) 请参阅 duplicate 如何使用 BPB 创建引导扇区。这可能会解决您的问题。
-
首先,您是将 USB 引导为软盘驱动器 (FDD) 仿真或硬盘驱动器磁盘仿真 (HDD)。您应该能够在 USB 相关启动的 BIOS 中看到此设置。我假设从您的 QEMU 命令行中您正在 LInux 上进行开发?
-
您有机会试用当前答案中的代码吗?
标签: assembly x86 qemu bootloader bios