Quand les plombs ptent : sjt.

Another Quick How-To for Dual-X-Headed/Legged Linux

A local multi-user linux setup, step by step.

2003 March 14th (updated 2006 February 27th) - Jean-Daniel Pauget - dualh@disjunkt.com


This document intend to describe how I managed to have a PC with:

  •  two different monitors plugged to ...
  •  two different graphic-cards matching ...
  •  two different keyboards and mice

... in order to run ...

  •  two instances of XFree86, each one having it's own login screen, and thus having ...
  •  two different users working on the same one and only one PC box at a time.

Such configurations are often called multiseat linux, multi-seat linux, multiuser X11, or some variations around that theme.

Also, most of this setup can be used in order to produce more than two full featured independent X-servers : users regularly reported 3 and sometime up to 5 or 6 seats, though in my opinion, it might lead to a bunch of wires.

The main problem up to this date (February 2006) is that linux kernel has only one behaviour regarding multiple keyboards : any key pressed catched on any keyboard is redirected to the one and only active Virtual Terminal (VT).

Several solutions were explained on the net, all of them have to patch (and recompile) the kernel to change its behaviour, and also to patch or to download a patched X server so that it would not react the same way any more to Virtual Console changes (when you press CTRL_ALT_F1/F7, for example).

Note (2006/02/27 : don't forget to read the updated appendice and Notes.

Two Users, One Machine.

rss-feed for dual-heading


Two Users, One Machine.

One method : asking or patching the kernel to ignore USB keyboard.

One solution, described here  by Miguel Freitas and with some variant there by Frode Trydal, uses a simple trick : disabling the USB keyboard recognition in the kernel and adding raw-usb decoding to the Xserver in order to handle the events coming from the USB keyboard without listening to the regular kernel-recognised keyboard.

I couldn't apply the first method because I could not get the latest kernel to compile the way described by Miguel Freitas, and my hardware would not work decently with kernel older than 2.4.19. I also discarded the second method, because I understood it would work only on top of framebuffer XServers and my NVidia 4200 is known to have troubles with framebuffers.

Another method (backstreet-ruby patch) : patching the kernel for handling separatly the keyboards.

This method, described here by Vojtech Pavlik, is a patch applied to the kernel that allows the kernel to handle one keyboard with a first set of Virtual Terminals (say VT1 to VT7), and subsequent detected keyboards have the next VTs (VT8-14, then VT15-21 etc...)

You must then patch a little bit the Xserver you intend to use so that it can handle the new behaviour of the VTs. You also have to configure several X servers, one instance for each graphical cards, each configuration will also detail mice/screens matching.

There are several tricks that you must be warned of about the new VT handling :

  1. matching a set of VTs to a keyboard !

    There is no way to choose which keyboard will match which Virtual Terminal, simply the first keyboard detected by the kernel matches the first set of VTs, and so on... (ex: on my configuration, the ps2 keyboard got the first set)

  2. USB keyboard (and others ?) might be "splitted" !

    About USB keyboard, as far as I understand, a single USB keyboard might be internally represented by several keyboards, for example one for the main usual keys, another one for some "multimedia keys" etc... As there are yet no way for the kernel to guess which subsequent detected keyboards are to be matched together, each "part" is assigned a set of VTs.

    As a result, with my configuration, the second set of vt (vt8-15) is probably assigned to some of the dumb "multimedia" fancy keys of my USB keyboard and cannot decently be used. The third set of vt is assigned the regular part of the USB keyboard and is fully usable.

    This leads us to the next trick :

  3. ask for enough set of VTs in order to match every keyboard, even when "splitted" !

    You must assign enough subsequent sets of vt so that in case of "internally splitted" keyboard you can find a set matching a useable part of the related keyboard.

    In short, and for example : on my configuration I have two keyboards, one is ps2 and the other is usb ; I had to ask for 3 sets of VTs in order to have :

    1.  the first set for the ps2
    2.  the second set for the unusual multimedia part of the usb keyboard (so almost unusable)
    3.  the third set is matching the regular part of the usb keyboard and is fully usable.

My Road Book :

here, I detail one after the other all the operations I had to perform on my box.

  1. description before adding anything :

    •  Intel PIV 2,4 GHz
    •  256 Mb memory
    •  ASUS P4PE MotherBoard (intel i845 chipset)
    •  NVidia GeForce 4200Ti AGP 4x graphical card
    •  ps2 keyboard / USB mouse
    •  Debian 3.0 distribution except :
    •  kernel 2.4.20 + ACPI patches + NVidia module, configured by myself
    •  XFree was the binary dist of debian + NVidia modules
  2. adding a new graphical card and checking that it works with XFree4 :

    The AGP slot is of course occupied on my machine, so I have to find a XFree4 supported PCI card. Be careful : for example some old trident worked well with XFree3 and are buggy with XFree4 ! I was offered an "ATI Technologies Inc 3D Rage Pro 215GP" that works fair enough with XFree4 though it's not 3D accelerated yet.

    • I plugged the new ATI, choose in my bios to remain using the AGP VGA bios as primary bios so that the main console was still on the NVidia.
    • boot, the linux is ok, the console and X are running fine on nvidia, and of course nothing happens on the ATI.
    • shut down the nvidia X server, and removed it from the list of default servers in /etc/gdm/gdm.conf
    • backed-up my /etc/X11/XF86Config-4 to /etc/X11/XF86Config-4-NVidia
    • configured an XFree4 for the new ATI (on my debian : dpkg-reconfigure xserve-xfree86)
    • added the new server in gdm's list and relaunched gdm : a nice X is running on the other screen.
    • I neatly copied the new config file to /etc/X11/XF86Config-4-ATI
  3. switching to the backstreet-ruby kernel :

    • downloaded the kernel patch there
    • applied it to my kernel source tree
    • configured it this way (2.4.29-pre3) :
      • in the new or moved "Input device support" section, I checked : [Input core support], [Mouse support], [event interface support], [serial i/o support], [i8042PC Keyb controller]
      • and further the appropriate keyboard and mouse : AT Keyboard, PS2 and serial mouse.
      • in the "Console drivers" I checked [VGA text console] and [DUMB console] and no frame-buffer (unsuportted yet)
      • the USB part is configured normally : I checked [HID layer] [/dev/hiddev raw hid support] plus my other devices (digital camera and so on...)
    • compile, install
    • I add some append option in the new entry in my lilo.conf in order to get enough sets of VTs
    • when I reboot , the last X isn't ok, I had to create some new devices as explained there and to tell my X to use the appropriate new mouse device.
      cd /dev
      mkdir old
      mv mouse js? old
      mkdir input
      cd input
      mknod js0 c 13 0
      mknod js1 c 13 1
      mknod js2 c 13 2
      mknod js3 c 13 3
      mknod mouse0 c 13 32
      mknod mouse1 c 13 33
      mknod mouse2 c 13 34
      mknod mouse3 c 13 35
      mknod mice c 13 63
      mknod event0 c 13 64
      mknod event1 c 13 65
      mknod event2 c 13 66
      mknod event3 c 13 67
      cd ..
      ln -s input/js0 js0
      ln -s input/js1 js1
      ln -s input/mice mouse
  4. switching to the patched XFree4 and configuring for 2 running instances of X :

    Note (2005-06-01) :
    • I recently (may 2005) switched my dual-headed-legged machine from debian-woody to debian-sarge - Yes, I'm really a dinosaurus.

      Sarge is hopefully shipped with a pre-patched XFree-4.3.x Server !

      You don't need to build one from scratch anymore, nor you don't need to manually upgrade the XServer by yourself for each new security alert : you now can rely on debian peoples for that.

    • People who use Sarge may almost completly skip this step (though it might still be usefull for using both an ATI and a nVidia card on the same machine...

    • Aivils Stoss recently said that the Xorg server shipped with Ubuntu might also perfectly do the trick. Though I haven't tested-it myself, I think it's worth testing if someone is installing on a brand new empty machine !

    Note (2004-07-14) :
    • Aivils Stoss told me that his page describes a patch so that it may be possible to simply ask the kernel to filter some unwished XFree86 PCI steering commands by echoing 1 to /proc/bus/pci/hackvideo :

      echo 1 > /proc/bus/pci/hackvideo

      Then to add a server flag option in the XF86Config-4 file :

      Section "ServerFlags"
      Option "PciOsConfig" "1"

      There may be some drawback, such has machine-freeze at quiting X, and because there were, this isn't the solution I'm using yet !

    • Aivils also told me that pre-compiled patched server are available around his page, for those who don't want to build everything.

    • I downloaded from XFree's cvs the complete xc tree
    • patched it from there
    • configured my xc/config/cf/site.def so that it would fully install in
      ProjectRoot /usr/local/X11R6_1
      the previous point is rather important because ATI and NVidia don't share the same 3D rendering libraries...
    • build (make World) and installed.
    • I performed a second build in another ProjectRoot /usr/local/X11R6_2 for the other card
    • added th NVidia extension in one of the X11R6 installation tree
    • corrected my /etc/gdm/gdm.conf by ending it this way :
      name=Standard server
      command=/usr/bin/X11/X -deferglyphs 16
      name=server /usr/local/X11R6
      command=/etc/X11/LocX1 -deferglyphs 16
      name=server /usr/local/X11R6_2
      command=/etc/X11/LocX2 -deferglyphs 16
      0=locX2 vt7
      1=locX vt14
    • wrote two scripts for launching the proper X servers with proper libraries this way :
      content of /etc/X11/LocX1 :
      set BASE=/usr/local/X11R6_1
      setenv LD_LIBRARY_PATH "${BASE}"/lib
      exec "${BASE}"/bin/X -xf86config /etc/X11/XF86Config-4-ATI $*
      content of /etc/X11/LocX2 :
      set BASE=/usr/local/X11R6_2
      setenv LD_LIBRARY_PATH "${BASE}"/lib
      exec "${BASE}"/bin/X -xf86config /etc/X11/XF86Config-4-NVidia $*
  5. description after installation :

    • Intel PIV 2,4 GHz
    • 256 Mb memory
    • ASUS P4PE MotherBoard (intel i845 chipset)
    • NVidia GeForce 4200Ti AGP 4x graphical card matching
    • ps2 keyboard / 1st USB mouse
    • ATI Technologies Inc 3D Rage Pro PCI graphical card matching
    • USB keyboard / 2nd USB mouse
    • Debian 3.0 distribution except :
    • kernel 2.4.20 + ACPI patches + NVidia module, configured by myself 
    • kept the binary dist from debian for XFree in the main /usr/X11R6 tree for system compatibility and backup (+ NVidia modules)
    • one additional install tree of X11R6 from XFree4.3.0 cvs tree + backstreetruby patch
    • another additional install tree of X11R6 from XFree4.3.0 cvs tree + backstreetruby patch + NVidia library
    • tuned gdm.conf
  6. small final corrections :

    Apart from creating to X11R6 trees as described above, my installation doesn't differ that much from Vojtech Pavlik description. But I encountered several minor drawbacks :

    my logitech mouse that was working perfectly, including the wheel, as a ps2 mouse lost it's wheel capability after the operation. I simply had to use it as a USB mouse to get the wheel back, go figure ?

    On both keyboards (french layout), one key was lost in the process  I had to use xmodmap to give it back its associated symbols with this trick - there is probably something better to do :

    content of .Xmodmap file in user's home (for handling missing '<'/'>'keys)

    keycode 94=60 62

The result :

The machine now boots like in a dream up to the two running Xservers with their corresponding loging pages.

The sessions of both cards work fully, even at logging out and back in several times.

As a result the machine is fully usable by two people simultaneously. Linux stability permits us to work several days without any single reboot, even playing a lot with multimedia, ieee1394, dvgrabbing, openGL and so on...

Two years later, several kernel upgrades later...

A decent linux-box's life involves regular kernel upgrades ; at least from time to time in consideration with security issues, and also because of much more numerous enhanced hardware support. Peoples have been actively updating kernel patches up to date in regard with linux 2.4.x and 2.6.x trees until now (2005 December 29th), and those days my machine is now running with kernel 2.4.33-pre2 and this patch.

Only one main change occured : now the kernel outputs each additionnal virtual console with its number, that is convenient for setting the proper -vt xx option for each running instance of Xserver. THe numbering scheme also changed, but no guessing is needed anymore since the appropriate vc numbers are displayed and available via dmesg.

At last, I also got rid of the 3D rage and added a PCI GeForce4 MX440 64Mb, it's now working great with only one X11 patched-tree for both cards since they share the same driver.

My future plans, on the hardware side, are to add another nvidia PCI, probably a 9525 128Mb

On software side, in a seek for low latency, I tried 2.6.x kernels, and could not get a stable dual head yet. On the other side, the low-latency patch for 2.4.x combined with backstreet-ruby is giving good results, I'll probably put a merged patch on this page some day.

References / Links :

rss-feed for dual-heading

Author : Jean-Daniel Pauget has been supporting all kind of weirdness with free software against hardware for a long time !
Quand les plombs ptent : sjt.