]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
options handling fixes
[projects/geninitrd.git] / geninitrd
1 #!/bin/sh
2
3 # geninitrd
4 #
5 #       by Jacek Konieczny <jajcus@pld.org.pl>
6 #
7 # based on mkinitrd from RedHat
8 #
9 PATH=/sbin:$PATH
10 export PATH
11
12 VERSION=%VERSIONTAG%
13
14 . /etc/rc.d/init.d/functions
15
16 COMPRESS="yes"
17 FS="rom"
18 PROBESCSI="yes"
19 PROBEIDE="yes"
20 PROBERAID="yes"
21 USEBSP="yes"
22
23 if [ -f /etc/sysconfig/geninitrd ] ; then
24         . /etc/sysconfig/geninitrd
25 fi
26
27 if is_yes $USEBSP ; then
28         [ ! -x /sbin/bsp ] && USEBSP="no"
29 fi
30 target=""
31 kernel=""
32 force=""
33 verbose=""
34 MODULES=""
35 img_vers=""
36 modulefile=/etc/modules.conf
37 if [ "`uname -m`" = "ia64" ]; then
38         IMAGESIZE=3000
39 else
40         IMAGESIZE=1500
41 fi
42 PRESCSIMODS="scsi_mod unknown sd_mod"
43 PREIDEMODS="ide-mod ide-probe ide-probe-mod ide-disk"
44 fstab="/etc/fstab"
45
46 usage () {
47         echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" >&2
48         echo "       [--omit-scsi-modules] [--omit-raid-modules] [--omit-ide-modules]" >&2
49         echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" >&2 
50         echo "       [--fs=rom|ext2|cram] [--no-bsp]" >&2
51         echo "       <initrd-image> <kernel-version>" >&2
52         echo "       (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" >&2
53         exit 1
54 }
55
56
57 my_find() {
58         for name in `ls`
59         do
60                 if [ -d $name ]; then
61                         if [ "$name" != "build" ]; then
62                                 (cd $name;my_find $1/$name $2)
63                         fi
64                 else
65                         if [ -f $name -a "$name" = "$2" ]; then
66                                 echo $1/$name
67                         fi
68                 fi
69         done
70 }
71
72 my_dirname() {
73         echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
74 }
75
76 findmodule() {
77         skiperrors=""
78         modName=$1
79         if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
80                 skiperrors=1
81                 modName="$(echo $modName | awk '{print(substr($0,2));}')"
82         fi
83
84         if [ "$modName" = "pluto" ]; then
85                 findmodule fc4
86                 findmodule soc
87         fi
88         if [ "$modName" = "fcal" ]; then
89                 findmodule fc4
90                 findmodule socal
91         fi
92
93         fmPath="`(cd /lib/modules/$kernel; my_find . "$modName.o")`"
94
95         if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
96                 if [ -n "$skiperrors" ]; then
97                         return
98                 fi
99
100                 # ignore the absence of the scsi modules
101                 for n in $PRESCSIMODS; do
102                         if [ "$n" = "$modName" ]; then
103                                 return;
104                         fi
105                 done;
106
107                 # ignore the absence of the ide modules
108                 for n in $PREIDEMODS; do
109                         if [ "$n" = "$modName" ]; then
110                                 return;
111                         fi
112                 done;
113     
114                 echo "No module $modName found for kernel $kernel" >&2
115                 exit 1
116         fi
117
118         # only need to add each module once
119         tmpFmPath="`echo "$fmPath"|awk -F/ '{for(i=1;i<NF;i++) { printf("%s\\\\/",$i); } { print $NF; }}'`"
120         if is_yes "`echo "$MODULES" | awk '/"'$tmpFmPath'"/ { print "yes"; }' `" ; then : ; else
121                 MODULES="$MODULES $fmPath"
122         fi
123 }
124
125 inst() {
126         if [ "$#" != "2" ];then
127                 echo "usage: inst <file> <destination>"
128                 return
129         fi 
130         [ -n "$verbose" ] && echo "$1 -> $2"
131         cp "$1" "$2"
132 }
133
134
135 while [ $# -gt 0 ]; do
136         case $1 in
137         --no-bsp)
138                 USEBSP="no"
139                 ;;
140         --fstab*)
141                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
142                         fstab="`echo $1 | awk -F= '{print $2;}'`"
143                 else
144                         fstab="$2"
145                         shift
146                 fi                  
147                 ;;
148         --with*)
149                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
150                         modname="`echo $1 | awk -F= '{print $2;}'`"
151                 else
152                         modname="$2"
153                         shift
154                 fi                  
155
156                 BASICMODULES="$BASICMODULES $modname"
157                 ;;
158         --version)
159                 echo "geninitrd: version $VERSION"
160                 exit 0
161                 ;;
162         -v)
163                 verbose=-v
164                 ;;
165         --nocompress)
166                 COMPRESS="no"
167                 ;;
168         --ifneeded)
169                 ifneeded=1
170                 ;;
171         -f)
172                 force=1
173                 ;;
174         --preload*)
175                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
176                         modname="`echo $1 | awk -F= '{print $2;}'`"
177                 else
178                         modname="$2"
179                         shift
180                 fi                  
181                 PREMODS="$PREMODS $modname"
182                 ;;
183         --omit-scsi-modules)
184                 PRESCSIMODS=""
185                 PROBESCSI="no";
186                 ;;
187         --omit-raid-modules)
188                 PROBERAID="no";
189                 ;;
190         --omit-ide-modules)
191                 PROBEIDE="no";
192                 ;;
193         --fs)
194                 FS="$2"
195                 shift
196                 ;;
197         --fs=*)
198                 FS="`echo $1 | awk -F= '{print $2;}'`"
199                 ;;
200         --image-version)
201                 img_vers=yes
202                 ;;
203         *)
204                 if [ -z "$target" ]; then
205                         target="$1"
206                 elif [ -z "$kernel" ]; then
207                         kernel="$1"
208                 else
209                         usage
210                 fi
211                 ;;
212         esac
213
214         shift
215 done
216
217 if [ -z "$target" -o -z "$kernel" ]; then
218         usage
219 fi
220
221 case "$FS" in
222         ext2)
223                 if [ ! -x /sbin/mke2fs ]; then
224                         echo "/sbin/mke2fs is missing"
225                         exit 1
226                 fi
227                 ;;
228         rom)
229                 if [ ! -x /sbin/genromfs ]; then
230                         echo "/sbin/genromfs is missing"
231                         exit 1
232                 fi
233                 ;;
234         cram)
235                 if [ ! -x /sbin/mkcramfs ]; then
236                         echo "/sbin/mkcramfs is missing"
237                         exit 1
238                 fi
239                  ;;
240         *)
241                 echo "Filesystem $FS not supported"
242                 exit 1
243                 ;;
244 esac
245
246 if [ -n "$img_vers" ]; then
247         target="$target-$kernel"
248 fi
249
250 if [ -z "$force" -a -f "$target" ]; then
251         echo "$target already exists." >&2
252         exit 1
253 fi
254
255 if [ ! -d "/lib/modules/$kernel" ]; then
256         echo "/lib/modules/$kernel is not a directory." >&2
257         exit 1
258 fi
259
260 for n in $PREMODS; do
261         findmodule "$n"
262 done
263
264 rootdev="$(awk '{ if ($2 == "/") { print $1; }}' $fstab)"
265 if is_yes "$PROBESCSI" && is_yes "$(echo "$rootdev" | awk '/^\/dev\/sd/ { print "yes"; }')" ; then
266
267     for n in $PRESCSIMODS; do
268         if [ "$n" = "unknown" ] ; then
269                 if [ ! -f "$modulefile" ]; then
270                         modulefile=/etc/conf.modules
271                 fi
272                 if [ -f "$modulefile" ]; then
273                         scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
274                         for n in $scsimodules; do
275                 # for now allow scsi modules to come from anywhere.  There are some
276                 # RAID controllers with drivers in block/
277                                 findmodule "$n"
278                         done
279                 fi
280         else
281                 findmodule "$n"
282         fi
283     done
284
285 fi
286
287 if is_yes "$PROBEIDE" && is_yes "`echo "$rootdev" | awk '/^\/dev\/hd/ { print "yes"; }'`" ; then
288     for n in $PREIDEMODS; do
289             findmodule "$n"
290     done
291 fi
292
293 if is_yes "$PROBERAID" ; then
294     # load appropriate raid devices if necessary
295     if is_yes "`awk '/^\/dev\/md/ && ! /noauto/ { print "yes"; }' "$fstab"`" ; then
296         for number in $(awk '/^[\t ]*raid-level/ { print $2; }' /etc/raidtab | LC_ALL=C sort -u) ; do
297             case "$number" in
298             [0145])
299                 findmodule "raid$number"
300                 ;;
301             *)
302                 echo "raid level $number (in /etc/raidtab) not recognized" >&2
303                 ;;
304             esac
305         done
306     fi
307 fi
308
309 # check to see if we need to set up a loopback filesystem
310 if is_yes "`echo "$rootdev" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
311         if [ ! -x /sbin/losetup ]; then
312                 echo "losetup is missing"
313                 exit 1
314         fi
315         key="^# $(echo $rootdev | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
316         if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
317                 echo "The root filesystem is on a $rootdev, but there is no magic entry in $fstab" 1>&2
318                 echo "for this device. Consult the geninitrd man page for more information" 2>&2
319                 exit 1
320         fi
321
322         line="`awk '/'$key'/ { print $0; }' $fstab`"
323         loopDev="$(echo $line | awk '{print $3}')"
324         loopFs="$(echo $line | awk '{print $4}')"
325         loopFile="$(echo $line | awk '{print $5}')"
326
327         BASICMODULES="$BASICMODULES -loop"
328         findmodule "-$loopFs"
329         BASICMODULES="$BASICMODULES -${loopFs}"
330         # don't have any clue, how is this supposed to work,
331         # anyway no bsp
332         USEBSP="no"
333 else # Check for other filesystems
334         rootFs="`awk '{if ($2 == "/") {print $3}}' $fstab`"
335         findmodule "-$rootFs"
336 fi
337
338 for n in $BASICMODULES; do 
339         findmodule "$n"
340 done
341
342 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
343         if [ -n "$verbose" ]; then
344                 echo "No modules are needed -- not building initrd image."
345         fi
346         exit 0
347 fi
348
349 if [ -n "$verbose" ]; then
350         echo "Using modules: $MODULES"
351 fi
352
353 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
354 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
355 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
356 RCFILE="$MNTIMAGE/linuxrc"
357
358 if [ -f "$MNTIMAGE" ]; then
359         echo "$MNTIMAGE already exists.  Remove it and try again" >&2
360         exit 1
361 fi
362
363 if [ -f "$IMAGE" ]; then
364         echo "$IMAGE already exists. Remove it and try again" >&2
365         exit 1
366 fi
367
368 if [ "$FS" = "ext2" ] ; then
369         dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
370
371         # We have to "echo y |" so that it doesn't complain about $IMAGE not
372         # being a block device
373         echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
374
375         mkdir -p "$MNTPOINT"
376         mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
377 else
378         mkdir -p "$MNTPOINT"
379 fi
380
381
382 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
383
384
385 # We don't need this directory, so let's save space
386 rm -rf "$MNTPOINT"/lost+found
387
388 for MODULE in $MODULES; do
389         MODULEDIR="`my_dirname "$MODULE"`"
390         mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
391         cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
392 done
393
394 # mknod'ing the devices instead of copying them works both with and
395 # without devfs...
396 mknod "$MNTIMAGE/dev/console" c 5 1
397
398 if is_yes "$USEBSP" ; then
399         s="$MNTIMAGE/etc/startup"
400         inst /sbin/bsp "$RCFILE"
401         echo "# autogenerated startup" > "$s"
402         echo "" >> "$s"
403     
404         for MODULE in $MODULES; do
405                 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
406                 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
407     
408                 if [ -n "$verbose" ]; then
409                         echo "Loading module $module with options $options"
410                 fi
411                 echo "insmod /lib/modules/$kernel/$MODULE $options" >> "$s"
412         done
413 else
414         inst /bin/trash "$MNTIMAGE/bin/sh"
415         inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
416     
417         mknod "$MNTIMAGE/dev/null" c 1 3
418         mknod "$MNTIMAGE/dev/ram" b 1 1
419         mknod "$MNTIMAGE/dev/systty" c 4 0
420         for i in 1 2 3 4; do
421                 mknod "$MNTIMAGE/dev/tty$i" c 4 1
422         done
423         mknod "$MNTIMAGE/dev/zero" c 1 5
424     
425         echo "#!/bin/sh" > "$RCFILE"
426         echo "" >> "$RCFILE"
427     
428         for MODULE in $MODULES; do
429                 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
430                 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
431
432                 if [ -n "$verbose" ]; then
433                         echo "Loading module $module with options $options"
434                 fi
435                 echo "Add module $module to initrd."
436                 echo "echo \"Loading $module module\"" >> "$RCFILE"
437                 echo "insmod -k /lib/modules/$kernel/$MODULE $options" >> "$RCFILE"
438         done
439
440         if [ -n "$loopDev" ]; then
441                 if [ ! -d /initrd ]; then
442                         mkdir /initrd
443                 fi
444     
445                 cp -a "$loopDev" "$MNTIMAGE/dev"
446                 cp -a "$rootdev" "$MNTIMAGE/dev"
447                 echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
448                 echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
449                 echo "echo Setting up loopback device $rootdev" >> $RCFILE
450                 echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
451         fi
452 fi
453
454 chmod +x "$RCFILE"
455
456 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
457
458 case "$FS" in
459         ext2)
460                 umount "$IMAGE"
461                 ;;
462         rom)
463                 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
464                 ;;
465         cram)
466                 mkcramfs "$MNTPOINT" "$IMAGE"
467                 ;;
468         *)
469                 echo "Filesystem $FS not supported by $0";
470 esac            
471
472 if is_yes "$COMPRESS" ; then
473         gzip -9 < "$IMAGE" > "$target"
474 else
475         cp -a "$IMAGE" "$target"
476 fi
477 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"
This page took 0.094874 seconds and 4 git commands to generate.