Linux 2.2 and the Frame-Buffer Console
Linux is a fascinating and fast-paced beast. It seems like only yesterday the hardy developers of the Linux kernel were busily putting the finishing touches on ELF support, loadable modules and SMP (Symmetric Multiple Processing)--things we take for granted today. In those days, more time was spent on the critical hurdles, the ones that would turn Linux into the great server platform it is today. In today's Linux world, more time is spent on the less critical components of the system: new file systems, television and radio cards and parallel-port drives. I feel the increased interest in the operating system by the world's corporations will make even more “non-critical” hardware be supported in the future.
Linux 2.2 is a milestone for Linux's development. No longer is Linux a niche operating system—it is a viable solution for the masses. With support for so many new options, it's no wonder.
Text-mode, Linux's most basic output method, is also one area where Linux has changed little since the “old” days. The text-mode console of Linux 2.0 is pure in its simplicity with one obvious (and maybe striking) fact: no code for graphical primitives is in the kernel. The lowest level interface to the text-mode kernel is as simple as the file stream. Higher level functions, such as would be required for full-screen text console applications (Pine, etc.), are done through a superset of the vt100 terminal protocol. Libraries, such as ncurses, are built on top of this to simplify programming and to provide a sort of terminal abstraction. Applications written for Linux's text-mode console using this abstraction can run on just about any terminal. Scroll back and Linux's famous virtual consoles are not a sophisticated extension of those basic building blocks, but rather an extension provided because of the text-mode driver's close relationship to the VGA hardware on which it was designed.
Other utilities exist, such as SVGATextMode, which allow us to access some of the graphical capabilities of hardware in text mode. These utilities generally allow one to change text resolution, fonts and colors. However, these extensions directly interface VGA features and do not call on any extensions in the kernel. Generally, the Linux console is so modular in design that it does not notice the low-level VGA feature changes. These utilities should not be confused with SVGALib or the frame-buffer console, as they allow manipulation only within the hardware's text modes.
There is obviously quite a bit more to modern hardware than simple text modes. As mentioned before, kernel hooks are not provided for accessing these functions, but many user-space programs and libraries are available that bypass the kernel altogether to access the hardware beneath. (“User space” is a term used to describe the limited and protected “space” in which user programs run. In contrast, “kernel space” routines are generally unprotected and can cause crashes and other problems. User protections can be removed in order to allow user programs to access hardware.) Unfortunately for SVGALib, the most popular alternative, the support API provided is heavily tied to the features of the VGA hardware, making it difficult to port either the SVGA library or the end application to any other type of hardware. The other downside is that this library does not support all VGA hardware at its full potential, but that can be forgiven due to the turbulent nature of hardware design. Limitations aside, SVGALib has proven to be a stable and popular solution to the console problem and is the primary interface used in Quake and other games.
The final and most popular option for accessing the video hardware under Linux is through the X Window System, the most common GUI subsystem for UNIX. The X Window System includes an “X Server” which is similar in purpose to a Windows-style video driver. In addition to “driver” features, the X server includes code for running programs over a network and handling many GUI tasks internally. In this respect, the “driver” portion is not truly separate from the “server” portion. A program that wishes to access the video hardware would do so by communicating with the X server through its API.
The first and most obvious disadvantage of this approach is that it would be difficult, if not impossible, on some setups to run a “console” (full-screen) application via this method. Second, because of the combined driver/server features of the X system, servers tend to be very large, making it difficult to allow programs to run in low-memory situations. The third disadvantage of this approach is that it is fairly common for companies to profit by selling closed-source X servers for new hardware. However, the primary advantage of this system, having a long-standing and cross-platform pillar to base graphical applications on, seems to outweigh the negatives.
Thus far, I have managed to not even mention the role frame-buffers play in current Linux kernels. The frame-buffer console system has been a staple of several other UNIX systems for quite some time and several Linux flavors, in particular Linux/m68k and Linux/PPC. The issue on those platforms that made the frame-buffer console so important is a simple one: not all video hardware supports a built-in text-mode. On these systems, the frame-buffer console is not a new luxury which brings up a boot logo, but rather a requirement for functionality. On these systems, the picture is a tad different. They still have X, of course, and X is an excellent way of creating applications in a device-independent fashion. A special X server designed specifically for dealing with frame-buffer systems has nearly always been available. The picture on those systems is also simplified, since no library is available that would enable them to run SVGALib applications.
Under the current implementation, a number of security concerns must be raised when dealing with the graphics subsystem. It is partly because of these security implications that the frame-buffer console has become a part of the Linux 2.2 kernel.
Hardware access to user programs must be provided through a kernel API which provides a layer of device abstraction. To keep the system secure and crash-free, the kernel interface must be carefully designed, as it is within the kernel that the most damage can be done. Access to hardware is dangerous; it would be quite easy to crash the machine if a user program could access it directly. Also, badly designed kernel interfaces could reveal sensitive data about a user, breaches of security, no matter how difficult to exploit, are taken very seriously in the Linux developer community. While no kernel provisions exist for direct hardware access, there are certain workarounds which can be used to circumvent these restrictions—in a way that is as secure as possible.
There are two exceptions to the “no direct access” rule. The first is simple: with programs run by root, the system administrator (who should generally know what she is doing) can access any files and any hardware directly. In fact, there are virtually no limitations as to what root can do. But you certainly don't want your users having the root password and using it each time they want to run Quake, do you? The second exception is the solution to this issue: the owner of a program (generally root) can set a flag called the “setuid bit” (Set User ID) on a program, allowing regular users to “be” the other user as far as the program is concerned. Thus, if root owns the file and it has the setuid bit set, that program will always have root access and therefore will always be able to access hardware directly. In this special and well-controlled case, end users can run their Quake or their X servers despite the fact that they normally wouldn't be able to access the hardware directly.
Note, however, that not all graphical programs will need to be “setuid root” to operate. X programs in particular do not access any hardware directly. Rather, they communicate to the X server via an API which then translates what they want to do onto the video hardware. SVGAlib applications, in contrast, generally all need to have special permissions to operate properly.
The security implications of having an arbitrary program run as root should be obvious. Linux does not currently have a method of saying that a particular program can “just” access any file or “just” access hardware directly—work is progressing in this area. Instead, a “setuid root” application can do anything, including shutting down the server. Talk about a denial of service! Thus, these applications must be very carefully written so that an errant user cannot do anything that would violate the security of the box. It is up to the administrator of the site to maintain and ensure these special programs are used only when absolutely necessary, otherwise gaping security holes will result.
Even a carefully written program can sometimes be cracked via “stack smashing” to gain root access if a programmer does not make sure to watch his buffers and use safer routines like strncpy instead of strcpy. In general, programmers who write “setuid root” applications should be aware of any buffers used throughout the program. For the record, strcpy and strncpy are both functions that copy text data (strings) from place to place in memory. The “n” in strncpy means there is a maximum number of characters to be copied. Otherwise, it would be possible for a cracker to manipulate data in such a way that the data being copied is larger than the place to which it is copied and the excess would overwrite memory. If they are skilled, this excess could include program code which would then be run to break into a shell or do other damage—and it would be executed as root.
Under the hood, Linux 2.2's text mode was designed to be a more modular system with defined interfaces and less of a dependency on VGA hardware internals. The casual observer will not notice either of these improvements. This is the same text mode we have come to love. However, improvements were made to allow better serial consoles for machines without video hardware and to allow for the turning off of virtual consoles, but these features are not expressly part of the text-mode driver.
Frame-buffer devices are the biggest new video feature of Linux 2.2 for i386. Unlike earlier versions of Linux, it is possible through the frame-buffer device to access the video hardware of a machine directly and in a device-independent manner. All the basic graphics primitives are supported, although acceleration is not generally supported at this time. Exactly how accelerated architectures will fit in is still a matter of debate. Some point to user-mode programs and libraries (such as GGI); others believe the best location for at least some types of acceleration is in the kernel. Note that, in contrast to the text-mode driver, there is no character cell display—it is handled elsewhere. SVGAlib applications and, to a lesser extent, X applications can both obtain approximately the same level of control over video hardware, but they are usually less portable and more of a security risk.
In addition to those features, it is now possible to access the frame-buffer devices through the use of device nodes, just like any other device. As an example, these device nodes, /dev/fd*, can be used to get a screen capture simply by doing a standard copy command.
Above the frame buffer is the frame-buffer console (fbcon). This is where the standard vt100+ terminal emulation is implemented. In fact, the emulation is so good that the end user may not even notice the system is in graphical mode. At this level, the kernel has a much larger control over fonts and other features formerly provided through utilities such as SVGATextMode.
Now, all of these features are great, but the major feature that will probably be the reason most Linux users try out the frame-buffer driver is the boot logo. Yes, now you can finally have a cute little picture of Tux carrying a beer whenever you turn on your computer.
Not nearly as many security problems exist under the new system as under the old. Programmers who write graphical applications do not need to be as careful as their legacy counterparts, since they are protected by the user-level security of the kernel. System administrators will also have fewer “setuid root” applications to track, making their security audits easier. In contrast, there will be more code in the kernel that could go awry, and kernel developers will need to keep the new video subsystem as bug-free as the rest of the Linux kernel.
My favorite feature of the new kernel subsystem, if it were to go into wide use, can be summed up in two words: cross-platform compatibility. Simply put, applications written to use the frame buffer will be immediately portable to all Linux platforms. This is in direct contrast to the current SVGALib system which does have some cross-platform compatibility—but only on systems with VGA-like hardware. This will, in theory, make compiling any graphical application on multiple Linux architectures as easy as compiling an application with ncurses is today.
Bear in mind, however, that this argument does not apply to X applications which are already cross-platform. Rather, this level of compatibility would help with X at a somewhat lower level.
Another advantage of having a single level of abstraction for video hardware at the kernel level is with X servers. Unlike older X servers which needed to concentrate on the specific features of a class of video cards, frame-buffer-aware ones can concentrate solely on the networking and other X aspects while allowing the kernel to handle video specifics. In my perfect world, that would allow developers more time to look at X issues rather than video issues. If a developer was still interested in developing video code, he or she could always look to the kernel for something to do.
The X server for the frame buffer is already available as Xfree86-FBDev and has shipped with some distributions.
One of the largest downsides of the new kernel driver system, and the one that has been getting the most attention, is the question of stability. Will these new frame buffers impact the outstanding uptimes of modern Linux? The answer is simply no. One of the glorious things about Linux is that you are generally never forced to do things you don't want and disabling the frame buffer is as easy as a recompile (if the distributions even ship with it by default—something I highly doubt).
It is my opinion that Linux developers reach a higher standard than some other software developers do. (This might explain why I've never gotten anything more than teeny bits into the kernel myself.) Even in a worst-case scenario, a rampant kernel module is only somewhat more dangerous than a rampant “setuid root” X server. People accept that risk daily.
The new driver system has less supported hardware than its legacy counterpart. Additionally, the supported hardware is generally in a sub-optimal or non-accelerated position. In contrast to XFree and to a lesser extent SVGAlib, that is an order of magnitude less support. The video subsystem today is a lot like the sound subsystem was yesterday, i.e., it supports very few cards. With time and patience, developers will no doubt make this new system as robust as possible.
Also, the frame buffer is not meant to be a generic base for an acceleration architecture. While it is likely that better acceleration will be provided in the future, we may have to wait until that becomes generally available. Alternately, it is quite likely that the GGI project (General Graphics Interface at http://www.ggi-project.org/) or some organization will propose and implement a workaround to this situation. Once again, due to the newness of the system, not all answers are immediate.
Red Hat 5.2 (which I use at home and at work) already includes support for the frame-buffer X server, FBDev. If you are experimenting with this feature of Linux 2.2 and have Red Hat, this will save you a download/compile cycle. Unfortunately, at this time there is no easy way to configure this device; I recommend consulting the documentation. Red Hat 6.0 may include this feature or make it easier to use.
To those who want to jump right into the frame-buffer console, an option exists that works with nearly all VGA-compatible video cards: the VesaFB driver. It does require a VESA 2.0-compatible BIOS. This driver is not a good example of what the new features of Linux 2.2 can do, but it does allow one to get her feet wet. In particular, it lacks support for resizing the screen resolution and it requires the mode to be changed at boot time. In reality, this driver is meant only as an example driver and your mileage may vary getting it into production work. Users of Linux on other platforms may have a better idea of how things should be in the end.
Joseph Pranevich (jpranevich@lycos.com) is an avid Linux geek and, while not working for Lycos, enjoys writing (all kinds) and working with a number of open-source projects.