October 5, 2003

Dual-Heading My Debian Box

Author: JT Smith

- by Kent West -

I had heard about having two monitors connected to one PC some time
ago. I had actually seen it on a Macintosh about 10 years ago. I was
quite impressed. More recently I saw a dual-headed Linux setup in the student worklab at
the university where I work. Okay, it's time for me to give it a try.

At home I've got an Athlon XP1700+ system running Debian Unstable. It's
got an S3 Virge PCI video card in it; not great, but adequate for my
little 15" Compudta-branded screen. By rummaging/borrowing, I came up
with a second 15" screen of a Sony Trinitron flavor, and a second video
card, an ATI Rage128 AGP.

So I put the ATI card in the AGP slot, connected the second monitor to
the AGP card (leaving the first monitor connected to the S3 the way it
had been), and fired up the computer. I wasn't sure what to expect, but
all I got was a normal system on the first monitor; the power button on
the second monitor stayed orange/yellow, indicating it was not getting
a signal.

I wondered how the system (even before the kernel starts to load)
decided which monitor to use, and I decided it must be a BIOS setting.
So I rebooted and went into the BIOS. On my BIOS, I found a setting for
"Init Video Device on Boot" or something similar (I'm running my box
currently; I'm not going to reboot just to get the details accurate)
that had a PCI and an AGP setting. I changed the setting from PCI to
AGP and rebooted. Wow; the boot messages showed up on the second
card/monitor now! Cool! (I have no idea how to tell the BIOS which card
to use if I had had two PCI cards; perhaps there was an option in there
that I just didn't get around to finding.)

Then when X started, it started on the first card/monitor, and the
second card/monitor on which I had just booted went blank. Once in X, I
tried Ctrl-Alt-F1, and just as expected, the second c/m came back to
life allowing me to log into the first VT; the first c/m went "nuts
with color", until I hit Alt-F7, which restored that c/m and caused the
second c/m to go blank again. I toggled back and forth a few times just
to make sure it was really working. Cool.

Then I ran "dpkg-reconfigure xserver-xfree86" and selected the ATI r128
driver and restarted X. Now the first card/monitor remained "dead", and
both the console VT and X worked as expected on the second c/m.

All that was left now to do was to get both monitors working at the
same time in X. Turns out that it was a lot simpler to do than I would
have expected. It's all controlled by the "/etc/X11/XF86Config-4" file
and the magic "Xinerama" extension.

My original "/etc/X11/XF86Config-4" file had these sections:

Section "Device"
    Identifier "S3 Virge"
    Driver "s3virge"
EndSection

Section "Monitor"
    Identifier "Generic Monitor"
    HorizSync 28-50
    VertRefresh 43-75
    Option "DPMS"
EndSection

Section "Screen"
    Identifier "Default Screen"
    Device "S3 Virge"
    Monitor "Generic Monitor"
    DefaultDepth 15
    SubSection "Display"
        Depth 15
        Modes "1152x864" "1024x768"
"800x600"
    EndSubSection
EndSection

Section "ServerLayout"
    Identifier "Default Layout"
    Screen "Default Screen"
    InputDevice "Generic Keyboard"
    InputDevice "Configured Mouse"
EndSection

Notice that there's a section that defines a name for the S3virge card,
and a section that defines a name and options for the monitor, and a
section that defines what the resolution and color depth will be, and a
final section that puts it all together.

I changed the section defining the video card to this:

Section "Device"
    Identifier "S3 Virge"
    Driver "s3virge"
    BusID "PCI:0:12:0"
EndSection

Notice the only thing I added was the BusID; the bus id is normally
optional for a single-head machine, but according to "man
XF86Config-4", it's mandatory for a dual-head box. I got the id from
the output of the "lspci" command, which looks like this:

westk03[westk]:/home/westk> lspci
00:00.0 Host bridge: VIA
Technologies, Inc. VT8366/A/7 [Apollo KT266/A/333]
00:01.0 PCI bridge: VIA Technologies,
Inc. VT8366/A/7 [Apollo KT266/A/333 AGP]
00:0b.0 Ethernet controller: Lite-On
Communications Inc LNE100TX (rev 20)
00:0c.0 VGA compatible controller: S3
Inc. 86c325 [ViRGE] (rev 06)
00:11.0 ISA bridge: VIA Technologies,
Inc. VT8233 PCI to ISA Bridge
00:11.1 IDE interface: VIA
Technologies, Inc. VT82C586/B/686A/B PIPC Bus Master IDE (rev 06)
00:11.2 USB Controller: VIA
Technologies, Inc. USB (rev 1b)
00:11.3 USB Controller: VIA
Technologies, Inc. USB (rev 1b)
00:11.4 USB Controller: VIA
Technologies, Inc. USB (rev 1b)
00:11.5 Multimedia audio controller:
VIA Technologies, Inc. VT8233 AC97 Audio Controller (rev 30)
01:00.0 VGA compatible controller:
ATI Technologies Inc Rage 128 RL/VR AGP

Notice that the line we're interested in is the one mentioning the S3:
    00:0c.0 VGA compatible controller: S3 Inc.
86c325 [ViRGE] (rev 06)

and it's the 00:0c.0 part that
we're interested in. This number is in hex, and it converts to PCI:0:12:0 in XF86Config-4/decimal
format.

Now in order to keep things clear in my mind, I decided to change the
names of some of the data in XF86Config-4. The "Monitor" and "Screen"
sections became this:

Section "Monitor"
    Identifier "CompuData Monitor"
    HorizSync 28-50
    VertRefresh 43-75
    Option "DPMS"
EndSection

Section "Screen"
    Identifier "Screen 1"
    Device "S3 Virge"
    Monitor "CompuData Monitor"
    DefaultDepth 15
    SubSection "Display"
        Depth 15
        Modes "1152x864" "1024x768"
"800x600"
    EndSubSection
EndSection

Because I changed the names in the two sections above, I also had to
change the names of their references in the "ServerLayout" section:

Section "ServerLayout"
    Identifier "Default Layout"
    Screen "Screen 1"
    InputDevice "Generic Keyboard"
    InputDevice "Configured Mouse"
EndSection

Okay, other than adding the BusID, I didn't really change anything; I
just changed some names to make it easier to track what's going on.

Now I add in the section for the second, ATI video card/Sony monitor.
Don't change any of the above sections; just add the new sections:

Section "Device"
    Identifier "ATI Rage 128"
    Driver "ati"
    BusID "PCI:1:0:0"
EndSection

Section "Device"
    Identifier "S3 Virge"
    Driver "s3virge"
    BusID "PCI:0:12:0"
EndSection

Section "Monitor"
    Identifier "Sony Trinitron"
    HorizSync 28-50
    VertRefresh 43-75
    Option "DPMS"
EndSection

Section "Monitor"
    Identifier "CompuData"
    HorizSync 28-50
    VertRefresh 43-75
    Option "DPMS"
EndSection

Section "Screen"
    Identifier "Screen 2"
    Device "ATI Rage 128"
    Monitor "Sony Trinitron"
    DefaultDepth 15
    SubSection "Display"
        Depth 15
        Modes "1152x864" "1024x768"
"800x600"
    EndSubSection
EndSection

Section "Screen"
    Identifier "Screen 1"
    Device "S3 Virge"
    Monitor "CompuData"
    DefaultDepth 15
    SubSection "Display"
        Depth 15
        Modes "1152x864" "1024x768"
"800x600"
    EndSubSection
EndSection

And finally, the following changes to the "ServerLayout" section make
all the difference:

Section "ServerLayout"
    Identifier "DualHead"
    Screen "Screen 1" LeftOf "Screen 2"
    Screen "Screen 2"
    Option "Xinerama"
    InputDevice "Generic Keyboard"
    InputDevice "Configured Mouse"
EndSection

Then I restarted X, and lo and behold, it works! Way cool! The
Identifier could be "TwoHeadedBeastie" if you desired, and the relative
location can not only be "LeftOf", it can also be "RightOf", "Above",
"Below", or "Relative". Lots of fun.

Give it a try; it helps you to learn some of the secrets of
XF86Config-4, and results in a neat show-and-tell system.

Click Here!