Wednesday, August 20, 2008

W(S)XGA+ Resolution in VirtualBox

Note: this post is related to a workaround for one specific problem encountered by the author.

Recently I switched from coLinux to VirtualBox. VirtualBox provides guest addition which includes enhanced support for Video. Originally it worked fine for me. Due to unknown reason, the problem arises: I could not use resolution 1440x900 (WXGA+) or 1680x1050 (WSXGA+) any more. WXGA+ is the native resolution of my laptop, while WSXGA+ is the resolution of the external LCD when the laptop is placed in a dock. After tweaking for a long time, following is the solution I found so far (I installed Gentoo Linux as guest OS).

1. Revert video driver from VirtualBox to Vesa

This is done by editing /etc/X11/xorg.conf, change one line in Section Device from Driver "vboxvideo" to Driver "vesa".

2. Install support of 1440x900 and 1680x1050 to VESA BIOS

Add parameter vga=864 as Linux bootup parameter (e.g. in /boot/grub/grub.conf) for resolution 1440x900, or vga=865 for 1680x1050.

When Virtual machine is turned off, run the following two commands at Windows command line prompt, assuming virtual machine is named "Gentoo":

VBoxManage setextradata "Gentoo" "CustomeVideoMode1" "1440x900x24"
VBoxManage setextradata "Gentoo" "CustomeVideoMode2" "1680x1050x24"

Start virtual machine, select resolution 1440x900 or 1680x1050 for console display. Note that the resolution for console is not necessarily the same resolution for X, i.e. you can use 1440x900 for console, and 1680x1050 for X.

3. Add modelines for resolution 1440x900 and 1680x1050.

I use gtf to generate needed modelines. For example for resolution 1440x900 with 60 Hz refresh rate, I use the following command:

$ gtf 1440 900 60

which give the following line:

  Modeline "1440x900_60.00"  106.47  1440 1520 1672 1904  900 901 904 932  -HSync +Vsync

I do not like the suffix _60.00, therefore what finally end up in section Monitor of /etc/X11/xorg.conf is (with addition of modeline for 1680x1050):

 modeline "1440x900" 106.47 1440 1520 1672 1904 900 901 904 932 -HSync +Vsync
 modeline  "1680x1050"  147.14  1680 1784 1968 2256  1050 1051 1054 1087  -HSync +Vsync

In addition, the two modes should be added in section Screen of /etc/X11/xorg.conf as well, my current setting is:

Section "Screen"
 Identifier "Screen0"
 Device     "Card0"
 Monitor    "Monitor0"
 DefaultDepth     24
 SubSection "Display"
  Viewport   0 0
  Depth     24
  Modes    "1680x1050" "1440x900"
 EndSubSection
EndSection

4. Select the resolution

Now the toughest part. You may have noticed that in section Monitor, there are two lines about HorizSync and VertRefresh. After experimenting, my conclusion is that one should comment out them when using 1680x1050 while enable them for 1440x900. Weird.

Since I need to switch between these two resolutions frequently, manually editing file /etc/X11/xorg.conf is boring. Therefore I write one script to automate the task. I named the script as xres and invoke it as sudo xres 1440 for resolution 1440x900 and sudo xres 1680 for 1680x1050. Following is its content:

#!/bin/bash
case $1 in
    1440)
        sed -i 's/^#    HorizSync    31.5 - 64.3/       HorizSync    31.5 - 64.3/' /etc/X11/xorg.conf
        sed -i 's/^#    VertRefresh  50.0 - 70.0/       VertRefresh  50.0 - 70.0/' /etc/X11/xorg.conf
        ;;
    1680)
        sed -i 's/^     HorizSync    31.5 - 64.3/#      HorizSync    31.5 - 64.3/' /etc/X11/xorg.conf
        sed -i 's/^     VertRefresh  50.0 - 70.0/#      VertRefresh  50.0 - 70.0/' /etc/X11/xorg.conf
        ;;
    *)
        echo "Supported horizontal resolution: 1440 and 1680."
        exit
        ;;
esac