1. 程式人生 > >2018-2019-1 20189219《Linux內核原理與分析》第四周作業

2018-2019-1 20189219《Linux內核原理與分析》第四周作業

選擇 sta 啟動系統 pid 初始 linu 便是 smp art

1. 首先設置斷點在start_kernel函數處,使用c命令之後提示進入了該啟動函數,如圖:

2. 進入函數之後發現這裏面的大多數函數並不能從名字上看出它們的意義,只能一步一步的試,於是我在init_task這個重要的進程變量處設置斷點b 510,然後c,發現menuOS竟然開始跑了。但是結果卻不盡如意,因為它最終沒有成功的啟動系統,而是卡死在這一步,於是ctrl+c中斷操作,得到了如下信息。

default_idle () at arch/x86/kernel/process.c:314
314     trace_cpu_idle_rcuidle(PWR_EVENT_EXIT,,smp_processor_id());

於是我去查看了arch/x86/kernel/process.c:314

310 void default_idle(void)
311 {
312     trace_cpu_idle_rcuidle(1, smp_processor_id());
313     safe_halt();
314     trace_cpu_idle_rcuidle(PWR_EVENT_EXIT,smp_processor_id());
315 }

看完之後一頭霧水,本打算放棄,我看到了在main.c:511中的smp_setup_processor_id()查閱得知,此函數是針對SMP處理器,用於獲取當前CPU的硬件ID,如果不是多核,函數為空。判斷是否定義了CONFIG_SMP,如果定義了,調用read_cpuid_mpidr讀取寄存器CPUID_MPIDR的值,即當前正在執行初始化的CPU ID

結合剛才qemu中給出的信息unable to init device /dev/mcelog,猜想應該是start_kernel函數在初始化0號進程的時候無法識別cpu的硬件ID從而報錯導致卡死。那如何來驗證自己的猜想呢?

  • 1.查看/dev/mcelog。在自己的系統上查看發現這是個c屬性文件,即字符設備,查閱得知,該設備是用於是 x86 的 Linux 系統上用來 檢查硬件錯誤,特別是內存和CPU錯誤的工具。
  • 2.查閱有關smp_processor_id()的資料,發現這個函數不同於smp_setup_processor_id()函數,它不可以直接讀取寄存器中的值來獲取cpuid,而必須獲取內核變量保存的處理器id,因此smp_processor_id()
    函數必須使用初始化函數。
    這大概便是為何剛才初始化0進程時出錯的原因了,但是苦於找不到上述兩個函數的源碼,找到了也不一定能看懂,只能粗略分析至此。

3. 這一次我不再直接進入初始化init_task模塊了,在進入start_kernel函數之後,我選擇了b 511,但是這一次c之後,qemu並沒有任何變化。b 512依舊沒有反應,

4.

2018-2019-1 20189219《Linux內核原理與分析》第四周作業