Ever Wonder What Actually Happens When X Starts Up?

I recently installed the shipping version of Red Hat 6.1 onto a bare hard drive. The installation went very well, and I told Linux to install KDE, my preferred desktop, but not GNOME. When I logged in and ran the infamous command to launch into my graphical (X) environment, what greeted me was something I'd never seen before -- KDE running with Enlightenment and using the GNOME panel across the bottom of the screen.

On The Desktop/Gnome
Figure One: Spawn of X: GNOME and KDE desktops are shown here running simultaneously.

I recently installed the shipping version of Red Hat 6.1 onto a bare hard drive. The installation went very well, and I told Linux to install KDE, my preferred desktop, but not GNOME. When I logged in and ran the infamous command to launch into my graphical (X) environment, what greeted me was something I’d never seen before — KDE running with Enlightenment and using the GNOME panel across the bottom of the screen.

After recovering from the disorientation of a deja huh? experience (I never really did figure out exactly what happened there), I realized that it might be a good idea to devote an entire column to the plumbing of an X session and to specifically talk about what happens when you enter startx.

Don’t worry if you use a graphical login screen and never issue startx — I’ll get to you before the end of this column. But for now it’s probably a good idea for everyone to read through at least this much of the labyrinth that is X initialization, to get a flavor for what’s going on and how you can tweak it.

I will revisit this topic in the future and talk about different distributions and components, but for this installment I’ll be focusing on Red Hat 6.1, KDE, and GNOME. If any details of what I mention here are different from your system, chances are that it’s just a minor difference between distributions. But if you run into anything with significant consequences, please feel free to drop me a line about it, and I’ll be sure to cover it in a future column.

The Name’s the Game

Just to make sure we’re on the same page, let me get the terminology straight. As you may know, the X Window System uses a client/server architecture to provide a graphical interface. This can be a little confusing, though, since the part you actually see is the server, and the clients are your individual programs. This is counterintuitive, since people are used to thinking of the client as being nearer to them, and the server as being invisible because it’s off in a closet.

Another terminology issue is what we call all this software that runs between our programs and X itself. I follow the convention of referring to KDE and GNOME as desktop environments, middle components like Enlightenment as window managers (although it’s quickly evolving beyond that role to a full-fledged desktop environment), and X as, well, X.

In the Beginning

When you enter the startx command, you’re running a shell script (as opposed to a binary command) that is /usr/X11R6/bin/startx. startx has the job of finding and using some configuration files and passing your command-line arguments along as needed to the command xinit, which is a binary program and not a script — but that’s getting ahead of the game.

startx first decides which configuration shell scripts to use. It looks for two — one for the client and one for the server. You can override the system scripts by placing your own files in your home directory (/home/login_ name). This is Linux, after all.

If startx can’t find the a client script named .xinitrc in your home directory, it then uses /etc/X11/xinit/ xinitrc. (Note there’s no dot on the system version of this file.) Some references say that the file used is /usr/ lib/X11/xinit/xinitrc, but that’s really the same file, because /usr/lib/X11/ xinit is a symbolic link to /etc/X11/ xinit. (See the section below on real directories versus symbolic links.) xinitrc is your mechanism for starting up programs and performing customization when an X session begins. Think of it as the X equivalent to your normal login profile.

Similarly, startx looks for .xserverrc in your home directory or a system equivalent /etc/X11/xinit/xserverrc (again sans leading dot on the file name). This script can be used to start the X server for your session, but it will default to simply running the command X:0, as explained below. Note that on a stock Red Hat 6.1 system, users don’t normally get individual .xinitrc or .xserverrc files, and at the system level there’s only an xinitrc, and no xserverrc.

OK, so startx does the front-end processing and calls xinit. What now? If xinit doesn’t get a client rc script name as a parameter, it looks in the user’s home directory for one. Since startx has likely passed xinit the name of a client script (whether it’s the user’s custom one or the default system one), xinit will simply use it. xinit will also look for the name of a server script, and if it doesn’t have one, it will default to running the X:0 command mentioned above. This is another twist in our little saga, since X :0 is etc/X11/X, which is really a symbolic link to the graphics-board-specific X server required by your hardware (or a generic frame buffer server). For example, on my system with an ATI Xpert 98 graphics board, /etc/ X11/X is a link to /usr/X11R6/bin/ XF86_Mach64.

If xinit isn’t given the name of a client script and can’t find one, then it fires up a bare X session — meaning without a window manager or desktop environment — and an X terminal window. You can see this rather underwhelming situation by entering just the command xinit from a text-mode command prompt. Using the exit command in the xterm window will shut down the whole X session.

But let’s back up to xinitrc for a second. If you look at the system version of xinitrc, /etc/X11/xinit/xinitrc, you’ll find that around line 84 (in Red Hat 6.1 version) there’s another example of our now familiar “home directory versus system file” processing. This time the code is looking for either the user’s ~/.Xclients or the system /etc/ X11/xinit/Xclients.

By default you don’t have a .Xclients file in your home directory, so you wind up using the system copy. If you look at /etc/X11/xinit/Xclients you’ll find a very curious piece of script code near the beginning (See Listing One).

Listing One: Snippet From /etc/Xll/xinit/Xclients

 # check to see if the user has a preferred desktop
if [ -f /etc/sysconfig/desktop ]; then
if [ -n "'grep -i GNOME /etc/sysconfig/desktop'"
]; then
elif [ -n "'grep -i KDE /etc/sysconfig/desktop'"
]; then
elif [ -n "'grep -i AnotherLevel
/etc/sysconfig/desktop'" ]; then

if [ -n "$PREFERRED" -a "$PREFERRED" !=
"AnotherLevel" ] && \
which $PREFERRED >/dev/null 2>&1; then

This reveals a subtle way you can customize your system. If you create the file that is examined via grep in Listing One (/etc/sysconfig/desktop) and include in it the name of the preferred desktop (GNOME, KDE, or AnotherLevel), then /etc/X11/xinit/Xclients will detect it and follow your wishes.

But /etc/sysconfig/desktop doesn’t exist on a stock Red Hat 6.1 system, either, which means that this code fails to find your setting. That means that control in the script will pass to the piece of code in Listing Two, which comes just after Listing One, in /etc/X11/xinit/Xclients.

Listing Two: Setting the Default Session

 if [ -z "$PREFERRED" ]; then


# by default, we run GNOME.
if which $GSESSION >/dev/null 2>&1; then
exec `which $GSESSION`

# if GNOME isn’t installed, try KDE.
if which $STARTKDE >/dev/null 2>&1; then
exec ‘which $STARTKDE’

As you can see from the script comment, this is where Red Hat 6.1 sets the default X session to be GNOME.

startkde is another shell script, in the directory /usr/bin. It does some housekeeping and makes sure you have certain KDE-specific files in your home directory, by copying system-default copies there if they don’t already exist. It also starts the KDE panel and kfm, KDE’s file manager.

gnome-session is a binary executable, not a script; it also resides in /usr/bin; and it does basically the same chores for GNOME that startkde does for KDE.

Notice that in all of this chaos I never mentioned everyone’s favorite nightmare in X, XF86config, the massive text file that contains the endless lovely details about your graphics hardware and your preferences for screen resolution and color depth that an X server needs to work properly. That would require a chapter-length treatment of its own.

Graphical Logins

Many users, particularly those running one of the newer distributions, don’t ever see the startx command, because they use a graphical login. The magic setting that controls this behavior is the runlevel your system uses when it boots. Runlevel 3 is used for “normal” or traditional multi-user, text-console mode, and 5 indicates all-X session with a graphical login. You can dynamically override your system’s runlevel via the LILO prompt (assuming that you use LILO), or via editing the /etc/inittab file.

At the LILO prompt, you can start at a particular runlevel simply by entering the name of the kernel followed by the numeric level:

 LILO: linux 5

If you’ll always want to use a particular runlevel, or, if you change your mind after you’ve told an installation program which way to set up your system, you can change it by editing your /etc/inittab file. After an initial set of comments, you’ll see a line in that file that looks like:


The 3 is the runlevel, which you can change to 5 to get the graphical login on the next system boot. You’ll still see the screens of text messages as Linux boots, and you’ll even see the text-mode login prompt, but just momentarily before the system flips into graphics mode and presents you with a graphical login prompt. On Red Hat 6.1 this prompt also lets you select between different sessions, including GNOME and KDE, assuming you have both installed, which makes it an even easier way to switch between those two environments at login time.

As for how the graphical login screen gets associated with runlevel 5, look further down in the /etc/inittab file and you’ll find a line that looks like:

 x:5:respawn:/etc/X11/prefdm -nodaemon

This runs prefdm, which initiates the graphical login. prefdm is another interesting side story in our little trip, because prior to Red Hat 6.1 it was a symbolic link that was created at system-boot time. The link was created by the initialization script /etc/rc.d/rc.sysinit, and it pointed to one of several scripts that would start your preferred display manager (kdm and gdm for example). In Red Hat 6.1 prefdm is no longer a link, but is actually a script that initiates the graphical login process. More important, it’s no longer re-created during system boot, so if you delete or rename it, runlevel 5 will lose its graphical login capability.

Under Red Hat 6.1, prefdm has nearly the exact same block of code I showed in Listing One. It’s the code that greps the /etc/sysconfig/desktop file to try to divine your display-manager preference. The difference is that instead of executing an X session via gnome-session or startkde, it starts just a display manager: kdm, gdm, or xdm.

kdm, gdm, and xdm are all binary programs, not scripts. The first two reside in /usr/bin, and the last is in /usr/X11R6/bin.

The $64,000 Question

It’s not hard to find documentation that tells you how to install GNOME or KDE, but there’s very little that tells you how to switch between them once you have both installed. As you’ve probably guessed by now, there’s a quick-and-dirty way to do this. All you have to do is add a .xinitrc file to your home directory that contains just the single line:


With this file in place, the startx command will fire up KDE, and if you delete or rename your .xinitrc file, startx will run GNOME. After a stock installation with both desktop environments installed, Red Hat uses GNOME as the default desktop environment. (You could debate endlessly whether this .xinitrc trick is a blatant hack, a convenient side-effect of the system architecture, or a cool and handy feature; my opinion of it depends entirely on my mood at the time I think about it.)

As for how this works — remember our little discussion above about how the system default xinitrc calls the system Xclients? By setting up your own .xinitrc with the startkde command in your home directory, you’re short-circuiting that entire process and jumping straight to the answer you want, do not grep, do not pass GO.

Who’s on First?

One of the hurdles in learning your way around X is that there are so many files squirreled away in so many directories, and some of those directories are virtual — they’re really symbolic links to other places. On a Red Hat 6.1 system, /etc/X11, /usr/X11R6/lib/X11, and /usr/X11R6/bin are all real directories, while /usr/bin/X11 is a link to /usr/X11R6/bin and /usr/lib/X11 is a link to /usr/X11R6/lib/X11. And, as I mentioned above, /usr/X11R6/bin/ is normally a symbolic link to the X server you’ll actually run, which typically resides in /usr/X11R6/bin/.


By now you’re probably thinking that X is way too complicated for the job it does. For an individual user running a GUI on a personal desktop or laptop computer with just a single physical screen, it is. It’s like using a 35-foot-long motor home to bring a couple of bags of groceries home from the neighborhood Safeway. But X is capable of doing far more than just running a single-screen, single-user desktop GUI. It can support remote operation (server and client on different machines), as well as multiple physical screens per session.

The good news is that it costs you practically nothing in terms of either money or system resources to have that extra capability sitting around unused. It’s a worthwhile tradeoff, since there are those rare times when you need or want to do something a little more exotic with X. But those are topics for other columns.

Coming to Terms with X

Term Definition
/etc/inittab File that sets your system’s runlevel
gnome-session Binary that starts up GNOME
prefdm Script that initiates the graphical login
startkde Script that starts up KDE
startx Unix command to start X from command line
XF86config X’s configuration file
Xinit Fires up X server
.xinitrc Script that stores your X client profile
.xserverrc Script that starts your X server

Lou Grinzo is a technical writer and consultant living in the wilds of upstate NY. He can be reached at lgrinzo@stny.irun.com.

Comments are closed.