|
囝仔放尿泉過溪,老人放尿滴著鞋。 |
在 uefi 環境下, 有對應的 print 可以使用, uefi 提供的服務有 boot service, runtime service, print 相關的函式屬於 boot service, 但是一旦呼叫 ExitBootServices() 之後, 就無法使用 print function 這些 boot service, 需要自己使用 framebuffer 來秀字。而在載入 kernel 之前, 需要呼叫 ExitBootServices()。
Graphics Output Protocol (GOP) 就是提供繪圖模式的功能, 所以可以拿來畫圖形, 自然也能拿來畫字。
UEFI OS loader 需要呼叫 ExitBootServices() 之後才能載入 os kernel, 所以在 os kernel 中, 該怎麼秀訊息?
在 legacy bios 下, 文字模式可以寫入 0xb8000 來印出字元, 繪圖模式是寫入 0xa0000, 這些在 uefi 都已經不能用, 所以連秀字都會是一個問題, 有一個簡單的方式是使用 com1, uefi 會出初始化 com1, 設定 baud rate 115200, 但需要用個 minicom 來看輸出, 會有點麻煩, 而且 notebook 也沒有 com1 可以用。
就算在 uefi loader 階段可以接受 com1 輸出, 但你不想在 os kernel 也用 com1 輸出吧! 感覺這 os kernel 很弱, 觀感不好。所以在這階段, 要把 frame buffer 資訊存起來, 傳遞給 os kernel。
這裡使用的流程是:
- 使用 gEfiGraphicsOutputProtocolGuid protocol 取得 framebuffer 相關資訊。
- 使用 Gop->QueryMode 找出想要設定的顯示模式。
- 再用 Gop->SetMode 設定顯示模式。
vga.c L117 ~ L146 就是在做這樣的事情, 以這個範例來說, 會設定為螢幕為 640X480X32bit color, 3 原色順序是: blue, green, red, reserve, 共 4 byte。
vga.c L276 gop->mode->fb_base 就是 framebuffer 開始位址, 對應到 (0,0) 這個螢幕座標。這就是 legacy bios 0xa0000 的對應值, 把顏色值寫到這區, 就可以畫圖了。
既然可以畫一個點, 就可以畫任何東西, 那該怎麼畫中/英文字呢? 中文麻煩了不只一點, 但英文已經有人做了, 我從 u-boot/include/video_font.h 取得 8X16 英文字形檔, 然後畫出所有英文字母。
fig1/fig2 分別是在模擬器和真實機器上的測試畫面。
|
fig 1 qemu 環境, 640*480*32bit color |
|
fig 2 在實際的 pc 上測試 |
ref:
- Ditching legacy BIOS in favor of UEFI
- UEFI Video after ExitBootServices()
- Get EFI/UEFI Memory Map
- set 80 x 25 text mode by UEFI
- Check Available Text And Graphic Modes From UEFI Shell
- Replacing VGA, GOP implementation for UEFI
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。