Graphics cards from different manufacturers are very different beasts, in fact, often different generations of graphics cards from the same manufacturer can be pretty different too. While there’s a great deal of standardisation for things such as resolutions, colour depths and talking to monitors; the software side has almost no standardisation whatsoever.
In fact, one of the most fundamental operations, setting the resolution and color depth we desire (aka. the Mode) can be different for each and every card, let alone each and every manufacturer.
Practically speaking, this means that there are only two things that know how to set the mode. The Video BIOS and the Graphics Driver. Historically, within Linux, the Graphics Driver has resided within the X Window System server.
There are lots of different places that we need to set the mode:
- during boot, the Video BIOS will set an initial mode
- this may be changed by the boot loader using the Video BIOS or VBE
- when the X server is started, it will likely set a new accelerated mode using the card’s native protocols rather than VESA
- when switching between away from the X server to another VT, the previous video mode has to be restored
- when switching back to the X server from another VT, the correct video mode has to be set
- when resuming from suspend or hibernate, the correct video mode for whatever VT we resume to has to be restored
The two biggest problems here are switching from/to the X server VT, and resuming from suspend. In the former case, the biggest difficulty is actually switching between X servers on different VTs (e.g. user switching). The process ends up looking like this:
- user switch initiates VT switch from X server on VT7 to X server on VT8
- X server on VT7 restores the previous video mode (likely VGA text)
- X server on VT8 sets the video mode appropriately
This leads to the black screen and flashing cursor between VT switches that everybody hates. In the resuming from suspend case, it’s really tricky; we don’t necessarily know the right video mode to restore, calling into the Video BIOS (even with VBE) is tricky, error-prone and doesn’t work if it wasn’t a VESA mode, and the X server’s mode setting code was never designed to be called externally. This means we used to basically rely on resuming into the X server and having that restore the mode for us.
All this changes with Kernel Mode Setting (KMS). Throughout the development of Lucid, you’ve probably seen that term mentioned a few times.
Simply put, Kernel Mode Setting is all about taking the bulk of the Graphics Driver code out of the X server and putting it into the Kernel. This means that the kernel has Graphics Drivers just like the kernel has Network Card Drivers, Wireless Drivers, USB Drivers, etc.
Most importantly, the kernel can set the mode whenever we need to and restore it on resume. The three most user-visible results of this are:
- a high-color, high-resolution splash screen during boot with a seamless (no black screen) transition into the X server
- fast and seamless transition between X servers when user switching
- extraordinarily fast resume from suspend directly into graphics (no blinking text cursor)
Behind the scenes there’s even more awesome waiting to be used in future releases.
Obviously most of the effort on writing these new drivers has gone to the “big three” graphics card vendors’ hardware. Intel themselves have contributed a large part of the KMS work, and their own drivers for it; nVidia owners are covered by the reverse-engineering effort that created the nouveau driver; and ATI owners are covered by the new radeon driver.
Those with graphics cards from other vendors are a little out in the cold here, but at least they’re no worse off than they were before. The biggest source of complaint comes from those with cards for which there is also a binary driver available (usually nVidia).
By switching from the in-kernel graphics driver (i.e. nouveau) to one supplied as a binary loaded into your X server (i.e. nvidia-glx), you will not have Kernel Mode Setting support and are effectively regressing your own system to Ubuntu 9.04 state.
I’m sure that nVidia users will be quick to point out that in Ubuntu 9.04, they had more than 16-colors for the splash screen, and that’s true.
One of the other changes made in 10.04 is the switch from using usplash to draw the splash screen to using Plymouth. Both had the ability to draw to frame buffers (basically kernel 2D graphics canvases), but Plymouth had much better support for multiple heads, native panel resolutions, and most importantly the smooth transition into X.
Supporting KMS properly for those using the open source drivers meant regressing slightly in prettyness for those who don’t.
usplash used to support higher colors and resolutions by using SVGAlib as a backend when a frame buffer was not available; writing a new Plymouth SVGAlib renderer was simply too much work on top of the existing integration worked that needed to happen for KMS. (If someone wanted to do it as a personal project though, go right ahead!)
An alternative to using SVGAlib would have been to at least set a better mode through VESA or VBE. There are two common ways to do this, firstly by using the VESA frame buffer (vesafb) or secondly by having the boot loader set the graphics mode and keep it set when running the kernel, triggering the use of the EFI frame buffer (efifb). The problem with both of these is resuming from suspend. As discussed in detail above, we don’t have the ability to restore this mode on resume.
So we picked the third alternative, which has the added attraction that it works on all hardware and doesn’t cause other issues. We use good, old, reliable 16-color VGA.