一.知識點回顧
1.計算機的“三個法寶”:存儲程序計算機,中斷,函數調用堆棧;
2.操作系統的“兩把寶劍”:中斷上下文的切換(保存現場和恢復現場),進程上下文的切換。
二.實驗內容
1.啟動menuos
執行命令 cd LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
menuos啟動成功。
2.利用gdb跟蹤調試內核
另打開一個shell窗口
設置斷點rest_init()
三.總結
1.start_kernel函數
start_kernel函數完成linux內核的初始化。幾乎每個內核部件都是由這個函數進行初始化的。
調用sched_init函數初始化調度程序;
電泳trap_init函數和init_IRQ函數來完成IDT初始化;
調用time_init()函數來初始化系統日期和時間;
調用kernel_thread()函數為進程1創建內核線程,這個內核線程又會創建其他的內核線程並執行。
2init_task進程和idle進程
init_task進程在Linux中屬於一個比較特殊的進程,它是內核開發者人為制造出來的,而不是其他進程通過do_fork來完成。Linux在無進程概念的情況下將一直從初始化部分的代碼執行到start_kernel,然後再到其最後一個函數調用rest_init。從rest_init開始,Linux開始產生進程,因為init_task是靜態制造出來的,pid=0,它試圖將從最早的匯編代碼一直到start_kernel的執行都納入到init_task進程上下文中。在rest_init函數中,內核將通過下面的代碼產生第一個真正的進程(pid=1):
kernel_init函數最有意思的地方在於它會通過調用kernel_execve來執行根文件系統下的/sbin/init文件(所以此前系統根文件系統必須已經就緒),kernel_execve對用戶空間程序/sbin/init的調用發起自int $0x80,這是個從內核空間發起的系統調用,與call_usermodehelper函數本質上是完全一樣的。
而此時init_task的任務基本上已經完全結束了,它將淪落為一個idle task,事實上在更早前的sched_init()函數中,通過init_idle(current, smp_processor_id())函數的調用就已經把init_task初始化成了一個idle task,init_idle函數的第一個參數current就是&init_task,在init_idle中將會把init_task加入到cpu的運行隊列中,這樣當運行隊列中沒有別的就緒進程時,init_task(也就是idle task)將會被調用,它的核心是一個while(1)循環,在循環中它將會調用schedule函數以便在運行隊列中有新進程加入時切換到該新進程上。