]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
- fix generating SCSI-enabled initrd (typo)
[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]" >&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 if [ "$FS" != "ext2" -a "$FS" != "rom" ] ; then
211     echo "Only ext2 and rom fs are supported!"
212 fi
213
214 if [ -z "$target" -o -z "$kernel" ]; then
215     usage
216 fi
217
218 if [ -n "$img_vers" ]; then
219     target="$target-$kernel"
220 fi
221
222 if [ -z "$force" -a -f $target ]; then
223     echo "$target already exists." >&2
224     exit 1
225 fi
226
227 if [ ! -d /lib/modules/$kernel ]; then
228     echo "/lib/modules/$kernel is not a directory." >&2
229     exit 1
230 fi
231
232 for n in $PREMODS; do
233         findmodule "" $n
234 done
235
236 rootdev=$(awk '{ if ($2 == "/") { print $1; }}' $fstab)
237 if is_yes "$PROBESCSI" && echo "$rootdev" | grep -q "^/dev/sd" ; then
238
239     for n in $PRESCSIMODS; do
240             findmodule scsi $n
241     done
242
243     if [ ! -f $modulefile ]; then
244         modulefile=/etc/conf.modules
245     fi
246     if [ -f $modulefile ]; then
247         scsimodules=`grep scsi_hostadapter $modulefile | grep -v '^[    ]*#' | LC_ALL=C sort -u | awk '{ print $3 }'`
248         for n in $scsimodules; do
249     # for now allow scsi modules to come from anywhere.  There are some
250     # RAID controllers with drivers in block/
251             findmodule "" $n
252         done
253     fi
254 fi
255
256 if is_yes "$PROBEIDE" && echo "$rootdev" | grep -q "^/dev/hd" ; then
257     for n in $PREIDEMODS; do
258             findmodule block $n
259     done
260 fi
261
262 if is_yes "$PROBERAID" ; then
263     # load appropriate raid devices if necessary
264     if grep '^/dev/md' $fstab | grep -v noauto >/dev/null 2>&1 ; then
265         for number in $(grep '^[        ]*raid-level' /etc/raidtab |
266                           awk '{print $2}' | LC_ALL=C sort -u) ; do
267             case $number in
268             [0145])
269                 findmodule "" raid$number
270                 ;;
271             *)
272                 echo "raid level $number (in /etc/raidtab) not recognized" >&2
273                 ;;
274             esac
275         done
276     fi
277 fi
278
279 # check to see if we need to set up a loopback filesystem
280 if echo $rootdev | cut -d/ -f3 | grep loop >/dev/null; then
281     key="^# $(echo $rootdev | cut -d/ -f3 | tr '[a-z]' '[A-Z]'):"
282     if ! grep "$key" $fstab > /dev/null; then
283         echo "The root filesystem is on a $rootdev, but there is no magic entry in $fstab" 1>&2
284         echo "for this device. Consult the geninitrd man page for more information" 2>&2
285         exit 1
286     fi
287
288     line=$(grep "$key" $fstab)
289     loopDev=$(echo $line | awk '{print $3}')
290     loopFs=$(echo $line | awk '{print $4}')
291     loopFile=$(echo $line | awk '{print $5}')
292
293     BASICMODULES="$BASICMODULES -loop"
294     findmodule fs "-$loopFs"
295     BASICMODULES="$BASICMODULES -${loopFs}"
296 else # Check for other filesystems
297     rootFs=`awk '{if ($2 == "/") {print $3}}' $fstab`
298     findmodule fs "-$rootFs"
299 fi
300
301 for n in $BASICMODULES; do 
302     findmodule "" $n
303 done
304
305 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
306     if [ -n "$verbose" ]; then
307         echo "No modules are needed -- not building initrd image."
308     fi
309     exit 0
310 fi
311
312 if [ -n "$verbose" ]; then
313     echo "Using modules: $MODULES"
314 fi
315
316 MNTIMAGE=/tmp/initrd.$$
317 IMAGE=/tmp/initrd.img-$$
318 MNTPOINT=/tmp/initrd.mnt-$$
319 RCFILE=$MNTIMAGE/linuxrc
320
321 if [ -f $MNTIMAGE ]; then
322     echo "$MNTIMAGE already exists.  Remove it and try again" >&2
323     exit 1
324 fi
325
326 if [ -f $IMAGE ]; then
327     echo "$IMAGE already exists. Remove it and try again" >&2
328     exit 1
329 fi
330
331 if [ "$FS" = "ext2" ] ; then
332         dd if=/dev/zero of=$IMAGE bs=1k count=$IMAGESIZE 2> /dev/null
333
334         if [ -e /dev/.devfsd ]; then
335                 LOOPDEV=/dev/loop/
336         else
337                 LOOPDEV=/dev/loop
338         fi
339
340         for devnum in 0 1 2 3 4 5 6 7 8; do
341             if losetup ${LOOPDEV}${devnum} $IMAGE 2>/dev/null ; then break; fi
342         done
343
344         if [ "$devnum" = "8" ]; then
345             rm -rf $MNTPOINT $IMAGE
346             echo "All of your loopback devices are in use!" >&2
347             exit 1
348         fi
349
350         LODEV=${LOOPDEV}${devnum}
351
352         # We have to "echo y |" so that it doesn't complain about $IMAGE not
353         # being a block device
354         echo y | mke2fs $LODEV $IMAGESIZE >/dev/null 2>/dev/null
355
356         if [ -n "$verbose" ]; then
357             echo "Using loopback device $LODEV"
358         fi
359
360         mkdir -p $MNTPOINT
361         mount -t ext2 $LODEV $MNTPOINT || {
362                 echo "Can't get a loopback device"
363                 exit 1
364         }
365 else
366         mkdir -p $MNTPOINT
367 fi
368
369 mkdir -p $MNTIMAGE
370 mkdir -p $MNTIMAGE/lib
371 mkdir -p $MNTIMAGE/bin
372 mkdir -p $MNTIMAGE/etc
373 mkdir -p $MNTIMAGE/dev
374 mkdir -p $MNTIMAGE/loopfs
375
376 # We don't need this directory, so let's save space
377 rm -rf $MNTPOINT/lost+found
378
379 inst /bin/ash.static "$MNTIMAGE/bin/sh"
380 inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
381
382 for MODULE in $MODULES; do
383     cp $verbose -a /lib/modules/$kernel/$MODULE $MNTIMAGE/lib
384 done
385
386 # mknod'ing the devices instead of copying them works both with and
387 # without devfs...
388 mknod $MNTIMAGE/dev/console c 5 1
389 mknod $MNTIMAGE/dev/null c 1 3
390 mknod $MNTIMAGE/dev/ram b 1 1
391 mknod $MNTIMAGE/dev/systty c 4 0
392 for i in 1 2 3 4; do
393     mknod $MNTIMAGE/dev/tty$i c 4 1
394 done
395
396 echo "#!/bin/sh" > $RCFILE
397 echo "" >> $RCFILE
398
399 for MODULE in $MODULES; do
400     module=`echo $MODULE | sed "s|.*/||" | sed "s/.o$//"`
401
402     options=`sed -n -e "s/^options[     ][      ]*$module[      ][      ]*//p" $modulefile`
403
404     if [ -n "$verbose" ]; then
405         echo "Loading module $module with options $options"
406     fi
407     echo "echo \"Loading $module module\"" >> $RCFILE
408     echo "insmod /lib/$module.o $options" >> $RCFILE
409 done
410
411 if [ -n "$loopDev" ]; then
412     if [ ! -d /initrd ]; then
413         mkdir /initrd
414     fi
415
416     cp -a $loopDev $MNTIMAGE/dev
417     cp -a $rootdev $MNTIMAGE/dev
418     echo "echo Mounting device containing loopback root filesystem" >> $RCFILE
419     echo "mount -t $loopFs $loopDev /loopfs" >> $RCFILE
420     echo "echo Setting up loopback device $rootdev" >> $RCFILE
421     echo "losetup $rootdev /loopfs$loopFile" >> $RCFILE
422 fi
423
424 chmod +x $RCFILE
425
426 (cd $MNTIMAGE; tar cf - .) | (cd $MNTPOINT; tar xf -)
427
428 if [ "$FS" = "ext2" ] ; then
429         mount $MNTPOINT
430         losetup -d $LODEV
431 else
432         genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
433         
434 fi
435
436 if is_yes "$COMPRESS" ; then
437     gzip -9 < $IMAGE > $target
438 else
439     cp -a $IMAGE $target
440 fi
441 rm -rf $MNTIMAGE $MNTPOINT $IMAGE
442
This page took 0.049553 seconds and 4 git commands to generate.