xref: /dflybsd-src/share/examples/kld/firmware/wrap-fw_module.sh (revision 137f4259438e31e5d1cb196034dc4fcde775d556)
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