4 # Copyright (c) 2006 Max Laier.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # Script to generate module .c file from a list of firmware images
36 print "usage: fw_stub <firmware:name>* [-l name] [-m modname] [-c outfile]";
40 # These are just for convenience ...
44 print s
> ctmpfilename
;
46 print s
> "/dev/stdout";
52 # Process the command line.
57 for (i =
1; i
< ARGC; i
++) {
60 # awk doesn't have getopt(), so we have to do it ourselves.
61 # This is a bit clumsy, but it works.
63 for (j =
2; j
<=
length(ARGV[i
]); j
++) {
64 o =
substr(ARGV[i
], j
, 1);
66 if (length(ARGV[i
]) > j
) {
67 opt_c =
substr(ARGV[i
], j
+ 1);
76 } else if (o ==
"m") {
77 if (length(ARGV[i
]) > j
) {
78 opt_m =
substr(ARGV[i
], j
+ 1);
87 } else if (o ==
"l") {
88 if (length(ARGV[i
]) > j
) {
89 opt_l =
substr(ARGV[i
], j
+ 1);
102 split(ARGV[i
], curr
, ":");
103 filenames
[num_files
] = curr
[1];
104 if (length(curr
[2]) > 0)
105 shortnames
[num_files
] = curr
[2];
107 shortnames
[num_files
] = curr
[1];
108 if (length(curr
[3]) > 0)
109 versions
[num_files
] = int
(curr
[3]);
111 versions
[num_files
] =
0;
116 if (!num_files
|| !opt_m
)
120 ctmpfilename = cfilename
".tmp";
122 gsub(/[-\.
]/, "_", modname
);
125 * Automatically generated by:\
128 printc
("#include <sys/param.h>");
129 printc
("#include <sys/errno.h>");
130 printc
("#include <sys/kernel.h>");
131 printc
("#include <sys/module.h>");
132 printc
("#include <sys/linker.h>");
133 printc
("#include <sys/firmware.h>");
134 printc
("#include <sys/systm.h>\n");
137 printc
("static long " opt_l
"_license_ack = 0;");
140 for (file_i =
0; file_i
< num_files
; file_i
++) {
141 symb = filenames
[file_i
];
142 # '-', '.' and '/' are converted to '_' by ld/objcopy
143 gsub(/-|\.
|\
//, "_", symb
);
144 printc
("extern char _binary_" symb
"_start[], _binary_" symb
"_end[];");
147 printc
("\nstatic int\n"\
148 modname
"_fw_modevent(module_t mod, int type, void *unused)\
150 const struct firmware *fp, *parent;\
157 TUNABLE_LONG_FETCH(\"legal." opt_l
".license_ack\", &" opt_l
"_license_ack);\
158 if (!" opt_l
"_license_ack) {\
159 printf(\"" opt_m
": You need to read the LICENSE file in /usr/share/doc/legal/" opt_l
".LICENSE.\\n\");\
160 printf(\"" opt_m
": If you agree with the license, set legal." opt_l
".license_ack=1 in /boot/loader.conf.\\n\");\
165 for (file_i =
0; file_i
< num_files
; file_i
++) {
166 short = shortnames
[file_i
];
167 symb = filenames
[file_i
];
168 version = versions
[file_i
];
169 # '-', '.' and '/' are converted to '_' by ld/objcopy
170 gsub(/-|\.
|\
//, "_", symb
);
173 reg = reg
"firmware_register(\"" short
"\", _binary_" symb
"_start , ";
174 reg = reg
"(size_t)(_binary_" symb
"_end - _binary_" symb
"_start), ";
175 reg = reg version
", ";
180 reg = reg
"parent);";
184 printc
("\t\tif (fp == NULL)");
185 printc
("\t\t\tgoto fail_" file_i
";");
187 printc
("\t\tparent = fp;");
190 printc
("\t\treturn (0);");
192 for (file_i = num_files
- 1; file_i
> 0; file_i
--) {
193 printc
("fail_" file_i
":")
194 printc
("\t\t(void)firmware_unregister(\"" shortnames
[file_i
- 1] "\");");
198 printc
("\t\treturn (ENXIO);");
200 printc
("\tcase MOD_UNLOAD:");
202 for (file_i =
1; file_i
< num_files
; file_i
++) {
203 printc
("\t\terror = firmware_unregister(\"" shortnames
[file_i
] "\");");
204 printc
("\t\tif (error)");
205 printc
("\t\t\treturn (error);");
208 printc
("\t\terror = firmware_unregister(\"" shortnames
[0] "\");");
210 printc
("\t\treturn (error);\
215 static moduledata_t " modname
"_fw_mod = {\
217 " modname
"_fw_modevent,\
220 DECLARE_MODULE(" modname
"_fw, " modname
"_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
221 MODULE_VERSION(" modname
"_fw, 1);\
222 MODULE_DEPEND(" modname
"_fw, firmware, 1, 1, 1);\
226 if ((rc =
system("mv -f " ctmpfilename
" " cfilename
))) {
227 print "'mv -f " ctmpfilename
" " cfilename
"' failed: " rc \