web-dev-qa-db-ja.com

カーネルにはmain()関数がありますか?

デバイスドライバーとカーネルプログラミングを学んでいます。 Jonathan Corbetの本によると、デバイスドライバーにはmain()関数はありません。

だから私は2つの質問:

  • デバイスドライバーにmain()関数が必要ないのはなぜですか?
  • カーネル自体にmain()関数がありますか?

誰かがこれを私に説明できますか?

52
someone

ユーザー空間プログラムでは、main()はプログラムへのエントリポイントです。つまり、バイナリが実行されたときに libc初期化コードによって呼び出されます です。 libc自体がメモリの割り当て、I/O、プロセス管理などをカーネルのsyscallインターフェースに依存しているため、カーネルコードにはlibcに依存する余裕はありません。

とは言っても、カーネルコードでのmain()start_kernel()であり、これは ブートローダーによって呼び出されます カーネルイメージをロードしてメモリに解凍した後、重要なハードウェアとメモリのページングをセットアップします。 start_kernel()は、システムセットアップの大部分を実行し、最終的にinitプロセスを生成します。

Linuxカーネルモジュールへのエントリポイントは、module_init()マクロを呼び出すことによってカーネルに登録されるinit関数です。登録されたモジュール初期化関数は、カーネルの起動時にdo_initcalls()関数を介して カーネルコードによって呼び出されます になります。

82
Thomas Nyman

カーネルにはmain関数がありません。 mainはC言語の概念です。カーネルはCおよびアセンブリで記述されています。カーネルのエントリコードはアセンブリによって記述されます。

起動シーケンスは次のように構成されています。

  1. BIOSは通常、ブートローダーをブートブロックデバイスからロードします。現在人気のあるブートローダーはgrubです。
  2. GrubはカーネルイメージをRAMにロードします。初期ルートデバイス(initrd)で可能です。次に、あるアドレスのコードが実行されます。
  3. カーネルイメージには、ファイルシステムモジュール、デバイスドライバーなど、いくつかのカーネルモジュールがあります。カーネルイメージはファイルシステムモジュールを使用してルートファイルシステムをマウントします。これで、カーネルはすべてのカーネルモジュールをディスクからロードして実行できます。
  4. カーネルは初期化タスクを実行します。たとえば、PCIバスを経由してすべてのPCIデバイスを見つけ、すべてのデバイスドライバーを初期化します。
  5. 最後に、カーネルはプロセス0とプロセス1(initプロセス)を作成し、CPUのコンテキストをリング0からリング3に切り替え、initプロセス(プロセスIDは1)を開始します。これでカーネルブートが完了しました。
  6. initプログラムは、すべてのinitスクリプトを実行します。すべてのサービスが開始されます。シェルが呼び出されます。ユーザーはログインできます。

main関数はC関数です。実は主な方法はCプログラムの入り口ではありません。 Cランタイムはmainの前に多くの関数を呼び出します。 GCCには拡張機能(コンストラクター)があります。 「コンストラクタ」と宣言された関数は、mainの前に呼び出されます。

例えば:

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 

このマクロはqemuプロジェクトからのものです。

17
Edward Shen

たとえば、 Arch/x86/boot/main.c のmain()関数は、システムをリアルモードからプロテクトモードに切り替える準備をしますが、他のアーキテクチャにはそのようなコードはありません。ニース 概要 x86プラットフォームでのLinuxカーネル2.6.xのブートがどのように機能するかを示します。それは本当に読む価値があります。

ドキュメント HOWTO Linuxカーネル開発を行う によると、Linuxカーネルは

標準Cライブラリに依存しない独立したC環境。C標準の一部はサポートされていません。

c標準によると、BTWはそれを意味します

自立環境のプログラムが「メイン」関数を定義する必要があるかどうかは、実装定義です。

9
dsmsk80