at master 4.2 kB view raw
1# When no modules are built, the $out/lib/modules directory will not 2# exist. Because the rest of the script assumes it does exist, we 3# handle this special case first. 4if ! test -d "$kernel/lib/modules"; then 5 if test -z "$rootModules" || test -n "$allowMissing"; then 6 mkdir -p "$out" 7 exit 0 8 else 9 echo "Required modules: $rootModules" 10 echo "Can not derive a closure of kernel modules because no modules were provided." 11 exit 1 12 fi 13fi 14 15version=$(cd $kernel/lib/modules && ls -d *) 16 17echo "kernel version is $version" 18 19# Determine the dependencies of each root module. 20mkdir -p $out/lib/modules/"$version" 21touch closure 22for module in $rootModules; do 23 echo "root module: $module" 24 modprobe --config no-config -d $kernel --set-version "$version" --show-depends "$module" \ 25 | while read cmd module args; do 26 case "$cmd" in 27 builtin) 28 touch found 29 echo "$module" >>closure 30 echo " builtin dependency: $module";; 31 insmod) 32 touch found 33 if ! test -e "$module"; then 34 echo " dependency not found: $module" 35 exit 1 36 fi 37 target=$(echo "$module" | sed "s^$NIX_STORE.*/lib/modules/^$out/lib/modules/^") 38 if test -e "$target"; then 39 echo " dependency already copied: $module" 40 continue 41 fi 42 echo "$module" >>closure 43 echo " copying dependency: $module" 44 mkdir -p $(dirname $target) 45 cp "$module" "$target" 46 # If the kernel is compiled with coverage instrumentation, it 47 # contains the paths of the *.gcda coverage data output files 48 # (which it doesn't actually use...). Get rid of them to prevent 49 # the whole kernel from being included in the initrd. 50 nuke-refs "$target" 51 echo "$target" >> $out/insmod-list;; 52 *) 53 echo " unexpected modprobe output: $cmd $module" 54 exit 1;; 55 esac 56 done || test -n "$allowMissing" 57 if ! test -e found; then 58 echo " not found" 59 if test -z "$allowMissing"; then 60 exit 1 61 fi 62 else 63 rm found 64 fi 65done 66 67cd "$firmware" 68for module in $(< ~-/closure); do 69 # for builtin modules, modinfo will reply with a wrong output looking like: 70 # $ modinfo -F firmware unix 71 # name: unix 72 # 73 # There is a pending attempt to fix this: 74 # https://github.com/NixOS/nixpkgs/pull/96153 75 # https://lore.kernel.org/linux-modules/20200823215433.j5gc5rnsmahpf43v@blumerang/T/#u 76 # 77 # For now, the workaround is just to filter out the extraneous lines out 78 # of its output. 79 modinfo -b $kernel --set-version "$version" -F firmware $module | grep -v '^name:' | while read -r i; do 80 echo "firmware for $module: $i" 81 for name in "$i" "$i.xz" "$i.zst" ""; do 82 [ -z "$name" ] && echo "WARNING: missing firmware $i for module $module" 83 if cp -v --parents --no-preserve=mode lib/firmware/$name "$out" 2>/dev/null; then 84 break 85 fi 86 done 87 done || : 88done 89 90for path in $extraFirmwarePaths; do 91 mkdir -p $(dirname $out/lib/firmware/$path) 92 for name in "$path" "$path.xz" "$path.zst" ""; do 93 if cp -v --parents --no-preserve=mode lib/firmware/$name "$out" 2>/dev/null; then 94 break 95 fi 96 done 97done 98 99if test -e lib/firmware/edid ; then 100 echo "lib/firmware/edid found, copying." 101 mkdir -p "$out/lib/firmware" 102 cp -v --no-preserve=mode --recursive --dereference --no-target-directory lib/firmware/edid "$out/lib/firmware/edid" 103else 104 echo "lib/firmware/edid not found, skipping." 105fi 106 107# copy module ordering hints for depmod 108cp $kernel/lib/modules/"$version"/modules.order $out/lib/modules/"$version"/. 109cp $kernel/lib/modules/"$version"/modules.builtin $out/lib/modules/"$version"/. 110 111depmod -b $out -a $version 112 113# remove original hints from final derivation 114rm $out/lib/modules/"$version"/modules.order 115rm $out/lib/modules/"$version"/modules.builtin