1*137f4259Szrj#!/bin/sh 2*137f4259Szrj 3*137f4259Szrjset -e 4*137f4259Szrj 5*137f4259Szrjif [ "$#" -eq 0 ] || [ "$#" -gt 2 ]; then 6*137f4259Szrj echo "Usage: $(basename $0) fw.bin [module_prefix]" 7*137f4259Szrj exit 1 8*137f4259Szrjfi 9*137f4259Szrj 10*137f4259Szrjif [ ! -f $1 ]; then 11*137f4259Szrj echo "File $1 does not exist" 12*137f4259Szrj exit 1 13*137f4259Szrjfi 14*137f4259Szrj 15*137f4259Szrjif [ "$#" -eq 2 ]; then 16*137f4259SzrjMOD_PREFIX=$2 17*137f4259Szrjfi 18*137f4259Szrj 19*137f4259SzrjMODULEDIR=${MODULEDIR:-/boot/modules.local} 20*137f4259SzrjWORKDIR=$(mktemp -d) 21*137f4259SzrjCURDIR=$PWD 22*137f4259Szrj 23*137f4259SzrjFWFILE=$(basename "$1") 24*137f4259Szrj# strip .bin and .fw extensions 25*137f4259SzrjMODNAME=$(basename $(basename "$1" .bin) .fw) 26*137f4259Szrj 27*137f4259Szrj# if module_prefix is provided, append to module name 28*137f4259Szrjif [ "$#" -eq 2 ]; then 29*137f4259SzrjMODNAME=${MOD_PREFIX}${MODNAME} 30*137f4259Szrjfi 31*137f4259Szrj 32*137f4259Szrj# copy firmware file to workdir 33*137f4259Szrjcp -v "$1" "$WORKDIR"/"$FWFILE" 34*137f4259Szrj 35*137f4259Szrj# prefer to use /sys build but provide workaround too 36*137f4259Szrjif [ -f /sys/tools/fw_stub.awk ]; 37*137f4259Szrjthen 38*137f4259Szrjecho "KMOD= ${MODNAME}" > "$WORKDIR"/Makefile 39*137f4259Szrjecho "FIRMWS= ${FWFILE}:${MODNAME}" >> "$WORKDIR"/Makefile 40*137f4259Szrjecho ".include <bsd.kmod.mk>" >> "$WORKDIR"/Makefile 41*137f4259Szrj 42*137f4259Szrj(cd $WORKDIR && make) 43*137f4259Szrj 44*137f4259Szrjelse 45*137f4259Szrj# workaround case to build a local fw module version w/o kernel sources (should have no impact) 46*137f4259Szrjset -x 47*137f4259Szrj 48*137f4259Szrj# ld/objcopy substitutes ' ', '-', '.' and '/' to '_' 49*137f4259SzrjFWSYM=$(echo ${FWFILE} |sed 's/ /_/g' | sed 's/-/_/g' |sed 's/\./_/g' |sed 's/\/_//g') 50*137f4259Szrjecho FWSYM=${FWSYM} 51*137f4259Szrj 52*137f4259Szrjcd $WORKDIR 53*137f4259Szrjld -b binary --no-warn-mismatch -r -d -o "${FWFILE}.fwo" "${FWFILE}" 54*137f4259Szrj 55*137f4259Szrjcat << EOF >> ${MODNAME}.c 56*137f4259Szrj#include <sys/param.h> 57*137f4259Szrj#include <sys/errno.h> 58*137f4259Szrj#include <sys/kernel.h> 59*137f4259Szrj#include <sys/module.h> 60*137f4259Szrj#include <sys/linker.h> 61*137f4259Szrj#include <sys/firmware.h> 62*137f4259Szrj//#include <sys/systm.h> 63*137f4259Szrj 64*137f4259Szrjextern char _binary_${FWSYM}_start[], _binary_${FWSYM}_end[]; 65*137f4259Szrj 66*137f4259Szrjstatic int 67*137f4259Szrj${MODNAME}_fw_modevent(module_t mod, int type, void *unused) 68*137f4259Szrj{ 69*137f4259Szrj const struct firmware *fp; 70*137f4259Szrj int error; 71*137f4259Szrj switch (type) { 72*137f4259Szrj case MOD_LOAD: 73*137f4259Szrj fp = firmware_register("${MODNAME}", _binary_${FWSYM}_start , (size_t)(_binary_${FWSYM}_end - _binary_${FWSYM}_start), 0, NULL); 74*137f4259Szrj if (fp == NULL) 75*137f4259Szrj goto fail_0; 76*137f4259Szrj return (0); 77*137f4259Szrjfail_0: 78*137f4259Szrj return (ENXIO); 79*137f4259Szrj case MOD_UNLOAD: 80*137f4259Szrj error = firmware_unregister("${MODNAME}"); 81*137f4259Szrj return (error); 82*137f4259Szrj } 83*137f4259Szrj return (EINVAL); 84*137f4259Szrj} 85*137f4259Szrj 86*137f4259Szrjstatic moduledata_t ${MODNAME}_fw_mod = { 87*137f4259Szrj "${MODNAME}_fw", 88*137f4259Szrj ${MODNAME}_fw_modevent, 89*137f4259Szrj 0 90*137f4259Szrj}; 91*137f4259SzrjDECLARE_MODULE(${MODNAME}_fw, ${MODNAME}_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 92*137f4259SzrjMODULE_VERSION(${MODNAME}_fw, 1); 93*137f4259SzrjMODULE_DEPEND(${MODNAME}_fw, firmware, 1, 1, 1); 94*137f4259SzrjEOF 95*137f4259Szrj 96*137f4259SzrjFFLAGS="-fno-common -ffreestanding -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-stack-protector" 97*137f4259Szrjcc -O -pipe -D_KERNEL -Wall -std=c99 -Werror -DKLD_MODULE ${FFLAGS} -mcmodel=kernel -mno-red-zone -c "${MODNAME}.c" 98*137f4259Szrjld -r -d -o "${MODNAME}.ko" "${FWFILE}.fwo" "${MODNAME}.o" 99*137f4259Szrj 100*137f4259Szrjfi 101*137f4259Szrj 102*137f4259Szrj 103*137f4259Szrj# copy firmware module to external modules dir 104*137f4259Szrjcp -v "$WORKDIR/$MODNAME.ko" "${MODULEDIR}/" 105*137f4259Szrj 106*137f4259Szrjrm -rf "${WORKDIR}" 107