Lo hice y lo entendí

El blog de Vicente Navarro
09 nov

vga=ask y los modos VESA disponibles en el sistema

A mucha gente no le preocupará la resolución de la consola de Linux, el modo texto que se usa cuando no estamos en el entorno X Window, bien porque no lo hayamos cargado, bien porque hayamos salido temporalmente de él con la combinación de teclas Control+Alt+Fx.

Sin embargo, a mí sí que me gusta mucho salir a la consola. Y especialmente, me gusta ver el arranque detallado del sistema. Si me conformara con ver el bonito logotipo de Debian o de Ubuntu mientras espero a que arranque el sistema, nunca habría descubierto problemas como los que conté en Solucionando el error “attempt to access beyond end of device” con reglas de udev, hal y/o un parche del kernel y en Disk might not be spun down properly. Update shutdown utility..

Es por eso que para mí es importante contar con una resolución en la consola adecuada a la pantalla que esté usando, para que las letras se vean lo más nítidas posibles y sin que sean monstruosamente grandes. La resolución la podemos especificar con el parámetro del kernel vga=DDD o vga=0xHHH, donde DDD es el número del modo VESA que queremos utilizar en decimal y HHH es el mismo número en hexadecimal. El único requisito es que el kernel haya sido compilado con soporte del driver de framebuffer VESA:

$ grep FB_VESA /boot/config-2.6.27-7-generic 
CONFIG_FB_VESA=m

Lo único que necesitamos saber es qué modos VESA acepta nuestro adaptador gráfico y qué números tienen. Los más comunes (800×600, 1024×768, 1200×1024, etc.) son bien conocidos, y es a lo que dediqué precisamente la tercera entrada de este blog: Modos VESA aceptados por el kernel de Linux.

Sin embargo, el advenimiento de infinidad de portátiles y pantallas con resoluciones nativas poco convencionales (1680×1050, 1400×1050, 1400×900, etc.) no nos facilita precisamente el saber qué modos soportará nuestra pantalla y nuestro adaptador gráfico ya que, en ocasiones, el modo ni siquiera está estandarizado.

Hasta ahora, la forma que yo tenía de obtener la lista de modos VESA soportados era configurar X.org para usar el driver VESA modificando el fichero de configuración /etc/X11/xorg.conf:

Section "Device"
...
        Driver  "vesa"
...
EndSection

y reiniciar el servidor X (por ejemplo, con Control+Alt+Borrar o con “/etc/init.d/gdm restart“). En el fichero de log /var/log/Xorg.0.log el driver nos muestra los modos VESA que va descubriendo:

(II) VESA(0): Searching for matching VESA mode(s):
Mode: 100 (640x400)
        ModeAttributes: 0x39f
        WinAAttributes: 0x7
        WinBAttributes: 0x0
        WinGranularity: 64
        WinSize: 64
        WinASegment: 0xa000
        WinBSegment: 0x0
...

De modo que el siguiente comando nos devolverá la lista de modos VESA soportados, incluyendo el número de bits dedicados a colores:

$ egrep 'Mode:|BitsPerPixel' /var/log/Xorg.0.log | sed 'N; s/\n//;'
Mode: 100 (640x400)	BitsPerPixel: 8
Mode: 101 (640x480)	BitsPerPixel: 8
Mode: 102 (800x600)	BitsPerPixel: 4
Mode: 103 (800x600)	BitsPerPixel: 8
Mode: 104 (1024x768)	BitsPerPixel: 4
Mode: 105 (1024x768)	BitsPerPixel: 8
Mode: 106 (1280x1024)	BitsPerPixel: 4
Mode: 107 (1280x1024)	BitsPerPixel: 8
Mode: 10e (320x200)	BitsPerPixel: 16
*Mode: 10f (320x200)	BitsPerPixel: 32
Mode: 111 (640x480)	BitsPerPixel: 16
*Mode: 112 (640x480)	BitsPerPixel: 32
Mode: 114 (800x600)	BitsPerPixel: 16
*Mode: 115 (800x600)	BitsPerPixel: 32
Mode: 117 (1024x768)	BitsPerPixel: 16
*Mode: 118 (1024x768)	BitsPerPixel: 32
Mode: 11a (1280x1024)	BitsPerPixel: 16
*Mode: 11b (1280x1024)	BitsPerPixel: 32
Mode: 130 (320x200)	BitsPerPixel: 8
Mode: 131 (320x400)	BitsPerPixel: 8
Mode: 132 (320x400)	BitsPerPixel: 16
*Mode: 133 (320x400)	BitsPerPixel: 32
Mode: 134 (320x240)	BitsPerPixel: 8
Mode: 135 (320x240)	BitsPerPixel: 16
*Mode: 136 (320x240)	BitsPerPixel: 32
Mode: 13d (640x400)	BitsPerPixel: 16
*Mode: 13e (640x400)	BitsPerPixel: 32
Mode: 147 (1400x1050)	BitsPerPixel: 8
Mode: 148 (1400x1050)	BitsPerPixel: 16

El número de modo que nos aparece es hexadecimal. Hay que sumarle 0×200 en hexadecimal o 512 en decimal para usar el número en el parámetro vga=. Por ejemplo, para usar 1400×1050, pasaríamos el parámetro vga=0x348 o vga=840.

Esto está documentado en las fuentes del kernel en Documentation/fb/vesafb.txt:

The graphic modes are NOT in the list which you get if you boot with
vga=ask and hit return. The mode you wish to use is derived from the
VESA mode number. Here are those VESA mode numbers:

    | 640x480  800x600  1024x768 1280x1024
----+-------------------------------------
256 |  0x101    0x103    0x105    0x107   
32k |  0x110    0x113    0x116    0x119   
64k |  0x111    0x114    0x117    0x11A   
16M |  0x112    0x115    0x118    0x11B   

The video mode number of the Linux kernel is the VESA mode number plus
0x200.
 
 Linux_kernel_mode_number = VESA_mode_number + 0x200

So the table for the Kernel mode numbers are:

    | 640x480  800x600  1024x768 1280x1024
----+-------------------------------------
256 |  0x301    0x303    0x305    0x307   
32k |  0x310    0x313    0x316    0x319   
64k |  0x311    0x314    0x317    0x31A   
16M |  0x312    0x315    0x318    0x31B 

Como nos cuenta, hay una opción vga=ask que nos debería de sacar los modos disponibles, pero que no resultaba útil puesto que no mostraba los modos gráficos, que son precisamente los más interesantes:

Sin embargo, desde el kernel 2.6.25, la opción vga=ask ya nos muestra los modos VESA disponibles:

x86 setup: display VESA graphics modes in vga=ask menu

Display VESA graphics modes, with their mode IDs, in the vga=ask
menu.  Most VESA mode numbers are platform-dependent, so it helps to
have an easy way to display them.

Con lo que ahora, si nos situamos sobre la entrada de GRUB de un kernel superior a la 2.6.25, le damos a la tecla “e” para editarla:

Elegimos la línea de kernel y volvemos a darle a “e”:

Añadimos el parámetro vga=ask:

Y pulsamos sobre “b” para arrancar esta entrada del menú, ahora ya podremos ver la lista de modos VESA disponibles:

Además de ver sus números de modo VESA para poder usarlos posteriormente, podremos arrancar seleccionando uno de ellos:

¡Qué mejora tan interesante! ¿Verdad? Me sorprende que nadie lo hubiera implementado antes.

Lo último que nos quedaría por ver es cómo dejar un parámetro vga= puesto por defecto en el menú del GRUB.

Si nos limitamos a añadirlo a mano al /boot/grub/menu.lst,

title           Ubuntu 8.10, kernel 2.6.27-7-generic
root            (hd0,2)
kernel          /boot/vmlinuz-2.6.27-7-generic root=/dev/mapper/nvidia_bdehcbaa3 ro vga=834 
initrd          /boot/initrd.img-2.6.27-7-generic

nos encontraremos con que cada vez que actualicemos el sistema, se instale un nuevo kernel y se actualice el menú con el comando update-grub, el parámetro desaparecerá. Por ello, tendremos que, o bien poner nuestra entrada de menú fuera de la sección de AUTOMAGIC KERNELS:

### BEGIN AUTOMAGIC KERNELS LIST
...
### END DEBIAN AUTOMAGIC KERNELS LIST

o bien, modificar las opciones de la sección:

## ## Start Default Options ##
...
## ## End Default Options ##

En esta sección, los comentarios llevan dos almohadillas (##), y las opciones que usará update-grub sólo una (#). Con este sistema, el GRUB no verá estas opciones pero update-grub sí. Así, por ejemplo, podemos poner que el kernel por defecto lleve la opción vga= deseada modificando el defoptions. Probablemente, si nos interesa el vga=, es fácil que nos interese también quitar las opciones quiet y splash para poder ver todos los pasos del arranque y no el logo de la distribución:

## additional options to use with the default boot option, but not with the
## alternatives
## e.g. defoptions=vga=791 resume=/dev/hda5
# defoptions vga=840

O en lugar de modificar el defoptions, que sólo afecta al kernel por defecto, también podemos hacer que todos los kernels lleven la opción modificando el kopt:

## default kernel options
## default kernel options for automagic boot options
## If you want special options for specific kernels use kopt_x_y_z
## where x.y.z is kernel version. Minor versions can be omitted.
## e.g. kopt=root=/dev/hda1 ro
##      kopt_2_6_8=root=/dev/hdc1 ro
##      kopt_2_6_8_2_686=root=/dev/hdc2 ro
# kopt=root=/dev/mapper/nvidia_bdehcbaa3 ro vga=840

Tras los cambios:

$ sudo update-grub
Searching for GRUB installation directory ... found: /boot/grub
Searching for default file ... found: /boot/grub/default
Testing for an existing GRUB menu.lst file ... found: /boot/grub/menu.lst
Searching for splash image ... none found, skipping ...
Found kernel: /boot/vmlinuz-2.6.27-7-generic
Found kernel: /boot/memtest86+.bin
Updating /boot/grub/menu.lst ... done

Actualización 22/11/08:

Ayer leía en Eternal Prisoner: Consiguiendo la mejor resolución para la shell sobre el vbetest, una pequeña aplicación que también nos permite ver los modos VESA soportados por nuestra gráfica. Este comando no viene empaquetado en Debian ni en Ubuntu, de modo que si nos interesa usarlo en estas distribuciones, podemos descargar el paquete del Linux Real Mode Interface (LRMI), que es el que contiene el vbetest.c y tras un simple make, que apenas tardará unos pocos segundos, ya lo tendremos compilado. Desafortunadamente, no se puede compilar en AMD64, así que sólo nos servirá en sistemas de 32 bits.

:wq

Entradas relacionadas

8 Comentarios a “vga=ask y los modos VESA disponibles en el sistema”

  • gau dice:

    Genial!

    A veces me asustas. Me da la impresión que me lees el pensamiento. Precisamente quería dedicar unas horas a esto mismo!!! Como tú, me gusta ver que “pasa” cuando arranca mi GNU/Linux. Otra vez me has evitado un montón de trabajo.

    Gracias, supercoco!!!

  • Paco dice:

    Buenas,

    Como siempre excepcional! Solo una preguntilla… Lo he probado y no me funciona, ¿es posible que sea porque uso un sistema x64?
    Uso gentoo con un kernel 2.6.25

    Saludos

  • albertjh dice:

    Hola!!
    Que gran artículo! como siempre genial… me ha costado bastante entenderlo no te creas…

    Saludos!

  • @gau Gracias, me alegra de que te haya sido útil. Y ya me explicarás mejor lo de que te leo el pensamiento… ¿Tantas veces he dado en el clavo de lo que te hacía falta? ;-)

    @Paco Gracias. No sé por qué no te funcionará. ¿Qué es lo que no te funciona exactamente? ¿El vga=ask? Tal vez quieras probar a arrancar con un CD/DVD de Knoppix que por defecto arrancan con vga=791 (1024x768x64k) a ver si te funciona bien la elección de modos VESA.

    @albertjh Gracias… Espero que no te haya costado porque me haya explicado muy mal ;-)

  • Paco dice:

    Hola de nuevo,

    No me funciona el parámetros “vga=ask”. Por mucho que lo pongo siguen sin salirme los modos gráficos (y como ya digo uso un kernel 2.6.25).

    Supuse que podría ser por usar un sistema x86_64 ya que en la nota que pones en tu post dice textualmente: “x86 setup: display VESA graphics modes in vga=ask menu” por lo que podría ser la razón.

    ¿Qué opinas?

    Saludos

  • @Paco No, no creo que sea por lo de los 64 bits. Mi sistema también es de 64 bits y a mi me funciona con el 2.6.27 que lleva Ubuntu. Los ejemplos que ves en las capturas son de una Debian de 32 bits con 2.6.24 (el que no saca los modos gráficos) y 2.6.26 (en el que sí funciona).

    Entiendo que los modos de texto sí que te salen para elegir, ¿no?

  • Paco dice:

    Buenas,

    Si, los modos de texto me salen sin problemas. Buscaré cual es el problema (ya que queda descartado lo de los 64bits). Si encuentro algo lo pondré por aquí. Muchas gracias de nuevo! :)

    Saludos

  • Muy bueno! Yo hace poco desactive las opciones “splash” y “quiet” del grub para ver lo que sucedía mientras booteaba, pero claro, con la resolución default de la consola es puro scroll y no se llega a leer mucho. Mañana con mas tiempo lo implemento.

    Saludos!

Tema LHYLE09, creado por Vicente Navarro