(作業3)Linux內核的啟動過程(從start_kernel到init進程啟動)


作業題目: 

詳細分析從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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM