陳鐵 + 原創作品轉載請註明出處 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000
其實對於Linux算是很熟悉了,最近五年的工作電腦就安裝的Ubuntu系統,由於畢竟工作時Windows還離不開,於是就在主機下虛擬個windows XP系統,解決必須用windows的工作。儘管這樣,對於內核的啓動過程其實一無所知,只是看到啓動過程不斷輸出信息,然後等待shell的登陸界面。這次通過學習,也算略有了解,就把老師要求的實驗過程記錄一遍,也加深自己的印象。
虛擬機中的電腦沒有成功,最後還是直接使用實驗樓的環境,把分析過程記錄一下:
直接啓動可調試模式。系統停止在內核加載之前。
按下Ctrl+Shift+T開啓另一個終端窗口。啓動gdb,加載內核代碼,連接遠程端口1234。
設置斷點break start_kernel,c命令繼續執行,可以看到虛擬機啓動窗口中,操作系統停止在Booting the Kernel。
在gdb中執行list命令可以查看當前執行的代碼。
執行幾次list命令,可以看見start_kernel中的初始化函數,有些名字就說明了作用,同時代碼開始處也都進行了說明。如
boot_cpu_init();
page_address_init();
trapf_init();
內存管理初始化
mm_init();
核心進程調度器初始化,其優先級要高於任何中斷,初始化進程0,也就是idle進程
sched_init();
init_IRQ();
init_timer();
console_init();
pidmap();
任務系統初始化
cred_init();
buffer_init();
key_init();
再設置一個斷點break rest_init,c命令繼續執行如下:
直接執行完啓動過程,出現老師改造過的簡單界面menuos。可以執行3個命令,其它輸入都會提示“This is a wrong cmd!
總結,Linux內核啓動有次引導程序Grub將內核代碼(內核映像)加載到內存,取得系統控制權,執行start_kernel中的相應代碼,完成系統的各種初始化處理,進入idle進程,也就是0好進程,在linux進程列表中看不到,然後調用init作爲系統的1號進程,完成系統環境的設置。init進程成爲所有進程的父進程,進入人機交互方式,出現我們熟悉的界面,完成內核的啓動。