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