qemu中的新版vga仿真


讓我們先來了解一下歷史:

VGA起源:

VGA 由IBM在1987年提出。 它有一些列的新功能,同時也兼容它的那些前輩如CGA跟EGA的所有功能:

1. 文本模式(80x25,字體小一下的話也可以支持80x50)

2. 16色模式(640x480,四位色)

3. 256色模式(320x240, 8位色)

4. 也支持用戶自定義一些操作,例如雙重掃描或者分屏操作

 

VGA 具有了256K的內存,這個內存可通過位於0xa0000的內存地址訪問。不支持同時訪問所有內存,你需要利用bank寄存器來映射你想訪問的內存塊,然后訪問這片內存。

所有由QEMU仿真的VGA 都支持以上功能

超級VGA, SVGA

在90年代初期,生產廠商開始推出不同種類的加強版VGA卡,它們一般叫做超級VGA, 也簡稱SVGA。 由qemu仿真的cirrus VGA就是一種典型的SVGA. 這種卡增加了如下新功能:

1. 更多的視頻內存

2. 更好的分辨率,如256色

3. 更多的色彩度(64K,16位像素)

4. 甚至更多的像素(16M,每像素24 或32 位)

5. 線性framebuffer,這樣就可以同時訪問所有內存而不需要如上的寄存器轉換

6 2D加速(cirrus blitter)

 

qemu中的SVGA

qemu中除了cirrus以外的所有SVGA都支持boche的顯示接口。這個接口一開始由boche開發實現,這也是它為什么叫boche顯示接口。我們在QEMU 中也實現了它。它也是QEMU中標准ga的第一接口。virtio-vga,qxl-vga 以及vmvga只有在vga兼容模式下才支持boche顯示接口。vga兼容模式一般是顯卡在剛開始啟動系統還沒有加載顯示驅動的時候

boche顯示接口是一種半虛擬化接口,在虛擬顯示設備里只仿真了一些必須的物理資源,例如並沒有仿真像時鍾速率或者其他時間相關的寄存器。

一般來說,boche顯示接口使用0x1ce(寄存器索引)以及0x1cf(寄存器數據)兩個IO接口, 因為這兩個寄存器都是16位的並且數據寄存器也沒有排列,所有它們不能應用在非x86的系統,所以0x1d0也可以用作數據接口

 

現代虛擬機所使用的圖形

讓我們先來看一下現代虛擬機在圖形領域的使用:

1. 基本上只使用32位的色彩模式, 只有一個例外就是真16位色,偶爾還會在一些資源有限的地方使用,例如樹莓派

2. 2D加速已死, 現在或者使用軟件渲染或直接使用3D引擎來2D渲染

3. 文本模式除了BIOS外也很少被使用了,即便是這樣也只有在boot中加載KMS驅動以前使用,而UEFI則直接進入了圖形模式

4. 顯存轉映射模式也不存在了,文本模式仍然使用0x0000窗口,不是文本模式的緩存太小了也用不上bank切換

 

所以我們其實有很多其實由復雜代碼實現的仿真功能並沒有真正派上用場,而且這些代碼也有很多的安全隱患

 

所以,我們能簡化一下事情么?

答案是肯定的。 QEMU1.3已經開始這樣的工作了。 我們給stdvga設置了一個MMIO bar, 然后通過這個bar 來訪問vga寄存器一個bochs顯示接口寄存器

OVMF(UEFI對qemu的實現) 也在使用MMIO bar模式。 bochs-drm.ko 驅動也是使用了MMIO的方式。 

所以,虛擬端其實已經忽略了vga方針。

 

引入 -device bochs-display

一種在QEMU3.0中引入的新的顯示設備:

1. 不再兼容VGA。 我們使用 display/other 替代 display/vga來表示 PCI class

2. 它有一個 stdvga樣式的MMIO bar, 當然vga寄存器已經不存在了

3.  下一步將不在同VGA共享代碼, 這樣也大大的減少了代碼的數量級

4. 不再需要IO接口, 可以直接在PCIe槽中插拔

5. OVMF已經支持這種設備

6. bochs-drm.ko 驅動也支持它

 

所以,對於UEFI的用戶來說,你可以從stdvga中直接切換到bochs-display

 

但是,BIOS跟文本模式該怎么辦呢?

 

直接訪問VGA硬件進入文本模式在今天已經很少見了。 一般seabios跟linux的加載器會通過調用vgabios函數來實現文本渲染,所以我們可以劫持以下這些函數來支持文本模式,而不是真的使用硬件來支持。 sgabios使用了一種類似的方法,直接把vga文本輸出到了串口

幸運的是我們不是第一個面對這些問題的人。 coreboot可以初始化圖形硬件,設置一個具有原始顯示像素的framebuffer。 如果適應seabios的話仍然需要文本模式,引文coreboot還是不太普遍,仍有很多問題。 所以coreboot是有一個vgabios的變量來渲染文本到framebuffer中

 

如果只是修改以下程序的初始化代碼而不是像coreboot那樣寫framebuffer的話,我們其實已經准備好了。 seabios啟動信息已經可以在bochs-display的famebuffer中顯示了。

qemu 3.1 將完全支持這個功能。 vgabiso雖然已經在QEMu3.0中,但是因為一些bug問題,並沒有被設置成默認選項,需要手動設置來使它工作。

 

當然它也存在以下缺點,當然因為是一些很少遇見的情況,可能不會對你造成困擾:

1 linux 的 vgacon 不能使用, 因為我們並不是真正的訪問硬件。 所以你需要使用vesafb或者只是忽略這些早期啟動信息。一旦bochs-drm驅動加載了 fbcon會恢復正常使用

2. vgabios使用了1024x768的固定分辨率,並且初始化后不支持模式切換,這是因為初始化代碼是在實模式中運行的。當然你可以使用小一些的分辨率,畫面會在左上角對齊。

 

以上就是全部了,希望你能喜歡這個新的vga設備

 

https://www.kraxel.org/blog/2018/10/qemu-vga-emulation-and-bochs-display/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM