]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/ndiscvt/ndisgen.sh
sysctl(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / usr.sbin / ndiscvt / ndisgen.sh
1 #!/bin/sh
2 #
3 # SPDX-License-Identifier: BSD-4-Clause
4 #
5 # Copyright (c) 2005
6 #       Bill Paul <wpaul@windriver.com>.  All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 # 1. Redistributions of source code must retain the above copyright
12 #    notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 #    notice, this list of conditions and the following disclaimer in the
15 #    documentation and/or other materials provided with the distribution.
16 # 3. All advertising materials mentioning features or use of this software
17 #    must display the following acknowledgement:
18 #       This product includes software developed by Bill Paul.
19 # 4. Neither the name of the author nor the names of any co-contributors
20 #    may be used to endorse or promote products derived from this software
21 #    without specific prior written permission.
22 #
23 # THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
24 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 # ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
27 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 # THE POSSIBILITY OF SUCH DAMAGE.
34 #
35 # $FreeBSD$
36 #
37
38 header () {
39 clear
40 echo "  =================================================================="
41 echo "  ------------------ Windows(r) driver converter -------------------"
42 echo "  =================================================================="
43 echo ""
44 }
45
46 mainmenu() {
47 header
48 echo "  This script is designed to guide you through the process"
49 echo "  of converting a Windows(r) binary driver module and .INF"
50 echo "  specification file into a FreeBSD ELF kernel module for use"
51 echo "  with the NDIS compatibility system."
52 echo ""
53 echo "  The following options are available:"
54 echo ""
55 echo "  1] Learn about the NDIS compatibility system"
56 echo "  2] Convert individual firmware files"
57 echo "  3] Convert driver"
58 echo "  4] Exit"
59 echo ""
60 echo -n "       Enter your selection here and press return: "
61 read KEYPRESS
62 return
63 }
64
65
66 help1 () {
67 header
68 echo "                          General information"
69 echo ""
70 echo "  The NDIS compatibility system is designed to let you use Windows(r)"
71 echo "  binary drivers for networking devices with FreeBSD, in cases where"
72 echo "  a native FreeBSD driver is not available due to hardware manufacturer"
73 echo "  oversight or stupidity. NDIS stands for Network Driver Interface"
74 echo "  Standard, and refers to the programming model used to write Windows(r)"
75 echo "  network drivers. (These are often called \"NDIS miniport\" drivers.)"
76 echo ""
77 echo "  In order to use your network device in NDIS compatibility mode,"
78 echo "  you need the Windows(r) driver that goes with it. Also, the driver"
79 echo "  must be compiled for the same architecture as the release of FreeBSD"
80 echo "  you have installed. At this time, the i386 and amd64 architectures"
81 echo "  are both supported. Note that you cannot use a Windows/i386 driver"
82 echo "  with FreeBSD/amd64: you must obtain a Windows/amd64 driver."
83 echo ""
84 echo -n "       Press return to continue... "
85 read KEYPRESS
86 return
87 }
88
89 help2() {
90 header
91 echo "                          Where to get drivers"
92 echo ""
93 echo "  If you purchased your network card separately from your computer,"
94 echo "  there should have been a driver distribution CD included with the"
95 echo "  card which contains Windows(r) drivers. The NDIS compatibility"
96 echo "  system is designed to emulate the NDIS API of a couple of different"
97 echo "  Windows(r) releases, however it works best with drivers designed"
98 echo "  for NDIS 5.0 or later. Drivers distributed for Windows 2000 should"
99 echo "  work; however, for best results you should use a driver designed"
100 echo "  for Windows XP or Windows Server 2003."
101 echo ""
102 echo "  If your card was supplied with your computer, or is a built-in device,"
103 echo "  drivers may have been included on a special driver bundle CD shipped"
104 echo "  with the computer."
105 echo ""
106 echo "  If you don't have a driver CD, you should be able to find a driver"
107 echo "  kit on the card or computer vendor's web site."
108 echo ""
109 echo -n "       Press return to continue... "
110 read KEYPRESS
111 return
112 }
113
114 help3 () {
115 header
116 echo "                          What files do I need?"
117 echo ""
118 echo "  In most cases, you will need only two files: a .INF file and a .SYS"
119 echo "  file. The .INF file is a text file used by the Windows(r) installer to"
120 echo "  perform the driver installation. It contains information that tells"
121 echo "  the installer what devices the driver supports and what registry keys"
122 echo "  should be created to control driver configuration. The .SYS file"
123 echo "  is the actual driver executable code in Windows(r) Portable Executable"
124 echo "  (PE) format. Note that sometimes the .INF file is supplied in Unicode"
125 echo "  format. Unicode .INF files must be converted to ASCII form with the"
126 echo "  iconv(1) utility before this installer script can use them."
127 echo "  Occasionally, a driver may require firmware or register setup"
128 echo "  files that are external to the main .SYS file. These are provided"
129 echo "  on the same CD with the driver itself, and sometimes have a .BIN"
130 echo "  extension, though they can be named almost anything. You will need"
131 echo "  these additional files to make your device work with the NDIS"
132 echo "  compatibility system as well."
133 echo ""
134 echo -n "       Press return to continue... "
135 read KEYPRESS
136 return
137 }
138
139 help4 () {
140 header
141 echo "                          How does it all work?"
142 echo ""
143 echo "  The installer script uses the ndiscvt(1) utility to convert the .INF,"
144 echo "  .SYS and optional firmware files into a FreeBSD kernel loadable module"
145 echo "  (.ko) file. This module can be loaded via the kldload(8) utility or"
146 echo "  loaded automatically via the /boot/loader.conf file. The ndiscvt(1)"
147 echo "  utility extracts the device ID information and registry key data"
148 echo "  from the .INF file and converts it into a C header file. It also uses"
149 echo "  the objcopy(1) utility to convert the .SYS file and optional firmware"
150 echo "  files into ELF objects. The header file is compiled into a small C"
151 echo "  stub file which contains a small amount of code to interface with"
152 echo "  the FreeBSD module system. This stub is linked together with the"
153 echo "  converted ELF objects to form a FreeBSD kernel module. A static ELF"
154 echo "  object (.o) file is also created. This file can be linked into a"
155 echo "  static kernel image for those who want/need a fully linked kernel"
156 echo "  image (possibly for embedded bootstrap purposes, or just plain old"
157 echo "  experimentation)."
158 echo ""
159 echo -n "       Press return to continue... "
160 read KEYPRESS
161 return
162 }
163
164 help5 () {
165 header
166 echo "                          Prerequisites"
167 echo ""
168 echo "  Converting a driver requires the following utilities:"
169 echo ""
170 echo "  - The FreeBSD C compiler, cc(1) (part of the base install)."
171 echo "  - The FreeBSD linker, ld(1) (part of the base install)."
172 echo "  - The objcopy(1) utility (part of the base install)."
173 echo "  - The ndiscvt(1) utility (part of the base install)."
174 echo ""
175 echo "  If you happen to end up with a .INF file that's in Unicode format,"
176 echo "  then you'll also need:"
177 echo ""
178 echo "  - The iconv(1) utility."
179 echo ""
180 echo "  If you have installed the X Window system or some sort of desktop"
181 echo "  environment, then iconv(1) should already be present. If not, you"
182 echo "  will need to install the libiconv package or port."
183 echo ""
184 echo -n "       Press return to continue... "
185 read KEYPRESS
186 return
187 }
188
189 infconv () {
190 header
191 echo "                  INF file validation"
192
193 if [ -z "$INFPATH" ]; then
194         echo ""
195         echo ""
196         echo "  A .INF file is most often provided as an ASCII file, however"
197         echo "  files with multilanguage support are provided in Unicode format."
198         echo "  Please type in the path to your .INF file now."
199         echo ""
200         echo -n "       > "
201         read INFPATH
202 fi
203
204 if [ ${INFPATH} ] && [ -e ${INFPATH} ]; then 
205         INFTYPE=`${EGREP} -i -c "Signature|.S.i.g.n.a.t.u.r.e" ${INFPATH}`
206         if [ ${INFTYPE} -le 0 ]; then
207                 echo ""
208                 echo "  I don't recognize this file format. It may not be a valid .INF file."
209                 echo ""
210                 echo -n "       Press enter to try again, or ^C to quit. "
211                 read KEYPRESS
212                 INFPATH=""
213                 return
214         fi
215
216         INFTYPE=`${EGREP} -i -c "Class.*=.*Net" ${INFPATH}`
217         if [ ${INFTYPE} -gt 0 ]; then
218                 echo ""
219                 echo "  This .INF file appears to be ASCII."
220                 echo ""
221                 echo -n "       Press return to continue... "
222                 read KEYPRESS
223                 return
224         fi
225
226         INFTYPE=`${EGREP} -i -c ".C.l.a.s.s.*=.*N.e.t" ${INFPATH}`
227         if [ ${INFTYPE} -gt 0 ]; then
228                 echo ""
229                 echo "  This .INF file appears to be Unicode."
230                 if [ -e ${ICONVPATH} ]; then
231                         echo "  Trying to convert to ASCII..."
232                         ${ICONVPATH} -f utf-16 -t utf-8 ${INFPATH} > ${INFFILE}
233                         INFPATH=${INFFILE}
234                         echo "  Done."
235                         echo ""
236                         echo -n "       Press return to continue... "
237                         read KEYPRESS
238                 else
239                         echo "  The iconv(1) utility does not appear to be installed."
240                         echo "  Please install this utility or convert the .INF file"
241                         echo "  to ASCII and run this utility again."
242                         echo ""
243                         exit
244                 fi
245                 return
246         fi
247
248         echo ""
249         echo "  I don't recognize this file format. It may not be a valid .INF file."
250         echo ""
251         echo -n "       Press enter to try again, or ^C to quit. "
252         read KEYPRESS
253         INFPATH=""
254 else
255         echo ""
256         echo "  The file '${INFPATH}' was not found."
257         echo ""
258         echo -n "       Press enter to try again, or ^C to quit. "
259         read KEYPRESS
260         INFPATH=""
261 fi
262 return
263 }
264
265 sysconv() {
266 header
267 echo "                  Driver file validation"
268
269 if [ ! -r "$SYSPATH" ]; then
270         echo ""
271         echo ""
272         echo "  Now you need to specify the name of the Windows(r) driver .SYS"
273         echo "  file for your device. Note that if you are running FreeBSD/amd64,"
274         echo "  then you must provide a driver that has been compiled for the"
275         echo "  64-bit Windows(r) platform. If a 64-bit driver is not available"
276         echo "  for your device, you must install FreeBSD/i386 and use the"
277         echo "  32-bit driver instead."
278         echo ""
279         echo "  Please type in the path to the Windows(r) driver .SYS file now."
280         echo ""
281         echo -n "       > "
282         read SYSPATH
283 fi
284
285 if [ ${SYSPATH} ] && [ -e ${SYSPATH} ]; then
286         SYSTYPE=`${FILE} ${SYSPATH}`
287
288         case ${SYSTYPE} in
289         *Windows*)
290                 echo ""
291                 echo "  This .SYS file appears to be in Windows(r) PE format."
292                 echo ""
293                 echo -n "       Press return to continue... "
294                 read KEYPRESS
295                 SYSBASE=`${BASENAME} ${SYSPATH} | ${TR} '.' '_'`
296                 ;;
297         *)
298                 echo ""
299                 echo "  I don't recognize this file format. It may not be a valid .SYS file."
300                 echo ""
301
302                 echo -n "       Press enter to try again, or ^C to quit. "
303                 read KEYPRESS
304                 SYSPATH=""
305                 ;;
306         esac
307 else
308         echo ""
309         echo "  The file '${SYSPATH}' was not found."
310         echo ""
311         echo -n "       Press enter to try again, or ^C to quit. "
312         read KEYPRESS
313         SYSPATH=""
314 fi 
315 return
316 }
317
318 ndiscvt() {
319 header
320 echo "                  Driver file conversion"
321 echo ""
322 echo "  The script will now try to convert the .INF and .SYS files"
323 echo "  using the ndiscvt(1) utility. This utility can handle most"
324 echo "  .INF files; however, occasionally it can fail to parse some files"
325 echo "  due to subtle syntax issues: the .INF syntax is very complex,"
326 echo "  and the Windows(r) parser will sometimes allow files with small"
327 echo "  syntax errors to be processed correctly which ndiscvt(1) will"
328 echo "  not. If the conversion fails, you may have to edit the .INF"
329 echo "  file by hand to remove the offending lines."
330 echo ""
331 echo -n "       Press enter to try converting the files now: "
332 read KEYPRESS
333 if ! ${NDISCVT} -i ${INFPATH} -s ${SYSPATH} -O -o ${DNAME}.h > /dev/null; then
334         echo "CONVERSION FAILED"
335         exit
336 else
337         echo ""
338         echo "  Conversion was successful."
339         echo ""
340         echo -n "       Press enter to continue... "
341         read KEYPRESS
342 fi
343 return
344 }
345
346 firmcvt() {
347         while : ; do
348 header
349 echo "                  Firmware file conversion"
350 echo ""
351 echo "  If your driver uses additional firmware files, please list them"
352 echo "  below. When you're finished, just press enter to continue. (If your"
353 echo "  driver doesn't need any extra firmware files, just press enter"
354 echo "  to move to the next step.)"
355 echo ""
356                 echo -n "       > "
357                 read FIRMPATH
358
359                 if [ ${FIRMPATH} ]; then
360                         if [ ! -e ${FIRMPATH} ]; then
361                                 echo ""
362                                 echo "  The file '${FIRMPATH}' was not found"
363                                 echo ""
364                                 echo -n "       Press enter to try again, or ^C to quit. "
365                                 read KEYPRESS
366                                 continue
367                         fi
368                         if ! ${NDISCVT} -f ${FIRMPATH} > /dev/null; then
369                                 echo ""
370                                 echo "CONVERSION FAILED"
371                         else
372                                 echo ""
373                                 echo "  Conversion was successful."
374                                 echo ""
375                                 FRMBASE=`${BASENAME} ${FIRMPATH}`
376                                 FRMBASE="${FRMBASE}.o"
377                                 FRMLIST="${FRMLIST} ${FRMBASE}"
378                         fi
379                         echo -n "       Press enter to continue... "
380                         read KEYPRESS
381                 else
382                         break
383                 fi
384         done
385
386 header
387 echo ""
388 echo "  List of files converted firmware files:"
389 echo ""
390 for i in ${FRMLIST}
391 do
392         echo "  "$i
393 done
394 echo ""
395 echo -n "       Press enter to continue... "
396 read KEYPRESS
397 return
398 }
399
400 drvgen () {
401 header
402 echo "                  Kernel module generation"
403 echo ""
404 echo ""
405 echo "  The script will now try to generate the kernel driver module."
406 echo "  This is the last step. Once this module is generated, you should"
407 echo "  be able to load it just like any other FreeBSD driver module."
408 echo ""
409 echo "  Press enter to compile the stub module and generate the driver"
410 echo -n "       module now: "
411 read KEYPRESS
412 echo ""
413 echo -n "       Generating Makefile... "
414 echo ".PATH:  ${PWD} ${STUBPATH}"                               >  ${MAKEFILE}
415 echo "KMOD= ${SYSBASE}"                                         >> ${MAKEFILE}
416 echo "SRCS+= ${STUBFILE} ${DNAME}.h bus_if.h device_if.h"       >> ${MAKEFILE}
417 echo "OBJS+=${FRMLIST} ${DNAME}.o"                              >> ${MAKEFILE}
418 echo "CFLAGS+=  \\"                                             >> ${MAKEFILE}
419 echo "  -DDRV_DATA_START=ndis_${SYSBASE}_drv_data_start \\"             >> ${MAKEFILE}
420 echo "  -DDRV_NAME=ndis_${SYSBASE} \\"                          >> ${MAKEFILE}
421 echo "  -DDRV_DATA_END=ndis_${SYSBASE}_drv_data_end"                    >> ${MAKEFILE}
422 echo "CLEANFILES+=      \\"                                     >> ${MAKEFILE}
423 echo "  ${INFFILE} \\"                                          >> ${MAKEFILE}
424 echo "  ${DNAME}.h \\"                                          >> ${MAKEFILE}
425 echo "  ${DNAME}.o"                                             >> ${MAKEFILE}
426 echo ".include <bsd.kmod.mk>"                                   >> ${MAKEFILE}
427 if [ -f ${MAKEFILE} ]; then
428         echo "done."
429 else
430         echo "generating Makefile failed. Exiting."
431         echo ""
432         exit
433 fi
434 echo -n "       Building kernel module... "
435 echo "" > bus_if.h
436 echo "" > device_if.h
437 if ! ${MAKE} -f ${MAKEFILE} all > /dev/null; then
438         echo "build failed. Exiting."
439         echo ""
440         exit
441 else
442         if [ -f ${SYSBASE}.ko ]; then
443                 ${MV} ${SYSBASE}.ko ${SYSBASE}.kmod
444                 echo "done."
445         else
446                 echo "build failed. Exiting."
447                 echo ""
448                 exit
449         fi
450 fi
451 echo -n "       Cleaning up... "
452 if ! ${MAKE} -f ${MAKEFILE} clean cleandepend > /dev/null; then
453         echo "cleanup failed. Exiting."
454         echo ""
455         exit
456 else
457         echo "done."
458 fi
459 ${RM} ${MAKEFILE}
460 ${MV} ${SYSBASE}.kmod ${SYSBASE}.ko
461 echo ""
462 echo "  The file ${SYSBASE}.ko has been successfully generated."
463 echo "  You can kldload this module to get started."
464 echo ""
465 echo -n "       Press return to exit. "
466 read KEYPRESS
467 echo ""
468 echo ""
469 return
470 }
471
472 convert_driver () {
473         while : ; do
474                 infconv
475                 if [ ${INFPATH} ]; then
476                         break
477                 fi
478         done
479
480         while : ; do
481                 sysconv
482                 if [ ${SYSPATH} ]; then
483                         break
484                 fi
485         done
486
487         ndiscvt
488         firmcvt
489         drvgen
490         return
491 }
492
493 ICONVPATH=/usr/bin/iconv
494 NDISCVT=/usr/sbin/ndiscvt
495 STUBPATH=/usr/share/misc
496 STUBFILE=windrv_stub.c
497 DNAME=windrv
498 CP=/bin/cp
499 MV=/bin/mv
500 RM=/bin/rm
501 TR=/usr/bin/tr
502 FILE=/usr/bin/file
503 EGREP=/usr/bin/egrep
504 MAKE=/usr/bin/make
505 BASENAME=/usr/bin/basename
506 TOUCH=/usr/bin/touch
507 MKTEMP=/usr/bin/mktemp
508
509 MAKEFILE=`${MKTEMP} /tmp/Makefile.XXXXXX`
510 INFFILE=`${MKTEMP} /tmp/ascii_inf.XXXXXX`
511
512 INFPATH=""
513 FRMLIST=""
514 SYSPATH=""
515 SYSBASE=""
516 FRMBASE=""
517
518 if [ -r "$1" -a -r "$2" ]; then
519         # Looks like the user supplied .INF and .SYS files on the command line
520         INFPATH=$1
521         SYSPATH=$2
522         convert_driver && exit 0
523 fi
524
525 while : ; do
526         mainmenu
527         case ${KEYPRESS} in
528         1)
529                 help1
530                 help2
531                 help3
532                 help4
533                 help5
534                 ;;
535         2)
536                 firmcvt
537                 ;;
538         3)
539                 convert_driver
540                 ;;
541         4)
542                 header
543                 echo ""
544                 echo "  Be seeing you!"
545                 echo ""
546                 exit
547                 ;;
548         *)
549                 header
550                 echo ""
551                 echo -n "       Sorry, I didn't understand that. Press enter to try again: "
552                 read KEYPRESS
553                 ;;
554         esac
555 done
556 exit