私はブートローダーを書くのが初めてです。 asmでhelloworldブートローダーを作成し、Cで作成しようとしています。Cでhelloworldブートローダーを作成しましたが、コンパイルできません。
これは私のコードです。何が悪いのですか?なぜコンパイルしないのですか?
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"
);
}
http://wiki.osdev.org/Rolling_Your_Own_Bootloader と、次のブートローダーセクションもご覧になることをお勧めします: http://www.brokenthorn.com/Resources/ OSDevIndex.html
自分でブートローダーを作成するための優れたチュートリアルがあります。さらに情報が必要な場合は、freenodeの#osdevチャネルに参加して、ディスカッションに参加することもできます。
ここでは多くのことを想定します。x86システムでブートローダーを実行したい場合、* nixボックスにgccツールチェーンを設定します。
ブートローダーを作成する際に考慮すべき点がいくつかあります。
ここで、gccにそのようなバイナリを出力させたい場合は、それを使っていくつかのトリックを実行する必要があります。
__asm__(".code16gcc\n")
を追加します。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
とブートローダーをビルドします
$ 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を使用してブートローダーをすでに構築しているので、残りは明らかだと思います。
-私のブログから取得: http://dc0d32.blogspot.in/2010/06/real-mode-in-c-with-gcc-writing.html
ブートローダーはASMで書かれています。
Cコード(またはC++など)をコンパイルすると、コンパイラは人間が読めるコードをマシンコードに「変換」します。そのため、結果について確信が持てません。
PCが起動すると、BIOSは特定のアドレスからコードを実行します。そのコードは、直接実行可能である必要があります。
そのため、Assemblyを使用します。これは、変更されていないコードを作成するための唯一の方法であり、プロセッサによって、記述どおりに実行されます。
Cでコーディングする場合でも、ASMブートローダーをコーディングする必要があります。これは、使用するコンパイラーによって生成されたマシンコードを適切にロードするために担当します。
各コンパイラは異なるマシンコードを生成することを理解する必要があります。実行前に前処理が必要になる場合があります。
BIOSでは、マシンコードを前処理できません。 PCの起動はメモリの場所へのジャンプにすぎません。つまり、この場所にあるマシンコードは直接実行されます。
GCCを使用しているため、さまざまな「ターゲット環境」に関する情報ページを読む必要があります。あなたはおそらく-ffreestandingフラグを使いたいでしょう。また、コンパイラの醜い魔法を避けるために、-fno-stack-protectorフラグを使用する必要がありました。
次に、memsetなどが見つからないというリンカーエラーが表示されます。したがって、これらの独自のバージョンを実装してリンクする必要があります。
私は数年前にこれを試しました-オプションが変更された可能性があります。
gcc
を-ffreestanding
で実行し(リンクしないでください)、フラグ-static
、-nostdlib
でld
を使用してリンクする必要があります。