Cir*_*四事件 12 x86 assembly qemu gnu-assembler bare-metal
我设法生成一个与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
Run Code Online (Sandbox Code Playgroud)
编译:
as -o main.o main.S
ld --oformat binary -o main.img -Ttext 0x7C00 main.o
Run Code Online (Sandbox Code Playgroud)
这个例子可以在这个回购中找到:https://github.com/cirosantilli/x86-bare-metal-examples/tree/2b79ac21df801fbf4619d009411be6b9cd10e6e0/no-ld-script
一旦:
qemu -hda main.img
Run Code Online (Sandbox Code Playgroud)
它hello world按预期在模拟器屏幕上显示.
但是,如果我尝试刻录到USB:
sudo dd if=main.img of=/dev/sdb
Run Code Online (Sandbox Code Playgroud)
然后将USB插入ThinkPad T400或T430,点击F12,然后选择我观察到的USB:
我也用Ubuntu 14.04映像测试了相同的USB,它启动正常,因此USB工作正常.
我应该如何更改此示例,以便它将在硬件上启动并显示hello world消息?
Ubuntu图像和我创建的图像有什么区别?
这记录在哪里?
我已将sudo dmidecodeT400 的输出上传到: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
Run Code Online (Sandbox Code Playgroud)
请注意,不可能mov立即ds:我们必须通过ax:8086-为什么我们不能将立即数据移动到段寄存器中?
所以问题的根源是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
Run Code Online (Sandbox Code Playgroud)
我还发现了这个密切相关的问题:C内核 - 在VM上运行正常而不是真正的计算机吗?
在英特尔手册卷3系统编程指南- 2015年325384-056US月 9.10.2"STARTUP.ASM清单"中含有大量的初始化例子.