



摘 要:嵌入式設備硬件資源相對受限,實時響應性要求高,但當前基于QEMU的MIPS架構模擬器的處理器時鐘精度低,虛擬機每計時1 ms對應真實時間誤差大于50倍。為提升虛擬機的實時性,對處理器時鐘仿真技術進行研究,基于開源仿真框架QEMU,分析了MIPS架構下處理器模型的時鐘初始化及時鐘中斷觸發方式,同時查閱天脈操作系統中關于處理器時鐘的配置代碼及系統運行tick計數方式,找出了時鐘中斷觸發不穩定的原因,通過修改處理器的時鐘模型代碼,實現虛擬機每計時1 ms,對應真實時間最大誤差小于2倍,有效提升了模擬器的時鐘精度。
關鍵詞:處理器時鐘;QEMU;虛擬仿真;MIPS
中圖分類號:TP311.5" " 文獻標志碼:A" " 文章編號:1671-0797(2025)07-0018-06
DOI:10.19514/j.cnki.cn32-1628/tm.2025.07.005
0" " 引言
嵌入式設備硬件資源相對受限、實時響應性要求高。其中,實時性是虛擬化技術需要面對的最重要的問題之一,在虛擬機操作系統和硬件之間增加了一個宿主機操作系統層,將影響虛擬機程序的實時性能。而當前在服務器和桌面領域廣泛應用的主流虛擬化方案,其設計之初并沒有考慮嵌入式領域的特殊需求,因此在實時性能上表現并不理想[1]。
可確定性是實時的最本質特點,實時程序的可確定性有兩個方面:運行可確定性和中斷響應可確定性。運行可確定指某一段代碼執行時間可確定,而中斷響應可確定指從硬件發出中斷到響應中斷的程序開始執行之間的時間可確定。
處理器時鐘是一個周期性的電脈沖信號,用于同步處理器內部的各個操作步驟,因此,實時性的基礎是高精度的處理器時鐘。
本文通過深入分析處理器時鐘的說明文檔、處理器時鐘模型代碼以及天脈操作系統對處理器時鐘配置的驅動代碼,根據操作系統驅動代碼對處理器時鐘的配置方法,找出了處理器時鐘模型中斷觸發不穩定的原因。通過修改模型代碼,完成了處理器時鐘精度的提升。
修改后的處理器時鐘模型實時性得到了有效提升,可以更好地支撐軟件在虛擬機上開發驗證,大幅縮短產品研發周期。另外,在硬件發布之前,開發人員可以選擇在虛擬機上完成更多的測試,從而提高產品質量。
1" " 技術背景
1.1" " 處理器時鐘簡介
處理器時鐘是處理器內部的一種計時器,是處理器執行操作的基本的時間單位,在計算機中是通過晶振產生的脈沖信號來計時,這些脈沖信號具有一定的頻率,稱為時鐘頻率,時鐘頻率越高,處理器每秒可以執行的指令數量就越多,性能也就越強[2]。
時鐘周期是處理器執行一個動作所需要的時間,它是時鐘頻率的倒數。CPU中的每個操作至少需要一個時鐘周期來完成,時鐘周期提供了一個統一的時間基準,使得不同的硬件組件和指令能夠按照同樣的時間節奏進行操作。各個組件和指令可以根據時鐘信號的跳變來確定何時開始和結束各自的操作,從而實現同步和協調。
處理器時鐘周期是影響計算機性能的關鍵因素之一。時鐘周期越短,處理器可以獲取的執行次數越多,計算機性能就會越高,但是,這也會使處理器產生更多的熱量,從而引發故障。同時,較高頻率的處理器也需要更高程度的電壓保持系統運行,這也會導致更多的能量被使用和釋放,從而增加了能源的消耗。因此,處理器時鐘的選擇會權衡性能和功耗兩方面因素。
1.2" " 處理器時鐘配置方法
MIPS架構的處理器中一般包含一個NODE PLL用于產生node時鐘,生成穩定且準確的時鐘信號,供CPU核、二級緩存Cache、一二級交叉開關及IO子網絡使用。node時鐘的產生結構如圖1所示。
輸出時鐘頻率的計算方式如下:
node_clock=(refclk/L1_div_ref)*(L1_loopc/L2_divout)
node_clock的分頻系數及倍頻系數是可以配置的,但需要保證可配分頻器的輸出refclk/L1_div_ref在合理范圍內。輸出的時鐘還可以由FREQ_SCALE模塊進行細粒度分頻控制[3]。
當SYS_CLKSEL設置為0x2b10時,表示PLL頻率通過軟件配置,這種配置下,默認對應的時鐘頻率為外部參考時鐘頻率,即所有PLL輸出都是SYS_SYSCLK,需要在處理器啟動過程中對時鐘進行軟件配置[4]。時鐘設置過程如下:
1)將對應的PLL的PD信號設置為1;
2)設置除了sel_pll_*及soft_set_pll之外的其他寄存器,即這兩個寄存器在設置的過程中寫為0;
3)將對應的PLL的PD信號設置為0;
4)其他寄存器值不變,將soft_set_pll設置為1;
5)等待寄存器中的鎖定信號locked_*為1;
6)設置sel_pll_*為1,此時對應的時鐘頻率將切換為軟件設置的頻率。
2" " 處理器時鐘仿真研究
2.1" " QEMU時鐘模型
QEMU(Quick EMUIator)在進行處理器時鐘仿真時,提供了多種時鐘類型和配置選項,以滿足不同虛擬化場景的需求。主要提供了以下幾種時鐘類型[5]:
1)REALTIME時鐘:依賴宿主機處理器時鐘,主要用來保持時間的準確性,與宿主機的實時時鐘進行同步,以確保虛擬機中的時間與實際時間保持一致。同時還支持一些特定的功能,例如時間偏移和頻率調整,時間偏移允許設置虛擬機時間和宿主機時間之間的固定差異,而頻率調整則可以用來微調虛擬機時間的流逝速度。
這種時鐘類型通過直接獲取宿主機處理器的時鐘信息來計時,因此其精度和穩定性受限于宿主機時鐘的性能。
2)VIRTUAL時鐘:只在虛擬機運行時才會計時,當虛擬機停止時,VIRTUAL時鐘也會停止,即VIRTUAL時鐘記錄的是虛擬機內部的時間滴答,它反映了虛擬機操作系統感知到的時間流逝,與REALTIME時鐘不同,VIRTUAL時鐘并不與宿主機的時間直接同步,它的前進速度取決于虛擬機執行的指令數量和宿主機處理器的性能[5],因此,在某些情況下,虛擬機內部的時間可能與宿主機時間存在偏差。
QEMU在icount模式下時,VIRTUAL時鐘的行為會有所不同,icount模式是一種指令計數模式,它允許QEMU根據虛擬機執行的指令數量來計算時間。在這種模式下,VIRTUAL時鐘可能會更加準確地反映虛擬機內部的時間流逝,但也可能與宿主機時間存在更大的偏差。
3)HOST時鐘:代表的是宿主機(Host OS)的時間,就像墻上的時鐘一樣,它會持續運行,即使虛擬機被掛起,HOST時鐘也會繼續走。HOST時鐘對于需要在虛擬機中模擬準確時鐘源的設備模型來說非常有用[6],因為對于實時操作系統或需要精確時間戳的應用,需要知道宿主機時間的準確變化。
QEMU允許虛擬機訪問HOST時鐘,直接獲取宿主機時間。HOST時鐘直接反映宿主機的系統時間,是虛擬機和宿主機之間的一個時間橋梁,因此其精度和穩定性與宿主機系統時間的精度和穩定性有關。
2.2" " 天脈操作系統對處理器時鐘的配置
天脈操作系統對處理器時鐘的關鍵配置包括:
1)通過配置協處理器CP0的Random寄存器,產生TLB(轉換后備緩沖器)陣列的入口索引。
2)通過配置協處理器CP0的Count寄存器,設置Count寄存器從0開始計數。
3)通過配置協處理器CP0的Compare寄存器,控制定時器中斷的頻率,當Count寄存器的值和Compare寄存器的值相等時,就會產生一個定時器中斷。
4)使能處理器時鐘中斷,在中斷處理函數中進行系統運行tick計數。
2.3" " QEMU中處理器時鐘模型設計
在QEMU中,模擬處理器時鐘采用的是定時器鏈表原理,使用鏈表結構來存儲和跟蹤所有的定時器,每個定時器在鏈表中都有一個對應的節點,節點中包含了定時器的相關信息[7],例如到期時間、回調函數等。
QEMU模擬處理器的指令運行,并在模擬過程中更新定時器的計數值,同時檢查當前計數值是否已達到或超過了設定的Compare寄存器的值(也稱為比較值),如果達到了設定值,那么將觸發定時器中斷,并更新定時器到期時間,將新的定時器插入到定時器鏈表中。當時鐘源發生變化時,QEMU會遍歷對應的定時器鏈表,檢查是否有定時器到期,如果有定時器到期,就會調用該定時器的回調函數,執行相應操作[8]。為了優化性能,QEMU的定時器鏈表是按照定時器的到期時間排序的,這樣當QEMU需要查找到期的定時器時,只需要從鏈表的頭部開始遍歷,直到找到第一個未到期的定時器為止。這種方式減少了遍歷鏈表的時間復雜度,流程如圖2所示。
2.4" " 虛擬機系統中時鐘誤差分析
在虛擬環境下,虛擬機使用的時鐘來自于QEMU的時鐘模型,QEMU的時鐘模型是軟件模擬,這樣就存在一些場景無法保證能及時準確地模擬實時中斷。
主要場景包括:
1)宿主機操作系統負載重,因而影響QEMU進程的被調度機會,宿主機操作系統不是實時操作系統,時鐘中斷的處理也并非“搶占”式,只有虛擬機獲得運行時刻才可執行[9],導致軟件時鐘中斷不能及時產生。
2)QEMU處理器時鐘模型的定時器鏈表存在排隊問題,需要等先到期的定時器回調函數執行完畢后才會查詢下一個定時器[9],導致定時精度不足。
3)天脈操作系統對定時器進行計數重載時,由于虛擬機運行速度慢,概率性出現Compare寄存器值小于當前的Count值,導致計算的定時器到期時間溢出。
4)QEMU中默認的時鐘源為VIRTUAL時鐘,該時鐘源反映了虛擬機操作系統感知到的時間流逝,并不與宿主機的時間直接同步,無法保證虛擬機的時間精度。
2.5" " 處理器模型優化
2.5.1" " 定時器替換
在Windows系統下多媒體定時器是一種高精度定時器,它提供比傳統Timer定時器更高的定時精度和更可靠的定時響應。與傳統的Timer定時器依賴VM_TIMER消息不同,多媒體定時器使用函數產生一個獨立的線程[10],在一定的中斷次數到達后,它直接調用預先設置好的回調函數進行處理,而不必等待應用程序的消息隊列為空,可以實現高達1 ms的定時精度,因此可以采用多媒體定時器替換QEMU的定時器鏈表。
timeSetEvent屬于多媒體定時器的一種,可以很精確地讀出系統的當前時間,并且能在非常精確的時間間隔內完成一個函數或過程的調用,函數原型如下:
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD dwUser, UINT fuEvent);
參數說明:
uDelay:以毫秒為單位指定事件的周期。
uResolution:以毫秒指定延時的精度,數值越小定時器事件分辨率越高,缺省值為1 ms。
lpTimeProc:指向一個回調函數。
dwUser:存放用戶提供的回調數據。
fuEvent:指定定時器事件類型。TIME_ONESHOT表示uDelay毫秒后只產生一次事件,TIME_PERIODIC表示每隔uDelay毫秒周期性地產生事件。
因此,處理器時鐘模型采用timeSetEvent創建高精度定時器,相關代碼如下所示:
void cpu_mips_clock_init (MIPSCPU *cpu)
{
CPUMIPSState *env = amp;cpu-gt;env;
UINT mMMTimerThreadID = 0;
mMMTimerThreadID = timeSetEvent (1, 1, mips_
timer_cb, env, TIME_PERIODIC );
}
在中斷處理函數mips_timer_cb中,定時觸發時鐘中斷,代碼如下所示:
static void CALLBACK mips_timer_cb (UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_
PTR dw1, DWORD_PTR dw2)
{
CPUMIPSState *env;
env = (CPUMIPSState *)dwUser;
if (env-gt;insn_flags amp; ISA_MIPS32R2){
env-gt;CP0_Cause |= 1 lt;lt; CP0Ca_TI;
}
qemu_mutex_lock_iothread();
qemu_irq_raise(env-gt;irq[(env-gt;
CP0_IntCtl gt;gt; CP0IntCtl_IPTI) amp;
0x7]);
qemu_mutex_unlock_iothread();
}
2.5.2" " 設置QEMU進程優先級
使用start命令,在啟動QEMU進程時,設定新啟動進程的優先級。以高優先級啟動QEMU進程,命令如下:
Start /HIGH qemu -system -mips64el.exe -M ls2k -bios ./bootrom.bin -kernel ./ls2k_os_bind.elf -serial\
COM4 -m 1024 -usb -smp 2 -nographic
2.5.3" " 更換時鐘源為REALTIME時鐘
修改處理器時鐘模型的時鐘源,使用REALTIME時鐘,REALTIME時鐘在Windows環境下通過QueryPerformanceFrequency獲取處理器頻率并使用QueryPerformanceCounter獲取當前時鐘,該函數可以提供微秒級的時間間隔[10],精度更高。
3" " 仿真與實驗結果
3.1" " 啟動QEMU
啟動QEMU并加載天脈操作系統,啟動命令如下:
start /HIGH qemu-system-mips64el.exe -M ls2k,loadCfgFile=loadfiles_hi600_dpm1.cfg -bios bootrom_
new.bin -kernel MSL_IPC.elf -m 4G -smp 2
其中,-M參數用于指定模擬的虛擬機(當前為龍芯2K1000),loadCfgFile用于指定加載的配置文件(包含天脈操作系統及應用文件的路徑和加載地址);-bios參數用于指定虛擬機啟動的boot文件;-kernel參數用于指定虛擬機啟動時加載的內核鏡像文件;-m參數用于指定分配給虛擬機的內存大小;-smp參數用于指定虛擬機中使用的邏輯CPU數量。
3.2" " 處理器時鐘模型優化測試
時鐘模型測試采用天脈操作系統時鐘驅動模塊的tick計數函數,首先設置每個tick為1 000 μs。代碼如下:
/* 設置每個tick的微秒值 */
microseconds_per_tick = 1000;
/* 設置時鐘頻率 */
sysClkRateSet(1000000/microseconds_per_tick);
在處理器時鐘中斷的回調函數中通過模型接口調用Windows系統的QueryPerformanceCounter函數記錄每次tick計數時的時間間隔,時鐘模型優化前的測試結果如圖3所示。
從測試結果可以看出,每次計算tick計數的時間間隔基本在100 000 000 ns左右,即100 ms,與設定的每個tick為1 000 μs即1 ms,誤差超過50倍。
優化處理器時鐘模型后對時鐘進行測試,測試結果如圖4所示。
從測試結果可以看出,每次計算tick計數的時間間隔在999 000~2 000 000 ns之間,即0.9~2 ms,與設定的每個tick為1 000 μs即1 ms誤差小于2倍。
以上實驗結果表明,優化后的處理器時鐘模型有效提升了模擬器時鐘精度,可以更好地支撐嵌入式實時系統在虛擬機上運行。
4" " 結束語
本文通過對QEMU的MIPS架構處理器時鐘仿真模型進行研究,分析出了時鐘模型精度誤差大的原因,采用替換多媒體定時器、設置QEMU進程的優先級以及修改時鐘源的方法,有效提升了QEMU的MIPS架構處理器時鐘模型的精度,為嵌入式實時操作系統在虛擬機上運行提供了有力保障。
[參考文獻]
[1] 于佳佳.基于QEMU的龍芯3A處理器數字化設計與實現[D].成都:電子科技大學,2018.
[2] QEMUdocumentation:Release6.1.0[S/OL].(2021-08-24)[2023-06-07].www.qemu.org.
[3] 董亮,許東歡,臧中原,等.時鐘模型輔助的慣性/衛星緊組合導航算法研究[J].導航定位與授時,2022,9(2):112-117.
[4] FAYNEH E,KNOLL E.Clock generation and distribution for Intel Banias mobile microprocessor[C]//
Proceedings of the Symposium on VLSI Circuits Digest of Technical Papers,2003:17-20.
[5] MOORE G E.Cramming more components onto integrated circuits[J].Proceedings of the IEEE,1998,86(1):82-85.
[6] 李可生,楊博,徐天偉,等.基于QEMU的可重構專用處理器模擬器實現[J].計算機工程與設計,2016,37(5):1335-1339.
[7] 懷進鵬,李沁,胡春明.基于虛擬機的虛擬計算環境研究與設計[J].軟件學報,2007,18(8):2016-2026.
[8] 崔磊,顏軻.軍用嵌入式仿真技術的體系結構研究[J].電子設計工程,2011,19(12):190-192.
[9] 劉春龍,王洋,申彪.多處理器嵌入式軟件的全數字仿真測試平臺開發技術[J].航天控制,2018,36(4):72-76.
[10] 李永際.計數器在時鐘電路設計中的應用[J].電子技術,2022,51(7):266-267.
收稿日期:2025-02-12
作者簡介:郭攀(1985—),男,陜西人,工程師,研究方向:機載計算機軟件。