1.問題の説明
initにstart_kernelからGDBトレースデバッグカーネルを使用して、起動プロセスのMenuOSを分析しながら、今週の調査を通じて、我々はさらにLinuxカーネルのソースコードに基づいて、ディレクトリ構造Linuxカーネルのソースコードを勉強するには、簡単なオペレーティングシステムのMenuOSを構築しますプロセスが開始され、さらに、どのようにLinuxカーネルの深い理解を関数のコードをLinuxカーネルのブートを分析します。
2.解決手順
2.1 Linuxカーネルのソース記述
Linuxカーネルのソースディレクトリ構造図に示すように。
ここで重要な部分ディレクトリ
アーチ:アーチは、略語のアーキテクチャです。ディレクトリ内のサポートされている各CPUアーキテクチャ用のカーネルには、対応するサブディレクトリがあります。各CPUサブディレクトリ、更に各ブート制御システム、メモリ管理、システムコールなどを含む、ブート、MM、カーネルおよび他のサブディレクトリに分解する。
ブロック:ブロックデバイスドライバ部。
暗号:暗号化、圧縮、CRCチェックサムアルゴリズム。
ドキュメント:一部の文書カーネルを保存します。
ドライバ:Linuxカーネルでサポートされているすべてのハードウェアデバイス用のストレージドライバのソースコードを分類ドライブのディレクトリ、。
FS:様々なファイルシステムを実装するコードを格納。各サブディレクトリには、ファイルシステムを実装するために対応しています。
含まれます:必要なカーネルヘッダファイル、パブリック(一般的な様々なCPUアーキテクチャ)ヘッダのストレージを。
INIT:カーネルの初期化コード。
IPC:プロセス間通信の実装コード。
カーネル:Linuxの最も重要なコア機能は、このディレクトリに実装されています。
LIB:ライブラリのコード。
MM:メモリ管理の一部を実装するために使用されるディレクトリ内のMMファイルは、アーキテクチャとは何の関係もありません。
ネット:ネットワークプロトコルの実装コード。
サンプル:カーネルプログラミングのいくつかの例。
スクリプト:カーネル構成スクリプト。
2.2簡単なLinuxカーネルを構築
ここでは「実験的な建物」環境、Linuxカーネルのバージョンを使用することは、3.18.6実験棟環境です。次のコマンドを使用して、Linuxカーネルの構築。
cd LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
QEMUシミュレーションカーネル、イメージ、bzImageはgzipで圧縮されたファイルは、カーネルイメージに圧縮された後のvmlinuxでは、「b」は、(小さなカーネルのために大規模なカーネルのイメージ、bzImage、zImageの)「ビッグ」を表しています。ルート・ファイル・システムは、一般的にメモリのルート・ファイル・システムおよびディスク・ファイル・システムが含まれています。ここでは、ルートファイルシステムは比較的簡単ですよ、ただrootfs.imgを作成します。
2.3 GDBのトレースを使用したデバッグ
使用GDBトレースデバッグコアに加え、2つのパラメータ1は、GDB-サーバー上に作成-s(1234ポートは、別のウィンドウを開くことができ、表に従い、カーネルイメージとGDBは、GDBサーバーを接続した後でロードされ、 、)。ブレークポイント、トレースカーネルを設定し、もう一方は、-S(ちょうど初期のCPUの前にフリーズ)です。
カーネルとしての効果が起動し
、カーネルがロードされ、GDBを起動し、ウィンドウを開くための接続を確立し
、次のコマンドを使用して、
#加载符号表
file linux-3.18.6/vmlinux
#用1234这个端口进行连接
target remote:1234
それが「C」に応じて実行し続けた場合、システムはブレークポイントで停止する位置start_kernel機能を開始し、実行するために始めた、ちょうど停止状態でstart_kernelにブレークポイントを設定
し、その後ブレークポイントrest_initを設定し、継続、でオフに停止ポイントで。
カーネル関数start_kernelブートプロセスの役割の2.4分析
main.ccソースファイルinitディレクトリには、全体のLinuxカーネルのブートの出発点であるが、その出発点は、主な機能はありませんが、Linuxカーネルの初期化中start_kernel機能、start_kernel機能は、システム全体を完了します。最後のステップrest_initカーネルの初期化関数initプロセスは、祖先はすべて、このプロセスを開始しています。
2.4.1 start_kernel機能
Start_kernel関数は、初期化モジュール、クロック、および他の一連の処理を完了するために、最初に行われます。
asmlinkage __visible void __init start_kernel(void)
{
…
set_task_stack_end_magic(&init_task);
printk(KERN_NOTICE"%s", linux_banner); /* 输出linux版本信息 */
setup_arch(&command_line); /* 设置与初始化硬件体系相关的环境并调用 */
sched_init() /* 初始化调度器,先于中断开始前 */
printk(boot_command_line); /* 提取分析核心启动参数过程(从bootloader中传递) */
parse_early_param();
parse_args
trap_init();
return
early_irq_init(); /* 中断初始化过程 */
init_IRQ();
init_timers(); /* 初始化定时器 */
timekeeping_init();
time_init(); /* 设置定时器及返回当前时间 */
console_init() /* 初步的初始化控制台 */
vmalloc_init();
vfs_caches_init_early();
mem_init(); /* 初始化内存并计算可用内存大小 */
kmem_cache_init(); /* 初始化SLAB缓存分配器 */
calibrate_delay(); /* 延迟校准 */
fork_init(num_physpages); /* 初始化max_threads,init_task参数为fork()提供参考 */
buffer_init(); /* 初始化块设备读写缓冲区 */
vfs_caches_init(num_physpages);
signals_init(); /* 初始化内核信号队列 */
rest_init(); /* 最后实际进入reset_init()函数,包括所有剩下的硬件驱动,线程初始化等过程,这也最终完成start_kernel的启动过程 */
}
2.4.2 rest_init機能
rest_initによる新kernel_initとkthreaddカーネルプロセス機能
kernel_thread(kernel_init, NULL, CLONE_FS); #创建一个内核线程,实际上是一个内核进程,其中pid=1。其中kernel_init只是一个函数
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
#在kthreadd函数中kthread_create_list全局链表中维护的内核线程。当调用kthread_create时,会创建一个kthread,并被添加到kthread_create_list链表中。当进程执行完毕后,就会被从链表中删除。
3.まとめ
今週学習することで、次の研究では、Linuxカーネルのブートプロセスのステップについての私の最初の理解は、より多くの機能がさらにLinuxシステムのカーネルを学びます。