Bindeglieder
Experimentelle DVB-Treiber einbinden
Treiberabhängigkeiten
Der Befehlsblock von Zeile 68 bis 78 übernimmt das Laden der Module. Eine Besonderheit stellt die Schleife von Zeile 72 bis 75 dar: Sie löst auf, welche Treiber zusätzlich benötigt werden, damit sich ein bestimmtes Kernel-Modul überhaupt laden lässt. Dazu benutzt das Skript die Datei modules.dep, die der Befehl depmod -a generiert und auch modprobe auswertet.
Jede Zeile der beginnt modules.dep beginnt mit dem Dateipfad und dem Namen des Treibers, gefolgt von einem Doppelpunkt und einer Liste von Kernel-Modulen, von denen das Modul abhängt. Nach dem Laden des Treiber in Zeile 77 per modprobe arbeitet das Programm die Treiberliste von hinten nach vorn ab und bindet ein Modul nach dem anderen ein, bis es schließlich den ursprünglich gewünschten Treiber als letztes lädt.
Zeile 76 sorgt dafür, dass sämtliche Module in umgekehrter Ladereihenfolge in der Variablen DvbModules eingetragen sind, die Zeilen 83 bis 85 speichern diese Reihenfolge dann in der Datei /var/run/dvbdriver.modules. Diese Notation macht es später leichter, die Module per modprobe -r nacheinander wieder zu entladen – fängt man am falschen Ende der Liste an, lassen sich die Module nicht entladen, da sie noch verwendet werden.
Prinzipiell kann modprobe -r die abhängigen Module auch selbst entladen, sodass das Auflösen der abhängigen Module in den Zeilen 72 bis 75 überflüssig wäre. Dies gilt jedoch nur für den Idealfall – braucht etwa ein Treiber etwas länger, um hinter sich aufzuräumen, blockiert er unter Umständen das Entladen anderer, abhängige Module. Ein erneutes modprobe -r würde jedoch scheitern, da das obenliegende Modul bereits entfernt wurde – die abhängigen Module blieben im Kernel. Mit einer Liste der abhängigen Module jedoch lassen sich durch den erneuten Aufruf von dvbdriver stop die noch verbliebenen Treiber entladen. Dies übernehmen die Zeilen 92 bis 94.
DVB-Empfangskarten
| Bezeichnung | Typ | Vendor-ID | Product-ID | Sub-Vendor-ID | Sub-Device-ID | Class-ID |
| CTX917 | DVB-T Budget | 0x1131 | 0x7134 | 0x16be | 0x0030 | 0x0480 |
| Hauppauge Nexus-CA Rev. 1.1 | DVB-C Premium | 0x1131 | 0x7146 | 0x13c2 | 0x000a | 0x0480 |
| Hauppauge Nexus-s Rev. 2.1 | DVB-S Premium | 0x1131 | 0x7146 | 0x13c2 | 0x0003 | 0x0480 |
| Hauppauge Nova-T 90002 | DVB-T Budget | 0x14f1 | 0x8800, 0x8802, 0x8804 | 0x0070 | 0x9002 | 0x0400, 0x0480 |
| Hauppauge Nova-T | DVB-T Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1011 | 0x0480 |
| Technotrend DVB-S Budget CI | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x100f | 0x0480 |
| Technotrend DVB-S Budget CI Rev. 1.0 | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1017 | 0x0480 |
| Technotrend DVB-S Budget Rev. 1.0 | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x100f | 0x0480 |
| Technotrend DVB-S Budget Rev. 1.1 | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1003 | 0x0480 |
| Technotrend DVB-S Budget Rev. 1.4 | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1016 | 0x0480 |
| Technotrend DVB-S1400 Budget | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1016 | 0x0480 |
| Technotrend DVB-S1401 Budget | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1018 | 0x0480 |
| Technotrend DVB-S1500 Budget CI | DVB-S Budget | 0x1131 | 0x7146 | 0x13c2 | 0x1017 | 0x0480 |
| Technotrend DVB-S Premium Rev. 1.3 | DVB-S Premium | 0x1131 | 0x7146 | 0x13c2 | 0x0000 | 0x0480 |
| Technotrend DVB-S Premium Rev. 1.5 | DVB-S Premium | 0x1131 | 0x7146 | 0x13c2 | 0x0000 | 0x0480 |
| Technotrend DVB-S Premium Rev. 1.6 | DVB-S Premium | 0x1131 | 0x7146 | 0x13c2 | 0x0000 | 0x0480 |
| Technotrend DVB-S2300 Premium | DVB-S Premium | 0x1131 | 0x7146 | 0x13c2 | 0x000e | 0x0480 |
In Reih und Glied
Ein großes Problem sind implizite Abhängigkeiten, ohne die ein Treiber die zugehörige Hardware nicht initialisieren kann, die jedoch nicht in der Modulliste modules.pcimap aufgeführt sind. Das Modul stradis für die Technotrend DVB-S1401 Budget bereitete besonderen Ärger: Es darf erst nach den Modulen dvb-ttpci und budget geladen werden, weil es sonst die DVB-Karte nicht in Betrieb nehmen kann. Statt dessen tauchen im Log Meldungen der Art i2c setup read timeout und i2c read timeout auf.
Die Lösung für das Skript dvbdriver sieht so aus, dass hinter der Variablen FIXEDMODULES in Zeile 4 von Listing 1 die beiden Module dvb-ttpci und budget eingetragen werden. Da das Skript zunächst sämtliche Module der Variablen FIXEDMODULES in genau der angegebenen Reihenfolge lädt und anschließend erst die Treiber der vorgefundenen DVB-Karten, ist sichergestellt, dass dvb-ttpci und budget in jedem Fall vor dem Modul stradis geladen sind.
Damit ist dvbdriver flexibel genug, auch in Zukunft auf implizite Abhängigkeiten oder vorgegebene Reihenfolgen beim Laden der Module zu reagieren. Durch die Hardware-Erkennung wird zudem sicher gestellt, dass sich lediglich die Treiber im Speicher befinden, die auch tatsächlich für den Betrieb der eingebauten Hardware benötigt werden – eine manuelle Pflege der Treiberlisten ist damit überflüssig.
Listing 1
#!/bin/bash
MODDEP=/lib/modules/`uname -r`/modules.dep
PCIMAP=/lib/modules/`uname -r`/modules.pcimap
FIXEDMODULES="dvb-ttpci,budget"
Tab=$'\t'
Newline=$'\n'
case "$1" in
load)
IFS=",${Tab}${Newline}"
for device in /sys/bus/pci/devices/*; do
read Vendor < ${device}/vendor
Vendor=${Vendor:2:4}
read Device < ${device}/device
Device=${Device:2:4}
read SubVendor < ${device}/subsystem_vendor
SubVendor=${SubVendor:2:4}
read SubDevice < ${device}/subsystem_device
SubDevice=${SubDevice:2:4}
read Class < ${device}/class
Class=${Class:2:6}
if [ "${Class:0:4}" = "0400" -o "${Class:0:4}" = "0480" ]; then
PciDev="${PciDev}${Tab}${Vendor},${Device},${SubVendor},${SubDevice},${Class}"
fi
done
Modules2Load="${FIXEDMODULES//,/${Tab}}"
IFS="${Newline}"
for z in `cat $PCIMAP`; do
IFS=" "
set – $z
module="$1"
vendor="${2:6:4}"
product="${3:6:4}"
subvendor="${4:6:4}"
subdevice="${5:6:4}"
class="${6:4:6}"
classmask="${7:4:6}"
IFS="${Tab}${Newline}"
for d in ${PciDev}; do
IFS=",${Tab}${Newline}"
set – $d
if [ "${vendor}" = "${1}" -a "${product}" = "${2}" -o \
"${vendor}" = "ffff" -a "${product}" = "ffff" ]; then
if [ "${subvendor}" = "${3}" -a "${subdevice}" = "${4}" -o \
"${subvendor}" = "ffff" -a "${subdevice}" = "ffff" ]; then
if [ "${class}" = "0000" -o \
"$[ 0x${5} & 0x${classmask} ]" = "$[0x${class}]" ]; then
for m in ${Modules2Load}; do
if [ "${m}" = "${module}" ]; then
module=""
fi
done
if [ -n "${module}" ]; then
Modules2Load="${Modules2Load}${Tab}${module}"
fi
fi
fi
fi
done
done
IFS=" ${Tab}${Newline}"
DvbModules=""
for m in ${Modules2Load}; do
dep=""
for d in `grep "${m}\.ko:" ${MODDEP}`; do
d=${d##*/}
dep="${dep}${Tab}${d%.ko*}"
done
DvbModules="${dep}${Tab}${DvbModules}"
modprobe ${m}
done
if [ -e /var/run/dvbdriver.modules ]; then
rm -f /var/run/dvbdriver.modules
fi
for m in ${DvbModules}; do
echo ${m} >> /var/run/dvbdriver.modules
done
;;
unload)
if [ ! -r /var/run/dvbdriver.modules ]; then
echo "Keine Modulliste gefunden (/var/run/dvbdriver.modules)"
exit 1
fi
for m in `cat /var/run/dvbdriver.modules`; do
modprobe -r ${m}
done
;;
esac
Infos
[1] DVB-Treiber: http://linuxtv.org
[2] Mercurial Repositoryies der DVB-Treiber: http://linuxtv.org/hg
[3] DVD-Treiber-Skript dvbdriver: http://www.linux-user.de/Downloads/2006/09/dvb



