Linux 0.11では、main.cとmain()があることがわかります。
私が理解したのは、ターゲットコードを実行するためにオペレーティングシステムが必要です。
つまり、Linux 0.11はオペレーティングシステムなので、以前は誰が実行していましたか? DOS?
答え1
名前は単におなじみと審美的な理由で選ばれました。ユーザー空間プログラムから呼び出すことができるmain()
Cランタイムはありません。main()
これを説明するコメントもありますinit/main.c
。
void main(void) /* This really IS void, no error here. */
関数main()
は次から呼び出されますboot/head.s
。
after_page_tables:
pushl $0 # These are the parameters to main :-)
pushl $0
pushl $0
pushl $L6 # return address for main, if it decides to.
pushl $_main
jmp setup_paging
L6:
jmp L6 # main should never return here, but
# just in case, we know what happens
のアドレスがスタックmain
にプッシュされる方法と using の代わりにsetup_paging
call を使用する方法に注意してください。つまり、最後にあるアドレスがの先頭から続くことを意味します。jmp
call
ret
main()
答え2
特に、0.11時代のLinuxカーネルはハードウェアBIOSによって直接ロードされます。
デフォルトでは、BIOSはフロッピーディスクのブートセクタまたはハードディスクのマスターブートレコードを表示し、そのセクタをロードします。ハードディスクの場合、MBRは「プライマリパーティション」ブートセクタをロードします。
このロードされたブートセクタには、カーネルをメモリにロードして実行する方法を知るのに十分な情報があります。
以前の0.11ディスクでは、本質的にあるディスクにカーネルがあり、別のディスクにルートディレクトリがあるフロッピーブートソリューションでした。
Linuxがハードドライブを処理している間、起動プロセスは非常に簡単です。 Linuxカーネルをロードして起動してBIOSローダーをエミュレートできる単純なDOSプログラムである「loadlin」などのツールを作成するのは非常に簡単です。これは、DOSまたはLinuxを起動する初期形式のデュアルブート用のDOS config.sysメニューを生成します。
しかし、本質的にLinuxカーネルは「ベアメタル」からロードされ、システムを引き継ぎます。
答え3
関数はmain
C言語の特徴です。 CPU が「ここから起動」するようにコンピュータ命令に正確に変換される方法は、基本的にコンパイラ実装の詳細です。ベアメタルでは、通常、最初の起動時にハードウェアに依存して特定のメモリアドレスで実行を開始できます。 Linux の初期バージョンは .simple x86 ブートローダに依存していました。この動作はBIOSファームウェアの規則によって異なりますが、実際にはすべてのレベルにプログラムの起動方法に関する規則を含むコンピュータアーキテクチャがあります。