QEMU/seaBIOS啓動流程分析

1 QEMU函數執行流程

  machine_init(pc_machine_init) –> pc_machine_init(void) –> 註冊QEMUMachine結構體變量pc_i440fx_machine_v2_3 –> pc_init_pci –> pc_init1 –> pc_memory_init –> pc_system_firmware_init –> old_pc_system_rom_init –> 檢查bios文件不爲空並且大小是65536的整數倍 –> memory_region_init_ram初始化一定大小的虛擬機物理內存 –> vmstate_register_ram_global –> memory_region_set_readonly –> rom_add_file_fixed將bios文件加載到虛擬機物理內存(uint32_t)(-bios_size)(物理內存最高的地方)處 –> memory_region_init_alias創建isa_bios作爲bios的別名使用,但是最多映射bios的最後128Kb –> memory_region_add_subregion_overlap將isa_bios映射到ISA空間 –> memory_region_set_readonly設置ISA空間爲只讀 –> memory_region_add_subregion將bios映射到ROM內存的最高處。

2 seaBIOS背景知識

  SeaBIOS也像正常的BIOS一樣,在虛擬機上電的時候,會被加載到地址空間0xFFFFFFF0處,並且該處是一條跳轉指令,虛擬機的虛擬CPU會去執行SeaBIOS的代碼,完成虛擬硬件的初始化,中斷服務函數的設置,ACPI表、SMBIOS表、E820表等的創建,最後引導啓動OS。
  SeaBIOS程序的各種入口點都在src/romlayout.S這個文件中定義了,啓動包括了vCPU上電後開始執行的起點src/romlayout.S:reset_vector,該位置會被QEMU加載到vCPU物理空間的0xFFFFFFF0位置。該處的指令是一個跳轉指令,該指令會跳轉到src/romlayout.S:entry_post位置,然後判斷是否是系統resume,如果不是則跳轉到post.c:handle_post()函數處,開始POST(Power On Self Test)階段。

3 Seabios啓動流程分析

這裏寫圖片描述

4 maininit函數功能

  對各種系統資源進行初始化,然後尋找可啓動的設備,其中比較重要的是對fw_cfg設備進行初始化,該設備是QEMU傳遞Firmware信息給SeaBIOS的一個模擬設備,SeaBIOS通過fw_cfg設備可以獲取到SMBIOS、ACPI、E820表等信息。
  詳細過程如下:
  1. 對系統的各種接口進行初始化,主要是軟件上的接口,沒怎麼動到其他硬件
    1.1 對fw_cfg設備進行初始化,該設備是QEMU傳遞Firmware信息給SeaBIOS的一個模擬設備,SeaBIOS通過fw_cfg設備可以獲取到SMBIOS、ACPI、E820表等信息。
    1.2 初始化中斷向量表
    1.3 初始化BDA(BIOS Data Area)、EBDA(Extended BIOS Data Area)數據區,這兩個區域是BIOS標準中定義的,用於存放一些BIOS相關的信息,並且有一些指定的用途。
  2. 配置平臺硬件
    1.1 配置平臺DMA控制器
    1.2 配置中斷控制器
    1.3 配置PCI設備,搜索系統中的PCI設備,併爲各個PCI設備分配I/O和Memory地址空間,讓系統能夠正確地訪問PCI設備,並配置相應的中斷。
    1.4 配置好SMRAM的內存入口點,並將其隱藏起來
    1.5 配置好MTRR(Memory Type Range Register)寄存器,即配置不同內存區間的內存屬性(從CPU的角度看)
    1.6 給其他非BSP(Bootstrap Processor)CPU,即AP(Application Processor)發送IPI中斷,讓AP對其自身進行初始化。並等待其他AP執行完畢。
    1.7 建立MP表,SMBIOS表和ACPI表
    1.8 配置時鐘和定時器
  3. 選取系統的顯卡,並執行其PCI Option ROM對顯卡進行初始化,這步完成後,顯示器就被點亮了,並且可以開始顯示啓動過程
  4. 對各種外設進行初始化,如USB控制器,磁盤控制器,鍵鼠控制器等等,由於外設比較多,並且速度慢,所以在對這些設備進行初始化的時候,SeaBIOS引入了Thread的概念(其實更應該叫做協程),讓多個設備的初始化同時執行,並不是嚴格的並行執行,此時只有一個CPU在執行,它在多個設備的初始化程序中來回切換,確保不會在一個設備的初始化中卡住很長時間
  5. 執行其他PCI設備的Option ROM,初始化相應的PCI設備
  6. 收集可啓動選項,並且調用0x19中斷,開始OS的啓動。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章