# [Solved] Loading firmware in initramfs

## MichiFridge

Hello,

I've got an encrypted root-partition. After loading the kernel an initramfs is loaded which decrypts the root-partition and boots it up. When I wait too long before decrypting and booting the root-partition, the firmware of my wifi-device fails to load and I can't use it. This is because the firmware-file is located on the root-partition (in /lib/firmware) which is not available at boot-time and loading the firmware seems to fail after approx. 60 seconds.

Now I need to know a little bit more about the way a firmware is loaded. I already tried to copy the ucode-file to my initramfs, but this didn't help. Can anyone give me a hint how to load a firmware from initramfs?

Thanks in advance,

MichaelLast edited by MichiFridge on Sat Jul 23, 2011 9:17 pm; edited 1 time in total

----------

## Hu

In addition to having the files in the initramfs, you need a program to load them.  The loading process is straightforward, but there are several surprises along the way.  I found a mailing list posting describing it some time ago, but did not bookmark it.  I did save a loader derived from the advice in that thread.  The filename of the loader is set in your kernel configuration, and defaults to /sbin/hotplug.  The key points are to echo 1 into the appropriate loading file to advise the driver that you are about to provide it with data, then copy the firmware into the corresponding data file, then echo 0 into loading if you succeeded or -1 if you failed.  The script below assumes the existence of a /sys, but does not assume that a sysfs will be mounted there.

```
#!/bin/bash

PATH="/sbin:/bin"

load_firmware() {

   local FN=/lib64/firmware/"$FIRMWARE"

   if [[ ! -e "$FN" ]]; then

      echo "$FN not found"

      return 1

   fi

   if ! cd /sys; then

      return 1

   fi

   local fst=$(stat -f -c %T .)

   if [[ "$fst" != 'sysfs' ]]; then

      echo "mounting /sys for $FN -> $DEVPATH"

      mount -n -t sysfs sysfs /sys || return 1

      if ! cd /sys; then

         umount -n -l /sys

         return 1

      fi

   else

      echo "loading $FN -> $DEVPATH"

   fi

   echo 1 >"./$DEVPATH/loading"

   rc=$?

   if [[ $rc -eq 0 ]]; then

      cat "$FN">"./$DEVPATH/data"

      rc=$?

   fi

   if [[ $rc -eq 0 ]]; then

      echo 0 >"./$DEVPATH/loading"

   else

      echo -1 >"./$DEVPATH/loading"

   fi

   if [[ "$fst" != 'sysfs' ]]; then

      umount -n -l .

   fi

   cd /

   return $rc

}

if [[ "$ACTION" != 'add' ]]; then

   exit 0

fi

if [[ "$FIRMWARE" == '' ]]; then

   exit 0

fi

exec >/dev/console 2>&1

if ! load_firmware; then

   echo "failed to load $FN -> $DEVPATH"

fi

exit 0
```

----------

## MichiFridge

Thank you, it works!

I already read about such a script but didn't give it a try because I don't have a /sbin/hotplug executable on my root-filesystem. So there seem to be other possibilities to load a firmware, too... Anyway, thanks for the quick response.

----------

## Hu

Yes, in a fully booted system, one of the regular daemons takes over firmware loading.  However, during early initialization in the initramfs, that daemon is not available, so loading must be done separately.

----------

