作業題目:
詳細分析從start_kernel到init進程啟動的過程並結合實驗截圖撰寫一篇署名博客,並在博客文章中注明“真實姓名(與最后申請證書的姓名務必一致) + 原創作品轉載請注明出處 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000 ”,博客內容的具體要求如下:
-
題目自擬,內容圍繞Linux內核的啟動過程,即從start_kernel到init進程啟動;
-
博客中需要使用實驗截圖
-
博客內容中需要仔細分析start_kernel函數的執行過程
-
總結部分需要闡明自己對“Linux系統啟動過程”的理解,尤其是idle進程、1號進程是怎么來的。
作答區:
1. 使用實驗樓的虛擬機打開shell,輸入如下命令:
cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
2. 使用gdb跟蹤調試內核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 關於-s和-S選項的說明: -S freeze CPU at startup (use ’c’ to start execution) -s shorthand for -gdb tcp::1234 若不想使用1234端口,則可以使用-gdb tcp:xxxx來取代-s選項
3. 另開一個shell窗口
gdb (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加載符號表 (gdb)target remote:1234 # 建立gdb和gdbserver之間的連接,按c 讓qemu上的Linux繼續運行 (gdb)break start_kernel # 斷點的設置可以在target remote之前,也可以在之后
4. 以上步驟的截圖如下:
5. start_kernel函數的執行過程:
1 lockdep_init(); 2 set_task_stack_end_magic(&init_task); // init_task即手工創建的PCB,0號進程即最終的idle進程。 3 smp_setup_processor_id(); 4 debug_objects_early_init(); 5 // ... 6 trap_init(); // 中斷初始化向量 7 mm_init(); // 內存管理莫怪的初始化 8 sched_init(); // 進程調度初始化 9 // ... 10 rest_init(); // 啟動1號進程
6. “Linux系統啟動過程”的理解:
不管分析內核的哪一部分都會涉及到start_kernel。通過start_kernel進行調用,來初始化。
init進程是第一個用戶態進程,叫做”1號進程“。通過rest_init函數 -> kernel_init函數 -> run_init_process生成,找根目錄下的程序來作為“1號進程”。
當系統沒有進程需要執行時就調度到idle進程。這就是“0號進程”。從系統啟動之后就一直存在。它創建了1號進程“kernel_init”和其他進程。這樣系統就啟動起來了。
作者:李春霖
原創作品轉載請注明出處
《Linux內核分析》MOOC課程地址:http://mooc.study.163.com/course/USTC-1000029000