Question

Je compile un noyau personnalisé sous Ubuntu et je suis en cours d'exécution dans le problème que mon noyau ne semble pas savoir où chercher firmware. Sous Ubuntu 8.04, le firmware est lié à la version du noyau les mêmes modules de pilotes sont ainsi. Par exemple, le noyau 2.6.24-24-générique stocke ses modules du noyau dans:

/lib/modules/2.6.24-24-generic

et son firmware dans:

/lib/firmware/2.6.24-24-generic

Quand je compile le noyau Ubuntu-2.6.24-24 générique selon Autre construction du « Debian » je reçois le répertoire des modules appropriés et travailler tous mes appareils sauf ceux qui ont besoin du firmware tels que ma carte sans fil Intel (module ipw2200)

.

Le journal du noyau montre par exemple que lorsque ipw2200 tente de charger le firmware du sous-système du noyau contrôlant le chargement du firmware est incapable de le localiser:

ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2

errno-base.h définit comme:

#define ENOENT       2  /* No such file or directory */

(La fonction de retour ENOENT met un signe moins en face d'elle.)

J'ai essayé de créer un lien symbolique dans / lib / firmware où le nom de mon noyau a dans le répertoire 2.6.24-24-générique, mais cela a donné lieu à la même erreur. Ce firmware est non-GPL, fourni par Intel et emballé par Ubuntu. Je ne crois pas qu'il y ait aucun lien réel à une version particulière du noyau. cmp montre que les versions dans les différents répertoires sont identiques.

Alors, comment le noyau sait où chercher firmware?

Mise à jour

J'ai trouvé cette solution au problème exact que je vais avoir, mais il ne fonctionne plus comme Ubuntu a éliminé /etc/hotplug.d et ne stocke son firmware dans /usr/lib/hotplug/firmware.

Update2

Un peu plus recherche a révélé de plus de réponses. Jusqu'à la version 92 de udev, le programme firmware_helper était le firmware de manière obtenu chargé. A partir de 93 udev ce programme a été remplacé par un script nommé firmware.sh fournissant des fonctionnalités identiques pour autant que je peux dire. Ces deux hardcode le chemin du firmware pour /lib/firmware. Ubuntu semble encore être en utilisant le binaire /lib/udev/firmware_helper.

Le nom du fichier du firmware est passé à firmware_helper dans l'environnement $FIRMWARE variable qui est concaténer le chemin /lib/firmware et utilisé pour charger le firmware.

La demande réelle pour charger le firmware est fait par le conducteur (ipw2200 dans mon cas) via l'appel système:

request_firmware(..., "ipw2200-bss.fw", ...);

quelque part entre le conducteur appelant request_firmware et firmware_helper regardant la variable d'environnement $FIRMWARE, le nom du package du noyau est obtenir le nom ajouté au début du firmware.

Alors qui le fait?

Était-ce utile?

La solution

Du point de vue du noyau, voir / usr / src / linux / Documentation / firmware_class / README :

 kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device)

 userspace:
        - /sys/class/firmware/xxx/{loading,data} appear.
        - hotplug gets called with a firmware identifier in $FIRMWARE
          and the usual hotplug environment.
                - hotplug: echo 1 > /sys/class/firmware/xxx/loading

 kernel: Discard any previous partial load.

 userspace:
                - hotplug: cat appropriate_firmware_image > \
                                        /sys/class/firmware/xxx/data

 kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
         comes in.

 userspace:
                - hotplug: echo 0 > /sys/class/firmware/xxx/loading

 kernel: request_firmware() returns and the driver has the firmware
         image in fw_entry->{data,size}. If something went wrong
         request_firmware() returns non-zero and fw_entry is set to
         NULL.

 kernel(driver): Driver code calls release_firmware(fw_entry) releasing
                 the firmware image and any related resource.

Le noyau ne fait charger tout firmware du tout. Il informe simplement l'espace utilisateur, « Je veux un firmware par le nom de xxx », et attend l'espace utilisateur à la conduite de l'image du firmware vers le noyau.

Maintenant, sur Ubuntu 8.04,

$ grep firmware /etc/udev/rules.d/80-program.rules
# Load firmware on demand
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware_helper"

afin que vous avez découvert, udev est configuré pour exécuter firmware_helper lorsque le noyau demande firmware.

$ apt-get source udev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Need to get 312kB of source archives.
Get:1 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (dsc) [716B]
Get:2 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (tar) [245kB]
Get:3 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (diff) [65.7kB]
Fetched 312kB in 1s (223kB/s)
gpg: Signature made Tue 14 Apr 2009 05:31:34 PM EDT using DSA key ID 17063E6D
gpg: Can't check signature: public key not found
dpkg-source: extracting udev in udev-117
dpkg-source: unpacking udev_117.orig.tar.gz
dpkg-source: applying ./udev_117-8ubuntu0.2.diff.gz
$ cd udev-117/
$ cat debian/patches/80-extras-firmware.patch

Si vous lisez la source, vous verrez que Ubuntu a écrit un firmware_helper qui est codé en dur pour rechercher d'abord /lib/modules/$(uname -r)/$FIRMWARE, puis /lib/modules/$FIRMWARE, et qu'aucun autre endroit. Traduire à sh, il fait à peu près ceci:

echo -n 1 > /sys/$DEVPATH/loading
cat /lib/firmware/$(uname -r)/$FIRMWARE > /sys/$DEVPATH/data \
    || cat /lib/firmware/$FIRMWARE      > /sys/$DEVPATH/data
if [ $? = 0 ]; then
    echo -n  1 > /sys/$DEVPATH/loading
    echo -n -1 > /sys/$DEVPATH/loading
fi

ce qui est exactement le format que le noyau attend.


Pour faire une histoire courte: paquet de udev Ubuntu a personnalisations qui semblent toujours /lib/firmware/$(uname -r) d'abord. Cette politique est en cours de traitement dans l'espace utilisateur.

Autres conseils

Wow ce qui est très utile et des informations m'a conduit à la solution à mon problème lors d'un module noyau USB personnalisé pour un appareil nécessitant le firmware.

Fondamentalement, chaque Ubuntu apporte une nouvelle mouture de hal, sysfs, devfs, udev, et ainsi de suite ... et les choses changer. En fait, je lis, ils ont cessé d'utiliser hal.

Alors l'ingénieur Inversez cette fois encore il est pertinent aux derniers [Ubuntu] systèmes.

Ubuntu Lucid (la dernière au moment de la rédaction), /lib/udev/rules.d/50-firmware.rules est utilisé. Ce fichier appelle le /lib/udev/firmware binaire, où la magie se produit.

Liste: /lib/udev/rules.d/50-firmware.rules

# firmware-class requests, copies files into the kernel
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware --firmware=$env{FIRMWARE} --devpath=$env{DEVPATH}"

La magie doit être quelque chose le long de ces lignes (source:. Pilotes de périphériques Linux, 3ème Ed, Ch . 14: Le modèle de périphérique Linux ):

  • echo 1 à loading
  • firmware de copie à data
  • en cas d'échec, l'écho de -1 à loading et le processus de chargement du micrologiciel d'arrêt
  • echo 0 à loading (signaler le noyau)
  • puis, un module noyau spécifique reçoit les données et le pousse à l'appareil

Si vous regardez la page source de Lucid pour udev, dans udev-151/extras/firmware/firmware.c, la source de ce firmware / lib / udev / binaire du firmware, qui est exactement ce qui se passe.

Extrait: Source Lucid, udev-151 / extras / firmware / firmware.c

    util_strscpyl(datapath, sizeof(datapath), udev_get_sys_path(udev), devpath, "/data", NULL);
    if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
            err(udev, "error sending firmware '%s' to device\n", firmware);
            set_loading(udev, loadpath, "-1");
            rc = 4;
            goto exit;
    };

    set_loading(udev, loadpath, "0");

En outre, de nombreux appareils utilisent un format Intel HEX (fichiers contenant textish somme de contrôle et d'autres choses) (wiki Je n'ai pas la réputation et pas la possibilité de créer un lien). Le programme du noyau ihex2fw (appelé de Makefile dans kernel_source / lib / firmware sur les fichiers HEX) convertit ces fichiers HEX à un format binaire arbitraire conçu que le noyau Linux prend alors avec request_ihex_firmware, parce qu'ils pensaient que la lecture de fichiers texte dans le noyau était idiot (il ralentirait les choses).

Sur les systèmes Linux actuels, cela est géré par udev et firmware.agent.

Linux 3.5.7 Gentoo, j'ai le même problème. RESOLU:

emerge ipw2200-firmware

Ensuite, allez dans / usr / src / linux

make menucofig

sur pilote de périphérique, supprimer tous les pilotes wirless ne sont pas nécessaires, réglez Intelli 2200 en tant que module et recompiler.

make
make modules_install
cp arch/x86/boot/bzImage /boot/kernel-yourdefault
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top