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