QEMU 建建建建建建建 建建建 Dept. of Electrical Engineering National Cheng Kung University Tainan, Taiwan, R.O.C
Jan 01, 2016
QEMU 建立系統之方法
許維哲Dept. of Electrical Engineering
National Cheng Kung UniversityTainan, Taiwan, R.O.C
NCKU EE CAD
SoC Lab 2WeiZhe, Hsu, NCKU
系統建立 (1/2)電腦硬體由下列五大單元所組成 :
控制單元 算術邏輯單元 記憶單元 輸入單元 輸出單元
控制單元
算術邏輯單元
記憶單元 輸出單元輸入單元
CPU 控制訊號資料路徑
NCKU EE CAD
SoC Lab 3WeiZhe, Hsu, NCKU
系統建立 (2/2)在進行其功能模擬時,我們將其簡化為下 :
CPU: 結合控制單元與算術邏輯單元之功能 記憶單元 周邊裝置 : 輸出 / 輸入單元
CPU
控制訊號匯流排
資料匯流排
周邊裝置
記憶單元
周邊裝置 周邊裝置
NCKU EE CAD
SoC Lab 4WeiZhe, Hsu, NCKU
系統建立流程
建立CPU
建立記憶單元
建立周邊裝置
首先,要建立系統中的所有裝置元件,並將所有的裝置元件做訊號連接,流程如下 :
記憶單元訊號連接
裝置連接
NCKU EE CAD
SoC Lab 5WeiZhe, Hsu, NCKU
建立 CPU(1/2)QEMU 會建立一個 CPU 專屬的資料結構,稱為 CPUState ,用來
存放 CPU 中的下列內容 : 暫存器 控制訊號 處理器狀態 輸出入訊號 處理器產品資訊 QEMU 模擬 CPU 時會用到的相關訊號
以下為 QEMU 所支援模擬的 CPU 指令集列表 :
指令集 建立的 CPUStateUniCore32 struct CPUState_UniCore32LatticeMico32 struct CPULM32StateCRIS struct CPUCRISStateSPARC struct CPUSPARCStateAlpha struct CPUAlphaStateSH4 struct CPUSH4State
NCKU EE CAD
SoC Lab 6WeiZhe, Hsu, NCKU
建立 CPU(2/2)
指令集 建立的 CPUStatePowerPC struct CPUPPCStatei386 struct CPUX86StateXTENSA struct CPUXtensaStateS/390 struct CPUS390XStateARM struct CPUARMStatem68k struct CPUM68KStateMicroBlaze struct CPUMBStateMIPS struct CPUMIPSState
NCKU EE CAD
SoC Lab 7WeiZhe, Hsu, NCKU
建立記憶單元 (1/4)在 QEMU 中,使用 qemu_ram_alloc() 函式來建立模擬目標系統上
的記憶單元。qemu_ram_alloc() 函式原型
ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size) dev : 此次建立的記憶單元,所屬於哪個裝置;若是建立系統共用的記
憶單元,則此項輸入參數為 NULL 值。 name : 此記憶單元的名稱,方便辨識。 size : 此記憶單元的大小,單位為 Byte 。
qemu_ram_alloc() 函式行為 向主機平台 (Host Machine) ,宣告一個指定 size 的記憶空間,用來模擬目
標平台 (Target Machine) 上的記憶單元。 建立一個 RAMBlock 資料結構,用來記錄與管理此記憶單元, RAMBlock
資料結構即為虛擬記憶單元 (QEMU 所模擬出來 ) 與真實記憶單元 ( 執行QEMU 的實體主機 ) 的對映。
將此 RAMBlock 資料結構加入 ram_list 鏈結表中統一管理。
NCKU EE CAD
SoC Lab 8WeiZhe, Hsu, NCKU
建立記憶單元 (2/4)RAMBlock 資料結構說明
實例說明 ARM Versatile-PB platform
系統預設記憶體大小為 128MB
typedef struct RAMBlock { uint8_t *host; ram_addr_t offset; ram_addr_t length; uint32_t flags; char idstr[256]; struct RAMBlock *next;} RAMBlock;
結構成員 說明*host 指向新宣告實體記憶體空間 ( 主機平台 ) 的指標 (host
virtual address)offset 上一筆 RAMBlock 宣告記憶體時的結束位址 ( 目標平
台 ) ,亦即本筆新宣告記憶體空間的起始位址 ( 目標平台 )(target physical address)length 此 RAMBlock 所指向的記憶體空間的大小 ( 單位為 Bytes)
flag 此記憶單元的狀態idstr 此記憶單元的名稱*next 指向下一個 RAMBlock 資料結構
NCKU EE CAD
SoC Lab 9WeiZhe, Hsu, NCKU
ARM Versatile-Express(Vexpress) platform 此系統預設了三個記憶體單元 :
主系統記憶體 128MB 影像顯示記憶體 8MB 周邊裝置私有記憶體 32MB
建立記憶單元 (3/4)
Logic Tile expansionDynamic memory expansion socket
PCI BusMBX
Static MemoryAHB M2 EXP
ReservedRegisters
Dynamic expansion socketSDRAM
0x000000000x080000000x100000000x101F50000x140000000x20000000
*hostoffsetlength*next
ram_list
struct RAMBlock
0x00x8000000 128MB
主機平台QEMU 的 ram_list 鏈結表Versatilepb platform 的記憶體配置Memory
NULL
0x400000000x410000000x700000000x800000000xFFFFFFF
F
NCKU EE CAD
SoC Lab 10WeiZhe, Hsu, NCKU
建立記憶單元 (4/4)
External AXI between daughterboardsDaughterboard private
Local DDR2 RAMReserved
Motherboard memory and peripherals
ReservedUSB
EthernetReserved
Video SRAMReserved
SRAMNOR Flash 1NOR Flash 0
ReservedDaughterboard private peripherals
Motherboard peripheralsReserved
Remappable memory section0x000000000x040000000x100000000x100200000x200000000x40000000
0x5C0000000x600000000xA00000000xE00000000xFFFFFFF
F
0x440000000x480000000x4A0000000x4C0000000x4C8000000x4E0000000x4F0000000x50000000
*hostoffsetlength*next
*hostoffsetlength*next
*hostoffsetlength*next
ram_list
struct RAMBlock
0x00x8000000
0x80000000x800000
0x88000000x2000000
128MB
主機平台QEMU 的 ram_list 鏈結表Vexpress platform 的記憶體配置
8MB
32MB
Memory
NULL
NCKU EE CAD
SoC Lab 11WeiZhe, Hsu, NCKU
建立周邊裝置 (1/2)QEMU 會為系統上的每個周邊裝置,建立專屬的資料結構,其
內容通常為下 : 裝置元件所連接 Data Bus 的相關訊號
AMBA Bus 、 PCI Bus 、 USB Bus… 等 裝置元件所連接 Control Bus 的相關訊號
中斷控制訊號…等 裝置元件的輸出入訊號 裝置元件的狀態
Status 、 flags… 等 裝置元件中需要被暫存的訊號與資料
buffer 、 stack… 等實例說明
以 ARM Versatilepb platform 上的 PL050 裝置 (Arm PrimeCell PL050 Keyboard / Mouse Interface) 為例 :
NCKU EE CAD
SoC Lab 12WeiZhe, Hsu, NCKU
建立周邊裝置 (2/2)typedef struct { SysBusDevice busdev; void *dev; uint32_t cr; uint32_t clk; uint32_t last; int pending; qemu_irq irq; int is_mouse;} pl050_state;
System Data Bus 相關訊號
裝置 I/O 訊號
中斷控制訊號裝置狀態
NCKU EE CAD
SoC Lab 13WeiZhe, Hsu, NCKU
裝置連接 (1/10)由於 ARM 系統使用 Memory Mapping I/O ,所有系統上的裝置皆
會有一組相對應的記憶體位址。當 CPU 欲存取某一周邊裝置或記憶單元時,便使用其相對應的
記憶體位址做存取資料的行為。QEMU 在建立記憶體單元與周邊裝置時,亦會建立一個記憶體
位址對映表 (PhysPageDesc table ) ,用來標示記憶單元或周邊裝置所占有的記憶體位址。
將記憶體位址註冊到記憶體位址對映表中的方法如下 : 在建立記憶單元與周邊裝置時,使用 cpu_register_physical_memory() 函
式,將該記憶單元或周邊裝置所佔有的記憶體位址註冊到記憶體位址對映表中。
cpu_register_physical_memory() 函式說明 : 原始程式碼為下 :
void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) { cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0);}
NCKU EE CAD
SoC Lab 14WeiZhe, Hsu, NCKU
實際呼叫函式為 cpu_register_physical_memory_offset() ,主要動作為建立PhysPageDesc table ,並將指定的記憶體位址區段加入到 PhysPageDesc table中,以下為 PhysPageDesc table 之介紹 :
PhysPageDesc table 為記憶體位址的對映表,與系統裝置同時建立,以提供 CPU 轉換位址時使用。
PhysPageDesc table 為加快搜尋位址的速度,使用兩層的結構 (L1 table 與L2 table) ,位址的區分如下 :
以 ARM 模擬目標系統為例,記憶體位址的區分為下 :
記憶體位址 [31:20] 為 L1_index 記憶體位址 [19:10] 為 L2_index 記憶體位址 [9:0] 為目標分頁的偏移值
裝置連接 (2/10)
高位元 低位元L1_index L2_index Target_page_offsetTarget Physical Address
L1_index L2_index Target_page_offset31 0919
Target Physical Address
NCKU EE CAD
SoC Lab 15WeiZhe, Hsu, NCKU
資料結構 PhysPageDesc 說明 結構內容
完整的 PhysPageDesc table 架構如下圖 由全域變數 l1_phys_map 指向 PhysPageDesc table 的開頭 L1 table 中有 L1_index 個 PhysPageDesc * 指標,每一個 PhysPageDesc * 指標
又指向由 L2_index 個 PhysPageDesc 結構所組成的 L2 table
裝置連接 (3/10)
typedef struct PhysPageDesc { ram_addr_t phys_offset; ram_addr_t region_offset;} PhysPageDesc;
NCKU EE CAD
SoC Lab 16WeiZhe, Hsu, NCKU
PhysPageDesc
[0]
PhysPageDesc *
l1_phys_map
L2 tables
PhysPageDesc **
裝置連接 (4/10)
(Global variable in exec.c)
L1 table
[0]
[L2_index]
[0]
[L2_index]
[L1_index]
最多會有L1_index*L2_index 個PhysPageDesc 結構
高位元 低位元L1_index L2_index Target_page_offsetTarget Physical Address
NCKU EE CAD
SoC Lab 17WeiZhe, Hsu, NCKU
裝置連接 (5/10)在 QEMU 所模擬的系統當中, CPU 與周邊裝置的資料存取,是
透過呼叫周邊裝置的 read/write function 來完成資料的讀 / 寫,如下圖 :
QEMU 在建立周邊裝置的同時,會將每個周邊裝置的CPUWriteMemoryFunc() 、 CPUReadMemoryFunc() 與 Device_state 存放在 io_mem table 中,統一管理。
Device_StateCPUWriteMemoryFunc()
CPUReadMemoryFunc()
Device_behavior_function()CPU
周邊裝置
NCKU EE CAD
SoC Lab 18WeiZhe, Hsu, NCKU
變數名稱 說明io_mem_write 將資料寫到 IO 裝置的函式指標陣列,第一維參數為 io_index ,即每個
IO 裝置皆會配給一個 io_index ,第二維參數為函式寫入方式 (0 表示以 byte 為單位做存取, 1 表示以 word 為單位做存取, 2 表示以dword 為單位做存取 )
io_mem_read 將資料從 IO 裝置讀取出的函式指標陣列io_mem_opaque 每個裝置皆有其所屬的 state , io_mem_opaque 則是指向所有裝置
state 的指標陣列,若同一個 io_index 有 r/w 函式但無專屬 state ,則該 io_mem_opaque[io_index] = 0
io_mem_used 用來記錄第 n 個 io_index 是否已經被註冊使用, 0 表示無人註冊使用,1 表示已被註冊使用
/* Global Variables in Exec.c*//* io memory support *//* In ARM system, IO_MEM_NB_ENTRIES = 128 */CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][3];CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][3];void *io_mem_opaque[IO_MEM_NB_ENTRIES];static char io_mem_used[IO_MEM_NB_ENTRIES];
裝置連接 (6/10)io_mem table 說明
NCKU EE CAD
SoC Lab 19WeiZhe, Hsu, NCKU
裝置連接 (7/10)綜合上述流程, QEMU 所建立的系統資料存取架構如下 :
Target Physical Address
PhysPageDesc table
CPU
ram_list主機平台記憶體
RAM
io_mem_read[]io_mem_write[]
io_mem_opaque[]
io_mem tables
I/O memoryDevice A
Device B
Device N
NCKU EE CAD
SoC Lab 20WeiZhe, Hsu, NCKU
裝置連接 (8/10)在一個系統中, CPU除了使用資料線與所有周邊裝置做連接,另外也會有控制線的連接,一般常見的控制線即為中斷訊號。
ARM Versatilepb platform 的中斷訊號連接圖
使用了兩層的中斷訊號控制器,高優先權的裝置將中斷訊號接在 PIC; 低優先權的裝置將中斷訊號接在 SIC 。
NCKU EE CAD
SoC Lab 21WeiZhe, Hsu, NCKU
裝置連接 (9/10) QEMU 所模擬的 ARM Versatilepb platform 中斷訊號連接圖
SIC(
Seco
ndar
y In
terru
pt C
ontro
ller)
PIC(
Prim
ary
Inte
rrupt
Con
trolle
r)
IRQ
FIQ
PCI3sic[30]
PCI2sic[29]
PCI1sic[28]
PCI0sic[27]
Ethernetsic[25]
MMCI1Asic[23]
MMCI0Asic[22]
UART3sic[6
]KMI1
sic[4]
KMI0sic[3]
MMCI1Bsic[2
]MMCI0B
sic[1]
DMACpic[17]
CLCDpic[16]
UART2pic[14
]UART1
pic[13]
UART0pic[12
]Real Time Clock pic[10]
Timer 2 and 3pic[5
]Timer 0 and 1
pic[4]
pic[31]
pl190_state
vpb_sic_state
cpu_pic[0]
cpu_pic[1] CPU
CPUARMState
NCKU EE CAD
SoC Lab 22WeiZhe, Hsu, NCKU
裝置連接 (10/10) QEMU 所模擬的 ARM Versatile-Express platform 中斷訊號連接圖
GIC
(Gen
eric
Inte
rrupt
Con
trolle
r )
pic[48]
pic[44]
pic[15]
pic[13]
pic[12]
pic[11]
pic[10]
pic[9]pic[8]
pic[7]
pic[6]pic[5]
gic_state
pic[4]
pic[3]pic[2]Timer 0/1
Timer 2/3RTC
UART0UART1UART2
UART3
MMCI0
MMCI1
Audio
KMI0
KMI1
Ethernet
CLCD
Dual Timer moduleIRQ CPU[0]
CPUARMState
IRQ CPU[1]
CPUARMState
IRQ CPU[2]
CPUARMState
IRQ CPU[3]
CPUARMState
parnet_irq[0]
parnet_irq[3]
parnet_irq[1]
parnet_irq[2]
NCKU EE CAD
SoC Lab 23WeiZhe, Hsu, NCKU
Versatilepb platform in QEMU
Device[0]
Device[1]
Device[2]
Device[3]
Device[N]
APB DevicesAHB Devices
pic[0] pic[1] sic[0] sic[1]
CPU PIC
SIC
cpu_pic[0~1]
pic[31]pic[0~30]
sic[0~31]
System Bus
PIC : Primary Interrupt ControllerSIC : Secondary Interrupt Controller
PIC Bus
SIC Bus
io_mem table
PhysPageDesc table
Host Mem
ram_list
NCKU EE CAD
SoC Lab 24WeiZhe, Hsu, NCKU
Versatile-Express platform in QEMU
Device[0]
Device[1]
Device[2]
Device[N]
pic[0] pic[1]
GIC
System Bus
GIC : Generic Interrupt Controller
IRQ Buspic[2] pic[n]
pic[0~63]
cpu_irq[0] cpu_irq[1] cpu_irq[2] cpu_irq[3]
CPU[3]CPU[2]CPU[1]CPU[0]Host Mem
PhysPageDesc tableram_list
io_mem table
NCKU EE CAD
SoC Lab 25WeiZhe, Hsu, NCKU
NEXTLoading kernel
將 OS kernel image 、 Root file system 、 bootloader code載入到模擬目標系統上
QEMU 動態模擬 中斷訊號接收與處理 動態二進制轉換
Translation Block 中間碼轉換