MultiHeads no Linux
A idéia é simples, colocar várias placas de vídeo, vários teclados e vários mouses num mesmo computador de forma que diversos usuários usem-o simultaneamente e independentemente a mesma CPU. Solução barata e muito na moda ultimamente.
Parte 3: Começando a por a mão na massa
Dentre os problemas que envolvem os multiheads, existem
alguns realmente chatos. As placas não são projetadas pra funcionar
de forma independente. Uma placa sempre derruba a outra, às vezes
aparecem caracteres estranhos em uma delas e a tela misteriosamente
começa a rodar com um simples mount ou swapon.
Por exemplo, uma interrupção pode ser "entendida" por todas elas. Isto acontece com a int 10. Quando a placa é inicializada. Porém simplesmente tirando a interrupção 10 faz com que as placas secundárias não tenham memória suficiente para inicializar (sem modos de tela válidos).
Mas calma, não é o fim do mundo. Para isso dá-se um jeito, colocando um script simples no boot que chamaremos de "Xorg-multiterminal". Ele só inicializará as placas sem a interrupção 10 pra que depois elas sejam usadas.
Mas primeiro vamos configurar o xorg.conf, edite o /etc/X11/xorg.conf mais ou menos com a seguinte configuração, mudando os endereços pelo qual você anotou:
Por exemplo, uma interrupção pode ser "entendida" por todas elas. Isto acontece com a int 10. Quando a placa é inicializada. Porém simplesmente tirando a interrupção 10 faz com que as placas secundárias não tenham memória suficiente para inicializar (sem modos de tela válidos).
Mas calma, não é o fim do mundo. Para isso dá-se um jeito, colocando um script simples no boot que chamaremos de "Xorg-multiterminal". Ele só inicializará as placas sem a interrupção 10 pra que depois elas sejam usadas.
Mas primeiro vamos configurar o xorg.conf, edite o /etc/X11/xorg.conf mais ou menos com a seguinte configuração, mudando os endereços pelo qual você anotou:
....
Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
Option "Protocol" "evdev"
Option "Dev Phys" "isa0060/serio0/input0"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"
Option "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Keyboard1"
Driver "kbd"
Option "Protocol" "evdev"
Option "Dev Phys" "usb-0000:00:03.0-1/input0"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"
Option "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Keyboard2"
Driver "kbd"
Option "Protocol" "evdev"
Option "Dev Phys" "usb-0000:00:03.0-2/input0"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"
Option "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Mouse1"
Driver "mouse"
Option "Protocol" "evdev"
Option "Dev Phys" "usb-0000:00:03.2-1/input1"
Option "CorePointer"
Option "ZAxisMapping" "4 5"
EndSection
Section "Device"
Identifier "Device0"
Driver "sis"
BusID "PCI:1:0:0"
Option "NoInt10" "Yes"
Option "RestoreBySetMode" "no"
EndSection
Section "Device"
Identifier "Device1"
Driver "ati"
BusID "PCI:0:9:0"
Option "NoInt10" "Yes"
Option "RestoreBySetMode" "no"
EndSection
Section "ServerLayout"
Identifier "Layout0"
Screen "Screen0"
InputDevice "Keyboard0"
InputDevice "Mouse0"
Option "SingleCard"
EndSection
Section "ServerLayout"
Identifier "Layout1"
Screen "Screen1"
InputDevice "Keyboard1"
InputDevice "Mouse1"
Option "SingleCard"
Option "DontZap" "on"
EndSection
Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
Option "Protocol" "evdev"
Option "Dev Phys" "isa0060/serio0/input0"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"
Option "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Keyboard1"
Driver "kbd"
Option "Protocol" "evdev"
Option "Dev Phys" "usb-0000:00:03.0-1/input0"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"
Option "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Keyboard2"
Driver "kbd"
Option "Protocol" "evdev"
Option "Dev Phys" "usb-0000:00:03.0-2/input0"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"
Option "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Mouse1"
Driver "mouse"
Option "Protocol" "evdev"
Option "Dev Phys" "usb-0000:00:03.2-1/input1"
Option "CorePointer"
Option "ZAxisMapping" "4 5"
EndSection
Section "Device"
Identifier "Device0"
Driver "sis"
BusID "PCI:1:0:0"
Option "NoInt10" "Yes"
Option "RestoreBySetMode" "no"
EndSection
Section "Device"
Identifier "Device1"
Driver "ati"
BusID "PCI:0:9:0"
Option "NoInt10" "Yes"
Option "RestoreBySetMode" "no"
EndSection
Section "ServerLayout"
Identifier "Layout0"
Screen "Screen0"
InputDevice "Keyboard0"
InputDevice "Mouse0"
Option "SingleCard"
EndSection
Section "ServerLayout"
Identifier "Layout1"
Screen "Screen1"
InputDevice "Keyboard1"
InputDevice "Mouse1"
Option "SingleCard"
Option "DontZap" "on"
EndSection
Aqui omiti várias informações, porém o principal ainda se encontra aí. Interessante também é desabilitar a aceleração 3D, já que não vai ser necessário mesmo, coloque Option "NoAccel" em cada device. A opção Dontzap no layout impede que o usuário feche o X com Ctrl+Alt+Backspace. Isso faz com que todos os usuários caiam. Atenção! o BusID usa endereços em decimal.. então converta a =10, b=11, c=12...
Outra coisa muito importante é o driver evdev (event devices), ele é o responsável pela separação dos dispositivos em distros como Mandriva e evdev não vem compilado no Xorg. Infelizmente você vai ter que compilar e o trabalho vai durar semanas. Outra solução é usar o /dev/input ao invés do endereço físico, mas sua distro deve suportar os protocolos.
Agora precisamos configurar o "Xorgmultiterminal" no boot. Pra isso crie um arquivo "xorg.conf.probe", que será baseado no xorg.conf. Ele habilita as placas no boot. Então crie o /etc/X11/xorg.conf.probe começando já da placa secundária:
Section "Device"
Identifier "Device1"
Driver "ati"
Screen 0
BusID "PCI:0:9:0"
Option "NoInt10" "no"
Option "NoAccel"
Option "RestoreBySetMode" "no"
EndSection
.....
Section "ServerLayout"
Identifier "probe"
Screen "Screen1"
Screen "Screen2" LeftOf "Screen1"
Screen "Screen3" LeftOf "Screen2"
InputDevice "Keyboard1"
InputDevice "Mouse1"
EndSection
Identifier "Device1"
Driver "ati"
Screen 0
BusID "PCI:0:9:0"
Option "NoInt10" "no"
Option "NoAccel"
Option "RestoreBySetMode" "no"
EndSection
.....
Section "ServerLayout"
Identifier "probe"
Screen "Screen1"
Screen "Screen2" LeftOf "Screen1"
Screen "Screen3" LeftOf "Screen2"
InputDevice "Keyboard1"
InputDevice "Mouse1"
EndSection
A ordem das telas não importa. Note que só são inicializadas as placas secundárias. E a interrupção 10 está como "NO".
Agora precisamos colocar na inicialização. Crie um script /etc/init.d/xorgmultiterminal com a seguinte linha de comando:
[[ -f "/etc/X11/xorg.conf.probe" ]] && /usr/X11R6/bin/X -config /etc/X11/xorg.conf.probe -probeonly
Agora descubra qual runlevel corresponde ao modo multi-usuário com X11 na sua distro dando um cat no /etc/inittab.
Vamos supor que seja o Debian, que é 3. Então entre em /etc/rc3.d e crie um link simbólico com:
$ ln -s /etc/init.d/xorgmultiterminal S80xorgmultiterminal
O número 80 corresponde a prioridade que esse script tem no boot. Quando você parar o X, execute sempre ele novamente na mão pra não precisar reiniciar. Por exemplo:
$ /etc/init.d/gdm stop
$ /etc/init.d/xorgmultiterminal
.......
$ /etc/init.d/gdm start
muito legal mesmo, tá de parabéns...