Bochs: VESA Bios Extensions Alejandro Furfaro Técnicas Digitales III Mayo de 2011 Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 1 / 15 Temario 1 2 Vistazo General Programación de las extensiones g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions ../img/lgban.g Ciclo lectivo 2011 2 / 15 Vistazo General Introducción El VGA BIOS de Bochs soporta, por extensión, la especificación VBE (VESA BIOS Extensions). Bochs solo emula VGA a nivel de hardware. En caso de habilitarse puede emular una tarjeta gráfica Cirrus, pero sin las extensiones VBE. En general emula una tarjeta de video simple que pueda manejarse con el VBE BIOS. La ventaja de esto es que si estamos corriendo nuestro kernel en Bochs (o en QEMU que también usa la VGA BIOS de Bochs) podemos acceder a este hardware emulado para setear modos de video directamente sin usar las VBE (acción que requiere entre otras cosas trabajar en modo real) g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions ../img/lgban.g Ciclo lectivo 2011 3 / 15 Programación de las extensiones Internals El hardware de gráficos emulado de bochs (de ahora en mas denominado BGA por Bochs Graphics Adaptor) se accede a través de dos ports de E/S de 16 bits cada uno. El primero es un registro ı́ndice y en segundo un registro de datos. (Esto es similar a como VGA maneja sus registros). A través de estos ports podemos habilitar o deshabilitar las extensiones VBE, cambiar la resolución de la pantalla y la profundidad de bits, y manejar una mayor pantalla virtual. Hay seis versiones de BGA (0xB0C0 a 0xB0C5), pero si estamos utilizando las últimas versiones de bochs solo nos debemos preocupar de la última (0xB0C5). Los fuentes de Bochs definen en vga.h, ubicado en el subdirectorio iodev/, un número de defines que son muy útiles para programar el BGA. Los nombres de esos defines inician todos con el prefijo g/FCEyN-Logo.jpg ../img/lgban.g VBE DISPI. Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 4 / 15 Programación de las extensiones Escribir y Leer Registros Para escribir un par ı́ndice/dato a un registro BGA se debe: 1 Escribir el valor del ı́ndice en el port de 16 bits #d e f i n e VBE DISPI IOPORT INDEX 2 0 x01CE Escribir el valor del dato en el port de 16 bits #d e f i n e VBE DISPI IOPORT DATA 0 x01CF BGA soporta 10 valores diferentes de ı́ndice (0 a 9): #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e g/FCEyN-Logo.jpg #d e f i n e #d e f i n e VBE VBE VBE VBE VBE VBE VBE VBE VBE VBE DISPI INDEX ID DISPI INDEX XRES DISPI INDEX YRES DISPI INDEX BPP DISPI INDEX ENABLE DISPI INDEX BANK DISPI INDEX VIRT WIDTH DISPI INDEX VIRT HEIGHT DISPI INDEX X OFFSET DISPI INDEX Y OFFSET Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions 0 x0 0 x1 0 x2 0 x3 0 x4 0 x5 0 x6 0 x7 0 x8 0 x9 ../img/lgban.g Ciclo lectivo 2011 5 / 15 Programación de las extensiones Escribir y leer Registros Para acceder a un registro, primero hay que escribir su valor ı́ndice en VBE DISPI IOPORT INDEX (0x01CE), para luego sı́ leer o escribir el valor de 16 bits de VBE DISPI IOPORT DATA (0x01CF). El valor retornado depende del registro especı́fico que se requiere. Para cambiar el contenido de los registros 1 a 3 (VBE DISPI INDEX XRES, VBE DISPI INDEX YRES, VBE DISPI INDEX BPP) deben antes deshabilitarse las extensiones VBE. Para ello se escribe el valor VBE DISPI DISABLED (0x00) en el ı́ndice VBE DISPI INDEX ENABLE (4). Los cambios no son visibles sino hasta que las extensiones VBE vuelvan a estar habilitadas. Para ello, escribimos el valor VBE DISPI ENABLED (0x01) al mismo ../img/lgban.g ı́ndice. g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 6 / 15 Programación de las extensiones codigo básico v o i d B g a W r i t e R e g i s t e r ( unsigned s h o r t I n d e x V a l u e , unsigned s h o r t D a t a V a l u e ) { outpw ( VBE DISPI IOPORT INDEX , I n d e x V a l u e ) ; outpw ( VBE DISPI IOPORT DATA , D a t a V a l u e ) ; } unsigned s h o r t B g a R e a d R e g i s t e r ( unsigned s h o r t IndexValue ) { outpw ( VBE DISPI IOPORT INDEX , I n d e x V a l u e ) ; r e t u r n inpw ( VBE DISPI IOPORT DATA ) ; } g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions ../img/lgban.g Ciclo lectivo 2011 7 / 15 Programación de las extensiones Check de disponibilidad Para comprobar si está disponible el BGA, puede leerse el valor del VBE DISPI INDEX ID (0). Si el valor leı́do es VBE DISPI ID5 (0xB0C5), significa que está presente la última versión de BGA. Si retorna 0xB0C0 a 0xB0C3, tenemos una versión bastante vieja de bochs y del VGA BIOS de Bochs. Si por alguna razón se necesita emular una versión vieja de BGA, pdemos en VBE DISPI INDEX ID (0), la versión exacta que se quiere conseguir. Si el comando se aplica con éxito, solo resta leer el registro nuevamente para comprobar si el valor que se seteó corresponde al valor enviado. Si este truco se ejecuta desde las aplicaciones y desde el kernel, puede romper la compatibiidad de Bochs VBE BIOS, que simpre espera encontrar la última versión. i n t B g a I s A v a i l a b l e ( void ) { r e t u r n ( B g a R e a d R e g i s t e r ( VBE DISPI INDEX ID)==VBE DISPI ID4 ) ; g/FCEyN-Logo.jpg ../img/lgban.g } Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 8 / 15 Programación de las extensiones Resolución y profundidad de bits Antes de empezar hay que fijar la resolución y la profundidad de bits: 1 2 3 4 5 Deshabilitar las extensiones. Escribir la resolución X en VBE DISPI INDEX XRES. Escribir la resolución Y en VBE DISPI INDEX YRES. Escribir la profundidad de bits en VBE DISPI INDEX BPP. Habilitar otra vez las extensiones. BGA es una emulación, no es hardware real. Las resoluciones máximas llegan a 1024, 1600, o 2560 en X (VBE DISPI MAX XRES) y 768, 1200 o 1600 en Y VBE DISPI MAX YRES). Depende de la versión de bochs. #d e f i n e VBE DISPI MAX XRES #d e f i n e VBE DISPI MAX YRES 2560 1600 Los valores posibles para profundidad de bits, son: #d e f i n e #d e f i n e #d e f i n e #d e f i n e g/FCEyN-Logo.jpg #d e f i n e #d e f i n e VBE VBE VBE VBE VBE VBE DISPI DISPI DISPI DISPI DISPI DISPI BPP BPP BPP BPP BPP BPP 4 8 15 16 24 32 Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions 0 x04 0 x08 0 x0F 0 x10 0 x18 0 x20 ../img/lgban.g Ciclo lectivo 2011 9 / 15 Programación de las extensiones Layout de la Memoria de Video Hay un layout particular para cada valor de profundidad de bits. Cualquiera sea el modo, el primer byte de memoria corresponde al pixel superior izquierdo de la pantalla. En general para un pixel de coordenadas (x,y), la dirección de memoria se calcula mediante (y ∗ VBE DISPI INDEX XRES + x) ∗ factor , donde factor depende directamente del valor de profundidad de bits configurado. g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions ../img/lgban.g Ciclo lectivo 2011 10 / 15 Programación de las extensiones Layout de la Memoria de Video 4BPP Se conoce como modo paleta. El color del pixel se representa mediante 4 bits (16 colores máximo). Estos bits seleccionan el color de fondo en el DAC del controlador 8BPP Puede establecer uno de 256 colores de una paleta de 8 bits, o puede coresponder a un tono e gris si la imagen es monocromática. 15BPP Cada pixel se representa con tres grupos de 5 bits, y el bit mas significativo que serı́a el No 16 se descarta. g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions ../img/lgban.g Ciclo lectivo 2011 11 / 15 Programación de las extensiones Layout de la Memoria de Video 16BPP Cada pixel se representa con dos grupos de 5 bits, el campo del color verde tiene 6bits. 24BPP Cada pixel es un grupo de 3 bytes 32BPP Cada pixel se representa con tres grupos de 16, y el byte mas significativo se descarta. g/FCEyN-Logo.jpg Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions ../img/lgban.g Ciclo lectivo 2011 12 / 15 Programación de las extensiones Modos de memoria Modo por bancos. Es el modo default. Cuando se habilitan las VBE extensions, y no se le indica nada en contrario, boschs habilita este modo, que implica tratar a cada área de memoria como un banco de a lo sumo 64 Kbytes, a partir de la dirección 0xA0000. (Ambos definidos en vga.h) #d e f i n e VBE DISPI BANK ADDRESS #d e f i n e VBE DISPI BANK SIZE KB 0 xA0000 64 Para seleccionar el número de banco de 64K con el que queremos trabajar se escribe el número de banco en VBE DISPI INDEX BANK, que como vimos le corresponde el Index 5, dentro de los registros internos del controlador. v o i d BgaSetBank ( u n s i g n e d s h o r t BankNumber ) { B g a W r i t e R e g i s t e r ( VBE DISPI INDEX BANK , BankNumber ) ; g/FCEyN-Logo.jpg } Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 ../img/lgban.g 13 / 15 Programación de las extensiones Modos de memoria Modo Linear Frame Buffer En este modo toda la memoria de video es un gran buffer a partir de la direccoión lineal 0xE0000000. #d e f i n e VBE DISPI LFB PHYSICAL ADDRESS 0 xE0000000 Para habilitar LFB, se usa el flag VBE DISPI LFB ENABLED (0x40), cuando se habilitan las extensiones VBE (de modo que escribir un valor igual a VBE DISPI ENABLED |VBE DSPI LFB ENABLED (0x41)). v o i d BgaSetVideoMode ( u n s i g n e d i n t Width , u n s i g n e d i n t H e i g h t , unsigned i n t BitDepth , i n t UseLinearFrameBuffer , i n t ClearVideoMemory ) { B g a W r i t e R e g i s t e r ( VBE DISPI INDEX ENABLE , VBE DISPI DISABLED ) ; B g a W r i t e R e g i s t e r ( VBE DISPI INDEX XRES , Width ) ; B g a W r i t e R e g i s t e r ( VBE DISPI INDEX YRES , H e i g h t ) ; B g a W r i t e R e g i s t e r ( VBE DISPI INDEX BPP , B i t D e p t h ) ; B g a W r i t e R e g i s t e r ( VBE DISPI INDEX ENABLE , VBE DISPI ENABLED | ( U s e L i n e a r F r a m e B u f f e r ? VBE DISPI LFB ENABLED : 0 ) | ( C l e a r V i d e o M e m o r y ? 0 : VBE DISPI NOCLEARMEM ) ) ; g/FCEyN-Logo.jpg ../img/lgban.g } Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 14 / 15 Programación de las extensiones misceláneos Limpiando la memoria de video Cuando habilita las extensiones VBE, bochs limpia la mameoria (léase, pone todos sus bytes en 0). Para evitar que esto ocurra, se puede usar el flag VBE DISPI NOCLEARMEM (0x80) justo alñ habilitar estas extensiones. Ası́ se pùede escribir el valor de VBE DISPI ENABLED |VBE DISPI NOCLEARMEM (0x81) para modo por Bancos, y VBE DISPI ENABLED |VBE DISPI LFB ENABLED |VBE DISPI NOCLEARMEM (0xC1) para Linear Frame Buffer. Conociendo las capacidades De la simple tarea de examinar el código de bochs [:O] (iodev/vga.c), puede verse que enviando el valor VBE DISPI GETCAPS al index VBE DISPI INDEX ENABLE hace que los campos VBE DISPI INDEX (XRES / YRES / BPP) retornen cuando se los lee en lugar de sus valores actuales, sus valores máximos (capacidad máxima). 8-bit DAC La paleta por default del DAC es de 3x6 bits, retornando de este modo un valor entre 0 y 63 por cada color. Seteando el bit VBE DISPI 8BIT DAC en VBE DISPI INDEX ENABLE cambia a 3x8 bits y convierte la paleta a los valores apropiados. Reseteando el bit g/FCEyN-Logo.jpg ../img/lgban.g todo vuelve a atrás otra vez. Alejandro Furfaro (Departamento de Electrónica) Bochs: VESA Bios Extensions Ciclo lectivo 2011 15 / 15