本文介绍了C语言中的Bootloader无法编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是编写引导加载程序的新手.我已经在asm中编写了helloworld引导程序,并且我现在正在尝试用C语言编写一个.我已经用C语言编写了一个helloworld引导加载程序,但是我无法对其进行编译.

I am a newbie in writing bootloaders. I have written a helloworld bootloader in asm, andI am now trying to write one in C. I have written a helloworld bootloader in C, but I cannot compile it.

这是我的代码.我究竟做错了什么?为什么不编译?

This is my code. What am I doing wrong? Why won't it compile?

void print_char();
int main(void){
char *MSG = "Hello World!";
int i;

__asm__(
    "mov %0, %%SI;"
    :
    :"g"(MSG)
);
for(i=0;i<12;i++){
    __asm__(
        "mov %0, %%AL;"
        :
        :"g"(MSG[i])
    );
    print_char();
}

return 0;
}

void print_char(){
__asm__(
    "mov $0X0E, %AH;"
    "mov $0x00, %BH;"
    "mov $0x04, %BL;"
    "int $0x10"
);
}

推荐答案

让我在这里假设很多事情:您想在x86系统上运行引导程序,并在* nix框上设置了gcc工具链.

Let me assume a lot of things here: you want to run your bootloader on an x86 system, you have the gcc toolchain set up on a *nix box.

在编写引导加载程序时,需要考虑以下几点:

There are some points to be taken into account when writing a bootloader:

  1. VBR的510字节限制,由于分区表(如果您的系统需要一个分区),MBR的限制更小
  2. 实模式-16位寄存器和seg:off寻址
  3. 引导程序必须是平面二进制文件,必须链接后才能在物理地址7c00h运行
  4. 没有外部库"引用(不是!)

现在,如果您想让gcc输出这样的二进制文件,则需要使用一些技巧.

now if you want gcc to output such a binary, you need to play some tricks with it.

  1. gcc默认情况下会拆分出32位代码.要使gcc输出代码在实模式下运行,请在每个C文件的顶部添加__asm__(".code16gcc\n").
  2. gcc在ELF中输出已编译的对象.我们需要一个在7c00h静态链接的垃圾箱.创建具有以下内容的文件linker.ld

ENTRY(main);
SECTIONS
{    
    . = 0x7C00;    
    .text : AT(0x7C00)
    {
        _text = .;
        *(.text);
        _text_end = .;
    }
    .data :
    {
        _data = .;
        *(.bss);
        *(.bss*);
        *(.data);
        *(.rodata*);
        *(COMMON)
        _data_end = .;
    }    
    .sig : AT(0x7DFE)    
    {        
        SHORT(0xaa55);
    }    
    /DISCARD/ :
    {
        *(.note*);
        *(.iplt*);
        *(.igot*);
        *(.rel*);
        *(.comment);
        /* add any unwanted sections spewed out by your version of gcc and flags here */    
    }
}

  • bootloader.c中编写引导加载程序代码并构建引导加载程序

  • write your bootloader code in bootloader.c and build the bootloader

    $ gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -I. -o bootloader.o bootloader.c
    $ ld -static -Tlinker.ld -nostdlib --nmagic -o bootloader.elf bootloader.o
    $ objcopy -O binary bootloader.elf bootloader.bin
    

  • 由于您已经使用ASM构建了引导加载程序,所以我认为剩下的对您来说是显而易见的.

  • Since you already have built boot loaders with ASM, I guess the rest is obvious to you.

    -取自我的博客: http://dc0d32.blogspot.in/2010/06/real-mode-in-c-with-gcc-writing.html

    这篇关于C语言中的Bootloader无法编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 10-17 00:35