UEFI開發探索06 – 圖形顯示01
到了我最喜歡的環節了,圖形顯示!
我曾經寫過不少關於圖形顯示的部落格和論文,特別是在Legacy BIOS以及嵌入式裝置中的顯示。PC的顯示一直都遵循著VESA的標準,在底層的訪問還是比較一致。雖然在多年的開發中,也在一些主機板上出現過奇怪的現象(一次而已。Award某款主機板,設定顯示模式的時候,花屏。在呼叫設定顯示模式的函式前,多壓幾次堆疊,問題又消失了。)。但當年寫的核心顯示程式碼,運行了近10年了,也沒出現過顯示的問題。
這是我曾翻爛過的參考書:

還有這些…

以及《最新VESA SVGA圖形影象程式設計祕技》 李軍著、《C語言遊戲程式設計從入門到精通》,還有影象格式,主要是BMP、PCX和jpeg。哦,還有一本雷軍(沒錯,我就是當年用過這本書,才成為米粉的)和求伯君的《深入DOS程式設計》。
寫得最紮實的是《IBM PC的原理及應用》以及《PC技術內幕》,想了解底層顯示原理的可以參考一下。雖然我覺得這些知識有點過時了,但對理解還是有幫助的。
在Foxdisk的部落格中,曾經簡略的提到了如何進行底層的顯示程式設計,三個步驟:
1) 設定顯示模式(如0x103為 800×600 256色的配置);
2) 設定顏色暫存器;
3) 按照圖形顯示的原理編寫畫點、畫線、畫圓等基本函式。
詳細的顯示原理以及程式設計沒有去討論,後面會陸續在Foxdisk的系列部落格中談到的。
回到UEFI的顯示上,基本的顯示原理不會有什麼變化,intel也沒有重新造一個新的顯示模型出來。我覺得UEFI應該還是如上述三個步驟一樣執行。無非還是顯示模式如何設定,怎麼畫點,以及如何減少視訊記憶體換頁。檢視UEFI spec(對照UEFI spec 2.8),有個關於顯示的PROTOCOL,截圖如下(uefi spec 2.8 page 448):

開始寫程式碼。
第一個問題就是SetMode。在Spec中提供了兩個SetMode函式,一個是EFI_GRAPHICS_OUTPUT_PROTOCOL的,另外一個是EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL的,這讓我很困惑。猜測後一個是用來轉換Text mode和Graphic mode的。
以前在除錯彙編程式碼時候,int 10h設定顯示模式為3,就是進入了Text mode。除錯顯示程式時,這是常用的程式碼。因為進入Graphic mode後,debug.exe的資訊很多時候是沒法顯示的,必須回到Text mode才能看到。因此我有上述的猜想。
在除錯中,我參照了aptio寫的程式碼,並且對照除錯結果,收集了一些資訊。未來可能用得上,記錄如下。
1. UGA window模擬環境中,text mode有三種,graphic mode有五種;
2.以前的程式碼(aptio)使用了gEfiConsoleControlProtocolGuid來獲取protocol,但是在uefi spec2.3.1中已經輸出了ConOut了,我以為沒有必要再這樣使用。懷疑與版本相容有關,是否EDK1中是這樣實現的?
3.GOP在後續版本中替代了UGA。see page 2065 in UEFI_Spec_2_3_1;
4.\EdkCompatibilityPkg\Foundation\Library\Dxe\Graphics,包含了一些使用方法;
5.\EdkCompatibilityPkg\Foundation\Protocol\ConsoleControl,包含了另外一些使用方法;
6.Text mode的第二個模式,columns和rows都是0,懷疑就是EfiConsoleControlScreenGraphics, 轉換為graphic mode所要用到的。
照舊將程式碼放到百度雲上了。這次的程式碼主要是收集資訊,加深對UEFI圖形顯示的理解。將程式碼編譯,顯示的資訊如下。

可以看到各種顯示資訊:Text Mode有三種,Mode 0應該就是我們常用的80×25的字元模式;Graphic則有5種,解析度分別為800×600、640×480、720×400、1024×768、1280×1024。對照VESA的標準,能體會不少事情。奇怪的是為什麼不是順序安排解析度的,有什麼深意嗎,還是EDK的開發者就是這麼隨意?
百度雲連結:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取碼:dx23
程式碼在 02 GraphicsOutput下
6 total views, 6 views today