portrait

Поиск



[software] [catdoc] [tcl] [geography] [old things]

Создание бездискового X-терминала с помощью Debian etch

В состав Debian etch входят пакеты ltsp-server и ltsp-utils, специально предназначенные для создания тонких клиентов. Но мне что-то получившаяся "тонкость" не понравилась.

Поэтому я пошел другим путем

Сначала я честно попытался воспользоваться debootstrap, но как выяснилось, зависимости у требуемых для X-терминала пакетов такие, что ой. Получится не меньше, чем у ltsp.

А мне в итоге удалось уложиться в 28Мб. Тоже много, но уже если захочется, можно вместо сетевой загрузки ненужную 32Мб CF-ку на IDE прицепить.

Постановка задачи

Имеется система, содержащая видеокарту, сетевую карту с PXE-bootrom, звуковую карту, флоповод и немножко памяти (у меня - 64 мб). Хочется чтобы эта штука превратилась в полноценное рабочее место, где можно работать с приложениями, в том числе и работающими со звуком, читать дискеты и USB-флэшки.

Для этого нам нужно чтобы на этой системе запустились X-сервер, nasd (желающие могут разработать вариант с PulseAudio или esd), и два floppyd - один на дисковод, другой на устройство /dev/sda1.

Последовательность действий:

Сначала собираем ядро с помощью kernel-package. В пакет. Ядро собираем без initrd, со всеми нужными модулями сетевых карт и поддержкой NFS-root внутри. В смысле NFS-клиент не должен быть модулем. Иначе NFS-root не включится.

Звук и поддержку USB можно модулями. USB нам нужна ради usb-storage, чтобы можно было втыкать флэшки в терминал и их читать с помощью mtools. Кроме того, может оказаться полезным использовать внешнюю USB-аудиокарту

Берем набор следующий пакетов (некоторые зависимости будут неудовлетворены, но для нужной нам функциональности хватит)

libc6
busybox
modutils (это если с ядром 2.4. Если 2.6, то module-init-tools)
libwrap0
portmap
nfs-common
x11-common
libxt6
libice6
libsm6
libx11-6
libaudio2
libxau6
nas
floppyd
libfontenc1
libgcc1
libxfont1
zlib1g
libfreetype6
xserver-xorg-core
xserver-xorg-video-ati (это у меня ati. У вас может быть другое. В
принципе, installed-size у драйверов маленький, можете хоть все
засобачить)
xserver-xorg-input-kbd
xserver-xorg-input-mouse
xserver-xorg-input-evdev

Выбираем некоторую директорию (у меня /var/diskless), откуда это дело будет раздаваться по NFS.

Распаковываем туда перечисленынные пакеты c помощью

dpkg-deb -х пакет директория

Никакие postinst скрипты не выполняются, но в данном случае нетривиальных postinst-скриптов и нет. Вместо этого делаем следующее

# chroot /var/diskless /bin/busybox sh
/ #  mount -t proc none /proc
/ #  busybox --install
/ #  ldconfig
/ #  exit

Вы, наверное, удивитесь: "А где же пакет xkb-data". А нету. Мы будем запускать xkbcomp с хоста, при логине из .xsession. Таким образом у каждого юзера может быть собственная раскладка клавиатуры.

Теперь надо дополнительно создать файл /var/diskless/etc/X11/Xwrapper.config (я не мудрствуя лукаво скопировал его с хоста), создать симлинк /var/diskless/etc/X11/X, ведущий на /usr/bin/Xorg (ага, именно со слэшом вначале). Большие эстеты могут создавать его зайдя в chroot и запустив там busybox-овский шелл, но я и так обошелся, создать директории /dev /tmp и /var/log и населить dev соответствующими специальными файлами. У меня там
audio    dsp0  mem     port    sda1   sda13  sda3  sda7  tty1  tty5
audio0   fd0   mixer   psaux   sda10  sda14  sda4  sda8  tty2  tty6
console  full  mixer0  random  sda11  sda15  sda5  sda9  tty3  urandom
dsp      kmem  null    sda     sda12  sda2   sda6  tty0  tty4  zero

В принципе, часть tty можно поотрывать, да и разделы sda кроме sda1 не нужны.

Кладем xorg.conf в /etc/X11 (у него должен быть единственный элемент font-path, указывающий на фонт-сервер) и имеем практически готовую систему, за исключением init.

Если у нас несколько терминалов, которым нужны разные конфигурации x-ов, то описываем в xorg.conf несколько секций ServerLayout с идентификаторами, соответствущими именам хостов (которые будут потом розданы по dhcp как option host-name).

Вместо init кладем шелловский скрипт следующего содержания:

#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
respawn() {
    (while true; do
        $1
        sleep 5
    done)  &
}
echo -n loading modules
for i in usbcore uhci usb-storage opl3sa2; do
    modprobe $i && echo -n " $i"
done
echo "."
echo starting portmapper
/sbin/portmap -v -d &
/sbin/rpc.statd
/sbin/rpc.lockd
echo mounting all filesystems
mount /proc
mount /proc/bus/usb
mount -t ramfs none /tmp
chmod 1777 /tmp

echo -n starting floppyd
floppyd -r root -d /dev/fd0&& echo -n " floppy" 
floppyd -r root -s 5704 /dev/sda1&& echo -n " flash"
echo .

HOSTNAME=`hostname` dmesg > /var/log/dmesg.$hostname.log respawn "nasd -aa"
respawn "X -query wagner.wagner.home -logfile /var/log/Xorg.$HOSTNAME.log -layout $HOSTNAME"
wait
Теперь получившуюся директорию надо раздать по NFS с опциями rw,no_root_squash и можно настраивать собственно загрузку.

Настройка X-ов

Как можно было заметить выше, X-серверу на терминале передается опция "-layout $HOSTNAME", позволяющая задать свою конфигурацию X-ов для каждого терминала.

Соответственно, в /var/diskless/etc/X11/xorg.conf должна присутствовать секция ServerLayout с идентификатором, соответствующем имени терминала.

Section "ServerLayout"
	Identifier "xterm5"
	Screen "xterm5-screen"
	InputDevice "Generic Keyboard"
	InputDevice "USB Mouse"
EndSection
и соответствующая секция Screen
Section "Screen"
	Identifier "xterm5-screen"
	Device "FoxConOnboard"
	Monitor "Roverscan"
	DefaultDepth 16
	...

Настройрка загрузки

Ставим на хост пакеты syslinux, dhcp3-server и tftp-hpa. В командную строку tftp-hpa нужно добавить опцию -r blksize, потому что у некоторых PXEboot ROM проблемы с этой опцией.

/usr/lib/pxelinux.0 и ядро из /var/diskless/boot копируем в /var/lib/tftpboot.

Создаем директорию /var/lib/ftpboot/pxelinux.cfg и помещаем туда файл default следующего содержания:

DEFAULT term root=/dev/nfs ip=dhcp rw
LABEL term
KERNEL vmlinuz-2.4.27-terminals

pxelinux позволяет искать конфигурационный файл по IP-адресу или mac-адресу, а через этот файл можно (в виде непонимаемых ядром опций командной строки, которые потом можно скриптом извлечь из /proc/cmdline) передать много такого, что не вписывается в DHCP. Но у меня пока в этом необходимости не возникло.

Сделать ядро, которое грузится нормально на терминалах с очень разным железом - вполне реально, а все последующее можно сконфигурировать из init-скрипта опираясь на hostname.

В dhcpd.conf пишем раздел host для терминала. (если терминалов много, можно написать один раздел group, но это уж читайте документацию на pxelinux и dhcpd сами)

      host xterm3 {
         hardware ethernet xx:xx:xx:xx:xx:xx;
         fixed-address 192.168.217.5;
         option host-name "xterm3";
         next-server 192.168.217.1;
        option domain-name "wagner.home";
         filename "pxelinux.0";
        option root-path "/var/diskless";

      }

Главное, не забыть команду next-server, потому что если PXE BootRom прекрасно обходится без неё, то pxelinux почему-то начинает тащить свой файл конфигурации и ядро с адреса 0.0.0.0.

Теперь ставим xfs, отрываем у него из конфига no-listen = tcp, и разрешаем обслуживание терминалов в display manager. В xdm для этого необходимо закоментарить строчку

DisplayManager.requestPort: 0 
в xdm-config и раскоментарить строчку
* # any host can get a login window
в Xaccess.

Готово, можно грузиться.

TBD

Научиться получать aдрес фонт-сервера и адрес хоста, передаваемого в опцию query по dhcp (опции font-server и x-display-manager)

Для этого надо пересобрать busybox включив там встроенный dhcp-клиент, и немного попатчить этот клиент, поскольку эти опции он из коробки не умеет.