#!/bin/bash # called from build.sh (kernel-kit) # download & process linux-firmware git source ./build.conf || exit 1 export LANG=C #faster setvar DEBUG = '0' #0=disabled, 1=enabled rm -f ./fw-*.log test $DEBUG -ne 1 -a -d zfirmware_workdir && rm -r zfirmware_workdir setvar CWD = $(pwd) # busybox stat faster? busybox|grep -qow 'stat' && setvar STAT = ''busybox stat'' || setvar STAT = 'stat' # vars setvar SRC_FW_DIR = ''../linux-firmware'' setvar DEST_FW_DIR = ''zfirmware_workdir/lib'' setvar SRC_FILE_FW = "${SRC_FW_DIR}/WHENCE" setvar dotconfig = $(find output -maxdepth 1 -type f -name 'DOTconfig*' | head -1) if test -f $dotconfig { setvar DOTCONFIG_str = $(grep -v -E '^#|is not set$' $dotconfig) } else { echo "WARNING: No DOTconfig file in output/" echo "Put a DOTconfig file there..." #exit 1 } setvar FIRMWARE_SFS = ""sources/fdrv_${kernel_version}_${package_name_suffix}.sfs"" setvar FIRMWARE_RESULT_DIR = ''zfirmware_workdir/lib/firmware'' setvar FIRMWARE_EXTRA_DIR = ''zfirmware_workdir/lib/linux-firmware'' setvar kernel_package = $(find output -type d -name 'linux_kernel*' | head -1) if test ! -d ${kernel_package} { setvar kernel_package = $(find $CWD -type d -name 'linux_kernel*' | head -1) } #if [ ! -d "${kernel_package}" ] ; then # echo "WARNING: No kernel package..." # #exit 1 #else setvar dest_kernel_package = "${kernel_package}/lib/firmware" test ! -d ${dest_kernel_package} && mkdir -p $dest_kernel_package #fi ################################################################# # FUNCTIONS ################################################################# proc func_git { if test -d $SRC_FW_DIR{ cd $SRC_FW_DIR echo "Updating the git firmware repo" git pull test $? -ne 0 && echo "Failed to update git firmware" # non fatal return 0 # precaution } else { cd .. echo "Cloning the firmware repo may take a long time" git clone git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git if test $? -ne 0{ echo "Failed to clone the git firmware repo" return 1 } return 0 } } proc process_driver { local driver=$1 local DRIVER=${driver^^} setvar DRIVER = ${DRIVER//-/_} case (DRIVER) { # try to avoid dups RADEON { setvar DRIVER = ''DRM_RADEON='' } NOUVEAU { setvar DRIVER = ''DRM_NOUVEAU='' } AMDGPU { setvar DRIVER = ''DRM_AMDGPU='' } I915 { setvar DRIVER = ''DRM_I915='' } KEYSPAN { setvar DRIVER = ''SERIAL_KEYSPAN=''} LIBERTAS { setvar DRIVER = 'LIBERTAS_USB' } RTL8821AE {setvar DRIVER = '8821AE' } MWIFIEX { setvar DRIVER = 'MWIFIEX_USB' } MWLWIFI { setvar DRIVER = ''CONFIG_MAC80211''} #see WHENCE, .config } echo -n "$driver " setvar D = $(echo $DOTCONFIG_str | grep $DRIVER | head -n1) if test -z $D { echo return 1 } else { echo -- $D -- return 0 } } proc get_func { local file=${1} local source_path=${SRC_FW_DIR}/${file} local target_dir=${CWD}/${FIRMWARE_EXTRA_DIR}/${file} setvar target_dir = ${target_dir%/*} # strip off file if test ! -d ${target_dir} { # manufacture dest subdirs before move mkdir -p ${target_dir} } cp -d ${source_path} ${target_dir} 2>/dev/null if test $? -eq 0{ echo "$file $($STAT -c %s $SRC_FW_DIR/$file)" >> fw-1.log } else { echo "FAILURE: $file" >> fw-1.log } } proc extract_firmware { shell { while read -r field value etc { case (field) { "Driver:" { setvar driver = "$value" # select firmware according based on DOTconfig... process_driver $driver || continue echo -n "$driver " >&2 while test 1 { read -r field value etc case (field) { "File:" { setvar file = "$value" ; get_func $file } "License:"|"Licence:" { break } } } } } } < ${SRC_FILE_FW} } > fw-2.log } proc fw_filter { setvar list = "$1" test -z $2 && setvar B = '10000000' || setvar B = "$2" #~10MB (salesmen MB ;-) test $B -eq 0 && setvar B = '10000000' echo "Filtering with $list" shell { echo ; echo ; echo "Filtering with $list" echo 'FILTERED FIRMWARE LIST IN ZDRV' echo '==============================' mkdir -p ${FIRMWARE_RESULT_DIR} setvar filelist = $(find ${FIRMWARE_EXTRA_DIR} | sed "s%${FIRMWARE_EXTRA_DIR}\/%%") # strip leading crap setvar filelist2 = $(find ${SRC_FW_DIR} | sed -e "s%${SRC_FW_DIR}\/%%" -e 's|\.git/||') # strip leading crap #echo "$filelist" while read line { setvar file = ${line##*/} setvar file2 = ${line} setvar action = 'mv' #move echo -n "$file " >&2 setvar file_path = $(echo $filelist | grep "^${file2}$" | head -n1) if test ! $file_path { setvar file_path = $(echo $filelist | grep "\/${file}$" | head -n1) test -z $file_path && continue } setvar source_path = "${FIRMWARE_EXTRA_DIR}/${file_path}" test -f ${source_path} -o -h ${source_path} || continue setvar target_dir = "${FIRMWARE_RESULT_DIR}/${file_path}" setvar target_dir = ${target_dir%/*} # strip off file if test ! -d ${target_dir} { # manufacture dest subdirs before move mkdir -p ${target_dir} } # make sure links follow targets test -h ${source_path} -a -e ${source_path} && setvar SSIZE = $($STAT -L -c %s ${source_path}) || setvar SSIZE = $(stat -c %s ${source_path}) test -z $SSIZE && continue #precaution test $SSIZE -gt $B && continue ##discard bigguns # do links first? setvar ret = '0' test -h ${source_path} && ${action} -f ${source_path} ${target_dir}/ #2>>fw-2.log setvar ret = ""$? test -e ${source_path} && ${action} -f ${source_path} ${target_dir}/ setvar ret = $(($ret + $?)) test $ret -le 1 && echo "${file} SUCCESS" || echo "${file} FAIL" } < $list } >> fw-2.log } proc licence_func { echo "Extracting licences" mkdir -p ${FIRMWARE_RESULT_DIR}/licences find ${SRC_FW_DIR} -type f -iname 'licen?e*' -exec cp '{}' ${FIRMWARE_RESULT_DIR}/licences ';' } ################################################################# # MAIN ################################################################# # update or clone git firmware if test $GIT_ALREADY_DOWNLOADED != "yes" { func_git || do { echo "ERROR" ; exit 1 ; } } cd ${CWD} test -d $DEST_FW_DIR && rm -rf $DEST_FW_DIR mkdir -p $DEST_FW_DIR test -f ${FIRMWARE_SFS} && rm -f ${FIRMWARE_SFS} # cut down firmware .. or not setvar FW_FLAG = "$1"; if test ! $FW_FLAG -a -z $CUTBYTES { echo -n " Cut down firmware? 1. Cut down according to firmware.lst [default] 2. Cut down according to built modules (needs work) 3. Don't cut down Choose option: " ; read cdf case (cdf) { 2 { setvar FW_FLAG = ""big"" } 3 { setvar FW_FLAG = ""complete"" } * { setvar FW_FLAG = """" } } } case (FW_FLAG) { complete { mkdir -p ${FIRMWARE_RESULT_DIR} echo "Copy all firmware" cp -an ${SRC_FW_DIR}/* ${FIRMWARE_RESULT_DIR}/ rm -rf ${FIRMWARE_RESULT_DIR}/.git ${FIRMWARE_RESULT_DIR}/LICEN* licence_func if test -d ${dest_kernel_package} { cp -an ${FIRMWARE_RESULT_DIR}/* ${dest_kernel_package}/ rm -r ${FIRMWARE_RESULT_DIR} } else { mksquashfs zfirmware_workdir ${FIRMWARE_SFS##*/} -comp xz md5sum ${FIRMWARE_SFS##*/} > ${FIRMWARE_SFS##*/}.md5.txt } } big { echo "Extracting firmware" extract_firmware # process entries in WHENCE echo #main_proc setvar echo = ""Not filtering"" mv ${FIRMWARE_EXTRA_DIR} ${FIRMWARE_RESULT_DIR} licence_func if test -d ${dest_kernel_package} { cp -n -r ${FIRMWARE_RESULT_DIR}/* ${dest_kernel_package}/ } } * { # create new list.. now gets filtered by size and obscure (= big ones deleted) # obscure fw are liquidio, phanfw.bin (netxen_nic) and cxgb{3,4} (chelsio) - mainly in servers grep '^File' $SRC_FILE_FW |grep -oE '\: [a-zA-Z].*|\: L.*|\: [0-9].*'|sed 's/^\: //'|grep -vE 'liquidio|cxgb[34]|phanfw.bin' > firmware.lst # choose if test ! $CUTBYTES{ echo -n " Cut down firmware more? 1. Cut down with some big, mostly obscure firmware removed (default) 2. Cut down eliminating fw bigger than 1.5MB - usually safe 3. Cut down eliminating fw bigger than 1MB - may cut wifi support 4. Cut down eliminating fw bigger than 500KB - use at own risk 5. Cut down eliminating fw bigger than 250KB - are you insane? Choose option: " ; read cdfplus case (cdfplus) { 2 { setvar CUTBYTES = '1500000' } 3 { setvar CUTBYTES = '1000000' } 4 { setvar CUTBYTES = '500000' } 5 { setvar CUTBYTES = '250000' } * { setvar CUTBYTES = '0' } } } echo "Extracting firmware" extract_firmware # process entries in WHENCE echo fw_filter firmware.lst $CUTBYTES find ${FIRMWARE_EXTRA_DIR} -type d -empty -delete licence_func # copy final fw to kernel if test -d ${dest_kernel_package} { cp -n -r ${FIRMWARE_RESULT_DIR}/* ${dest_kernel_package}/ } rm -r ${FIRMWARE_RESULT_DIR} # now move the extras to / lib/firmware & make sfs mv ${FIRMWARE_EXTRA_DIR} ${FIRMWARE_RESULT_DIR} mksquashfs zfirmware_workdir ${FIRMWARE_SFS} -comp xz md5sum ${FIRMWARE_SFS} > ${FIRMWARE_SFS}.md5.txt } } shell { echo '================' echo "FIRMWARE IN FDRV" echo '================' cat fw-1.log echo '==============================' test -f ${list}.log && cat ${list}.log && rm ${list}.log } &>> build.log # cleanup if test $DEBUG -ne 1 { rm -f fw-*.log rm -rf zfirmware_workdir } echo "Firmware script complete." ### END ###