2019-2020-1 20199311仕事の4週目の「Linuxカーネルの原理と分析」

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システムのカーネルを学びます。

おすすめ

転載: www.cnblogs.com/w-a-n-s-d-j/p/11653425.html