]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
find remove
[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/initrd ] ; then
32         . /etc/sysconfig/initrd
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                 (cd $name;my_find $1/$name $2)
70            else
71                 [ -f $name -a "$name" = "$2" ] && echo $1/$name
72            fi
73         done
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             
141         --fstab*)
142             if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
143                 fstab="`echo $1 | awk -F= '{print $2;}'`"
144             else
145                 fstab="$2"
146                 shift
147             fi              
148             ;;
149
150         --with*)
151             if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
152                 modname="`echo $1 | awk -F= '{print $2;}'`"
153             else
154                 modname="$2"
155                 shift
156             fi              
157
158             BASICMODULES="$BASICMODULES $modname"
159             ;;
160
161         --version)
162             echo "geninitrd: version $VERSION"
163             exit 0
164             ;;
165
166         -v)
167             verbose=-v
168             ;;
169
170         --nocompress)
171             COMPRESS="no"
172             ;;
173
174         --ifneeded)
175             ifneeded=1
176             ;;
177
178         -f)
179             force=1
180             ;;
181         --preload)
182             if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
183                 modname="`echo $1 | awk -F= '{print $2;}'`"
184             else
185                 modname="$2"
186                 shift
187             fi              
188             PREMODS="$PREMODS $modname"
189             ;;
190         --omit-scsi-modules)
191             PRESCSIMODS=""
192             PROBESCSI="no";
193             ;;
194         --omit-raid-modules)
195             PROBERAID="no";
196             ;;
197         --omit-ide-modules)
198             PROBEIDE="no";
199             ;;
200         --fs)
201             FS="$2"
202             shift
203             ;;
204         --fs*)
205             FS="`echo $1 | awk -F= '{print $2;}'`"
206             ;;
207         --image-version)
208             img_vers=yes
209             ;;
210         *)
211             if [ -z "$target" ]; then
212                 target="$1"
213             elif [ -z "$kernel" ]; then
214                 kernel="$1"
215             else
216                 usage
217             fi
218             ;;
219     esac
220
221     shift
222 done
223
224 if [ -z "$target" -o -z "$kernel" ]; then
225     usage
226 fi
227
228 case "$FS" in
229         ext2)
230                 if [ ! -x /sbin/mke2fs ]; then
231                         echo "mke2fs is missing"
232                         exit 1
233                 fi
234                 ;;
235         rom)
236                 if [ ! -x /sbin/genromfs ]; then
237                         echo "genromfs is missing"
238                         exit 1
239                 fi
240                 ;;
241         cram)
242                 if [ ! -x /sbin/mkcramfs ]; then
243                         echo "mkcramfs is missing"
244                         exit 1
245                 fi
246                  ;;
247         *)
248                 echo "Filesystem $FS not supported"
249                 exit 1
250                 ;;
251 esac
252
253 if [ -n "$img_vers" ]; then
254     target="$target-$kernel"
255 fi
256
257 if [ -z "$force" -a -f "$target" ]; then
258     echo "$target already exists." >&2
259     exit 1
260 fi
261
262 if [ ! -d "/lib/modules/$kernel" ]; then
263     echo "/lib/modules/$kernel is not a directory." >&2
264     exit 1
265 fi
266
267 for n in $PREMODS; do
268         findmodule "$n"
269 done
270
271 rootdev="$(awk '{ if ($2 == "/") { print $1; }}' $fstab)"
272 if is_yes "$PROBESCSI" && is_yes "$(echo "$rootdev" | awk '/^\/dev\/sd/ { print "yes"; }')" ; then
273
274     for n in $PRESCSIMODS; do
275         if [ "$n" = "unknown" ] ; then
276                 if [ ! -f "$modulefile" ]; then
277                         modulefile=/etc/conf.modules
278                 fi
279                 if [ -f "$modulefile" ]; then
280                         scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
281                         for n in $scsimodules; do
282                 # for now allow scsi modules to come from anywhere.  There are some
283                 # RAID controllers with drivers in block/
284                                 findmodule "$n"
285                         done
286                 fi
287         else
288             findmodule "$n"
289         fi
290     done
291
292 fi
293
294 if is_yes "$PROBEIDE" && is_yes "`echo "$rootdev" | awk '/^\/dev\/hd/ { print "yes"; }'`" ; then
295     for n in $PREIDEMODS; do
296             findmodule "$n"
297     done
298 fi
299
300 if is_yes "$PROBERAID" ; then
301     # load appropriate raid devices if necessary
302     if is_yes "`awk '/^\/dev\/md/ && ! /noauto/ { print "yes"; }' "$fstab"`" ; then
303         for number in $(awk '/^[\t ]*raid-level/ { print $2; }' /etc/raidtab | LC_ALL=C sort -u) ; do
304             case "$number" in
305             [0145])
306                 findmodule "raid$number"
307                 ;;
308             *)
309                 echo "raid level $number (in /etc/raidtab) not recognized" >&2
310                 ;;
311             esac
312         done
313     fi
314 fi
315
316 # check to see if we need to set up a loopback filesystem
317 if is_yes "`echo "$rootdev" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
318     if [ ! -x /sbin/losetup ]; then
319         echo "losetup is missing"
320         exit 1
321     fi
322     key="^# $(echo $rootdev | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
323     if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
324         echo "The root filesystem is on a $rootdev, but there is no magic entry in $fstab" 1>&2
325         echo "for this device. Consult the geninitrd man page for more information" 2>&2
326         exit 1
327     fi
328
329     line="`awk '/'$key'/ { print $0; }' $fstab`"
330     loopDev="$(echo $line | awk '{print $3}')"
331     loopFs="$(echo $line | awk '{print $4}')"
332     loopFile="$(echo $line | awk '{print $5}')"
333
334     BASICMODULES="$BASICMODULES -loop"
335     findmodule "-$loopFs"
336     BASICMODULES="$BASICMODULES -${loopFs}"
337     # don't have any clue, how is this supposed to work,
338     # anyway no bsp
339     USEBSP="no"
340 else # Check for other filesystems
341     rootFs="`awk '{if ($2 == "/") {print $3}}' $fstab`"
342     findmodule "-$rootFs"
343 fi
344
345 for n in $BASICMODULES; do 
346     findmodule "$n"
347 done
348
349 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
350     if [ -n "$verbose" ]; then
351         echo "No modules are needed -- not building initrd image."
352     fi
353     exit 0
354 fi
355
356 if [ -n "$verbose" ]; then
357     echo "Using modules: $MODULES"
358 fi
359
360 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
361 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
362 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
363 RCFILE="$MNTIMAGE/linuxrc"
364
365 if [ -f "$MNTIMAGE" ]; then
366     echo "$MNTIMAGE already exists.  Remove it and try again" >&2
367     exit 1
368 fi
369
370 if [ -f "$IMAGE" ]; then
371     echo "$IMAGE already exists. Remove it and try again" >&2
372     exit 1
373 fi
374
375 if [ "$FS" = "ext2" ] ; then
376         dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
377
378         # We have to "echo y |" so that it doesn't complain about $IMAGE not
379         # being a block device
380         echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
381
382         mkdir -p "$MNTPOINT"
383         mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
384 else
385         mkdir -p "$MNTPOINT"
386 fi
387
388
389 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
390
391
392 # We don't need this directory, so let's save space
393 rm -rf "$MNTPOINT"/lost+found
394
395 for MODULE in $MODULES; do
396     cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib"
397 done
398
399 # mknod'ing the devices instead of copying them works both with and
400 # without devfs...
401 mknod "$MNTIMAGE/dev/console" c 5 1
402
403 if is_yes "$USEBSP" ; then
404     s="$MNTIMAGE/etc/startup"
405     inst /sbin/bsp "$RCFILE"
406     echo "# autogenerated startup" > "$s"
407     echo "" >> "$s"
408     
409     for MODULE in $MODULES; do
410         module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
411         options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
412     
413         if [ -n "$verbose" ]; then
414             echo "Loading module $module with options $options"
415         fi
416         echo "insmod $module.o $options" >> "$s"
417     done
418 else
419     inst /bin/trash "$MNTIMAGE/bin/sh"
420     inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
421     
422     mknod "$MNTIMAGE/dev/null" c 1 3
423     mknod "$MNTIMAGE/dev/ram" b 1 1
424     mknod "$MNTIMAGE/dev/systty" c 4 0
425     for i in 1 2 3 4; do
426         mknod "$MNTIMAGE/dev/tty$i" c 4 1
427     done
428     mknod "$MNTIMAGE/dev/zero" c 1 5
429     
430     echo "#!/bin/sh" > "$RCFILE"
431     echo "" >> "$RCFILE"
432     
433     for MODULE in $MODULES; do
434         module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
435         options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
436     
437         if [ -n "$verbose" ]; then
438             echo "Loading module $module with options $options"
439         fi
440         echo "echo \"Loading $module module\"" >> "$RCFILE"
441         echo "insmod /lib/$module.o $options" >> "$RCFILE"
442     done
443     
444     if [ -n "$loopDev" ]; then
445         if [ ! -d /initrd ]; then
446         mkdir /initrd
447         fi
448     
449         cp -a "$loopDev" "$MNTIMAGE/dev"
450         cp -a "$rootdev" "$MNTIMAGE/dev"
451         echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
452         echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
453         echo "echo Setting up loopback device $rootdev" >> $RCFILE
454         echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
455     fi
456 fi
457
458 chmod +x "$RCFILE"
459
460 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
461
462 case "$FS" in
463         ext2)
464                 umount "$IMAGE"
465                 ;;
466         rom)
467                 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
468                 ;;
469         cram)
470                 mkcramfs "$MNTPOINT" "$IMAGE"
471                 ;;
472         *)
473                 echo "Filesystem $FS not supported by $0";
474 esac            
475
476 if is_yes "$COMPRESS" ; then
477     gzip -9 < "$IMAGE" > "$target"
478 else
479     cp -a "$IMAGE" "$target"
480 fi
481 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"
This page took 0.053847 seconds and 3 git commands to generate.