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