我尝试使用Internet下面的示例bootloader。
__asm__(".code16gcc\n");
__asm__ ("jmpl $0, $main\n");
#define __NOINLINE __attribute__((noinline))
#define __REGPARM __attribute__ ((regparm(3)))
#define __NORETURN __attribute__((noreturn))
/* BIOS interrupts must be done with inline assembly */
void __NOINLINE __REGPARM print(const char *s){
__asm__ __volatile__("movb %0 , %%al\n" : :"c"(*s):"memory");
//__asm__ __volatile__("movb $'W' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");
}
/* and for everything else you can use C! Be it traversing the filesystem, or verifying the kernel image etc.*/
void __NORETURN main(){
__asm__ __volatile__ ("movb $0x0, %al\n");
print("woo hoo!\r\n:)");
while(1);
}
用于链接下面使用的基本链接描述文件。
ENTRY(main);
SECTIONS
{
. = 0x7C00;
.text : AT(0x7C00)
{
*(.text);
}
.sig : AT(0x7DFE)
{
SHORT(0xaa55);
}
}
我准备了一个二进制可启动映像,并使用以下命令复制到软盘。
gcc -c -Os -g -march=i686 -ffreestanding -Wall -Werror -I. test.c -o test.o
ld -m elf_i386 -static -Ttest.ld -nostdlib --nmagic -o test.elf test.o
objcopy -O binary test.elf test.bin
sudo dd if=test5.bin of=/dev/fd0
我们很容易注意到我正在尝试打印字符' w'只有,从字符串"呜呜!"传递给 print()函数。 但是当我尝试在虚拟机上启动它时,它没有打印任何内容。
但是,如果我评论 print()的第一个陈述并取消注释第二个陈述,那么字符' W'打印如下,证明编译和启动印章都很好。这是使用movb $'W' , %al
:
我为链接器脚本,gcc选项,内联汇编和真实与虚拟机尝试了我最好的搜索问题,但无法解决此问题。
也可能是我在启动加载程序中如何保存静态变量的问题,而我还没有意识到。