我已经成功制作了一个适用于 QEMU 2.0.0 Ubuntu 14.04 的最小引导扇区:
.code16
.global _start
_start:
cli
mov $msg, %si
mov $0x0e, %ah
loop:
lodsb
or %al, %al
jz halt
int $0x10
jmp loop
halt:
hlt
msg:
.asciz "hello world"
.org 510
.word 0xaa55
编译:
as -o main.o main.S
ld --oformat binary -o main.img -Ttext 0x7C00 main.o
该示例可在此存储库中找到:https://github.com/cirosantilli/x86-bare-metal-examples/tree/2b79ac21df801fbf4619d009411be6b9cd10e6e0/no-ld-script
根据:
qemu -hda main.img
它按预期在模拟器屏幕上显示 hello world
。
但是如果我尝试刻录到 USB:
sudo dd if=main.img of=/dev/sdb
然后将 USB 插入 ThinkPad T400 或 T430,按 F12,然后选择我观察到的 USB:
- 一些启动消息很快就会出现
- 然后屏幕一片空白,顶部只有一个下划线光标
我还使用 Ubuntu 14.04 镜像测试了相同的 USB,它启动良好,因此 USB 工作正常。
我应该如何更改此示例,以便它可以在硬件上启动并显示 hello world 消息?
Ubuntu 镜像和我创建的镜像有什么区别?
这个记录在哪里?
我已将 T400 上 sudo dmidecode
的输出上传至:https://gist.github.com/cirosantilli/d47d35bacc9be588009f#file-lenovo-t400
最佳答案
正如 @Jester 所提到的,我必须将 DS
归零:
@@ -4,2 +4,4 @@ _start:
cli
+ xor %ax, %ax
+ mov %ax, %ds
mov $msg, %si
请注意,不可能mov
立即到ds
:我们必须通过ax
:8086- why can't we move an immediate data into segment register?
所以问题的根源在于QEMU的初始状态和真实硬件的初始状态之间的差异。
我现在将以下 16 位初始化代码添加到我的所有引导加载程序中,以保证更干净的初始状态。正如 Michael Petch 在评论中提到的那样,并非所有这些都是强制性的。
.code16
cli
/* This sets %cs to 0. TODO Is that really needed? */
ljmp $0, $1f
1:
xor %ax, %ax
/* We must zero %ds for any data access. */
mov %ax, %ds
/* The other segments are not mandatory. TODO source */
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
/*
TODO What to move into BP and SP? https://stackoverflow.com/questions/10598802/which-value-should-be-used-for-sp-for-booting-process
Setting BP does not seem mandatory for BIOS.
*/
mov %ax, %bp
/* Automatically disables interrupts until the end of the next instruction. */
mov %ax, %ss
/* We should set SP because BIOS calls may depend on that. TODO confirm. */
mov %bp, %sp
我还发现了这个密切相关的问题:C Kernel - Works fine on VM but not actual computer?
Intel Manual Volume 3 System Programming Guide - 325384-056US September 2015 9.10.2“STARTUP.ASM 列表 "包含一个大型初始化示例。
关于assembly - 如何使用 GCC 生成一个最小的 BIOS hello world 引导扇区,使其可以在真实硬件上的 USB 内存棒上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32508919/