linux kexec內核引導


linux kexec 介紹

kexec的功能是用一個運行的內核去運行一個新內核,就像運行一個應用程序一樣。這種機制因為跳過了bootloader,可以實現系統的快速重啟。另外kdump也是基於kexec實現(示意如下)。

 

kexec的實現有幾點難點:

  1. 在當前內核的上下文中,如何用新內核去替換現有內核?
  2. 正常復位啟動過程中,設備會被復位(或初始化)到已知狀態。跳過了復位階段,那如何在新內核kexec啟動時,保證設備狀態的可靠?

kexec的使用示例如下,其分為2部分:kexec內核加載和kexec內核執行。

    kexec -l /bzImage --initrd=/initrd.img.gz --append="ro nosmap loglevel=4 console=ttyS0,9600n8 acpi_rsdp=0x7b7fe014"
    kexec -e

kexec 內核加載

  1. 將內核鏡像文件、根文件系統、命令行參數等segment加載到用戶態內存;
  2. 對segment sha256檢查,確保內核數據沒有被破壞;如果是kdump,備份相關數據到備份區(如i386,最開始的640K配置數據用於SMP內核啟動,需要備份;或者powerpc,固定位置的異常向量等信息需要備份等)。這個環節又叫purgatory,其流程可以在用戶態控制實現,也可以在內核態控制實現(如使能--kexec-file-syscall選項);
  3. 分配內核態頁面,並將segment從用戶態內存copy到內核態頁面;如果使能--kexec-file-syscall選項,則跳過前面兩步,直接將segment加載到內核頁面,並進行purgatory。
  4. 分配頁面並初始化image->control_code_page,對其建立頁表,為下一步進行覆蓋當前內核時代碼尋址的頁表映射。初始化LEVEL4/3/2/1 4層頁表,並建立映射關系(如下圖所示)。

kexec 內核運行

  1. 調用設備驅動shutdown接口關閉設備;
  2. 關閉中斷,如IO-APIC, local irq, LAPIC;
  3. 關閉非0號CPU核;
  4. 清空TLB(此處以下代碼為匯編實現,具體實現與arch相關,一般名叫relocate_new_kernel);
  5. 設置段寄存器、gdt、idt等;
  6. 建立一個新棧,並將新內核的入口地址壓入棧中;
  7. 設置cr0寄存器:使能分頁功能和頁面保護功能;
  8. 設置cr4寄存器:使能擴展地址;
  9. 設置cr3寄存器,使cr3指向新的頁表根目錄;設置后,從此就與舊內核bye bye了;
  10. 將內核segment頁面copy到指定位置,覆蓋當前內核;
  11. 調用ret指令,從棧中彈出之前壓棧的新內核bzImage入口地址,進入新內核引導;

kexec 調試注意事項

  1. kexec不會同步或卸載文件系統,此過程需要用戶來保證;
  2. 從上面的流程中可以看出,kexec不會對cpu或設備進行復位,但系統重啟過程中會調用reboot_notifier_list,所以register_reboot_notifier注冊的接口不要有執行CPU復位等操作;
  3. 為了保證設備在kexec時處於穩定狀態,kexec會調用設備驅動的shutdown接口來關閉,確保用戶自己的設備驅動提供了正確的shutdown接口,或用戶通過其他方式進行關閉;

 

--EOF--

 


免責聲明!

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



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