Annotation of /trunk/mkinitrd-magellan/livecd/mkinitrd-livecd.in
Parent Directory | Revision Log
Revision 1876 -
(hide annotations)
(download)
Wed Jul 11 09:57:18 2012 UTC (12 years, 2 months ago) by niro
File size: 10468 byte(s)
Wed Jul 11 09:57:18 2012 UTC (12 years, 2 months ago) by niro
File size: 10468 byte(s)
-include missing firmware blobs in initrd
1 | niro | 562 | #!/bin/bash |
2 | niro | 810 | # $Id$ |
3 | niro | 562 | |
4 | # mkinitrd-livecd | ||
5 | # | ||
6 | # Copyright 2005 Red Hat, Inc. | ||
7 | # | ||
8 | # Written by Erik Troan <ewt@redhat.com> | ||
9 | # | ||
10 | # Contributors: | ||
11 | # Elliot Lee <sopwith@cuc.edu> | ||
12 | # Miguel de Icaza <miguel@nuclecu.unam.mx> | ||
13 | # Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de> | ||
14 | # Michael K. Johnson <johnsonm@redhat.com> | ||
15 | # Pierre Habraken <Pierre.Habraken@ujf-grenoble.fr> | ||
16 | # Jakub Jelinek <jakub@redhat.com> | ||
17 | # Carlo Arenas Belon (carenas@chasqui.lared.net.pe> | ||
18 | # Keith Owens <kaos@ocs.com.au> | ||
19 | # Bernhard Rosenkraenzer <bero@redhat.com> | ||
20 | # Matt Wilson <msw@redhat.com> | ||
21 | # Trond Eivind Glomsrød <teg@redhat.com> | ||
22 | # Jeremy Katz <katzj@redhat.com> | ||
23 | # Preston Brown <pbrown@redhat.com> | ||
24 | # Bill Nottingham <notting@redhat.com> | ||
25 | # Guillaume Cottenceau <gc@mandrakesoft.com> | ||
26 | # Peter Jones <pjones@redhat.com> | ||
27 | |||
28 | # heavily modified for magellan-linux by Niels Rogalla <niro@magellan-linux.de> | ||
29 | |||
30 | umask 0022 | ||
31 | export MALLOC_PERTURB_=204 | ||
32 | |||
33 | PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH | ||
34 | export PATH | ||
35 | |||
36 | VERSION=%VERSIONTAG% | ||
37 | |||
38 | MODULES="" | ||
39 | NOSTRIP=false | ||
40 | |||
41 | [ -e /etc/conf.d/mkinitrd-livecd ] && . /etc/conf.d/mkinitrd-livecd | ||
42 | |||
43 | LIBDIR="%LIBDIR%" | ||
44 | LINUXRC="${LIBDIR}/mkinitrd/linuxrc.sh" | ||
45 | MODULES_GENERIC="${LIBDIR}/mkinitrd/modules.generic" | ||
46 | MODULES_USB="${LIBDIR}/mkinitrd/modules.usb" | ||
47 | MODULES_SCSI="${LIBDIR}/mkinitrd/modules.scsi" | ||
48 | MODULES_SATA="${LIBDIR}/mkinitrd/modules.sata" | ||
49 | MODULES_PATA="${LIBDIR}/mkinitrd/modules.pata" | ||
50 | niro | 664 | MODULES_FRAMEBUFFER="${LIBDIR}/mkinitrd/modules.framebuffer" |
51 | niro | 1876 | FIRMWARE_PATH="/lib/firmware" |
52 | FIRMWARE_FILES="" | ||
53 | niro | 562 | |
54 | compress=1 | ||
55 | allowmissing="" | ||
56 | target="" | ||
57 | kernel="" | ||
58 | force="" | ||
59 | verbose="" | ||
60 | img_vers="" | ||
61 | builtins="" | ||
62 | modulefile=/etc/modules.conf | ||
63 | rc=0 | ||
64 | |||
65 | IMAGESIZE=4000 | ||
66 | PRESCSIMODS="sd_mod" | ||
67 | fstab="/etc/fstab" | ||
68 | |||
69 | vg_list="" | ||
70 | |||
71 | die() { echo "Error: $@"; exit 1; } | ||
72 | add_initrd() { echo "$@" >> ${DEST}/init || die; } | ||
73 | |||
74 | DEST="$(mktemp -d)" | ||
75 | IMAGE="$(mktemp)" | ||
76 | |||
77 | usage() | ||
78 | { | ||
79 | echo "usage: $(basename $0) [--version] [--help] [-v] [-f]" | ||
80 | echo " [--image-version] [--no-strip] [--nocompress]" | ||
81 | niro | 664 | echo " [--linuxrc /path/to/custom/linuxrc ]" |
82 | niro | 562 | echo " <initrd-image> <kernel-version>" |
83 | echo | ||
84 | echo " (ex: $(basename $0) /boot/initrd-2.2.5-15.img 2.2.5-15)" | ||
85 | |||
86 | exit 0 | ||
87 | } | ||
88 | |||
89 | moduledep() | ||
90 | { | ||
91 | if [ ! -f "/lib/modules/${kernel}/modules.dep" ] | ||
92 | then | ||
93 | die "No dep file found for kernel ${kernel}" | ||
94 | fi | ||
95 | |||
96 | echo "Looking for deps of module $1" | ||
97 | deps=$(awk 'BEGIN { searched=ARGV[2]; ARGV[2]=""; rc=1 } \ | ||
98 | niro | 1220 | function modname(filename) { match(filename, /\/([^\/]+)\.k?o.?g?z?:?$/, ret); return ret[1] } \ |
99 | niro | 562 | function show() { if (orig == searched) { print dep; orig=""; rc=0; exit } } \ |
100 | niro | 845 | /^.*kernel/ { show(); \ |
101 | niro | 562 | orig=modname($1); dep=""; \ |
102 | if ($2) { for (i = 2; i <= NF; i++) { dep=sprintf("%s %s", dep, modname($i)); } } } \ | ||
103 | /^ / { dep=sprintf("%s %s", dep, modname($1)); } \ | ||
104 | END { show(); exit(rc) }' /lib/modules/${kernel}/modules.dep $1) | ||
105 | [ -n "${deps}" ] && echo ":${deps}" || echo | ||
106 | } | ||
107 | |||
108 | findone() { /usr/bin/find "$@" | /bin/awk '{ print $1; exit; }'; } | ||
109 | findall() { /usr/bin/find "$@"; } | ||
110 | |||
111 | findmodule() | ||
112 | { | ||
113 | skiperrors="" | ||
114 | |||
115 | if [[ $1 = --skiperrors ]] | ||
116 | then | ||
117 | skiperrors=--skiperrors | ||
118 | shift | ||
119 | fi | ||
120 | |||
121 | local modName=$1 | ||
122 | |||
123 | if [ "${modName}" = "off" -o "${modName}" = "null" ] | ||
124 | then | ||
125 | return | ||
126 | fi | ||
127 | |||
128 | if [ $(echo ${modName} | cut -b1) = "-" ] | ||
129 | then | ||
130 | skiperrors=--skiperrors | ||
131 | modName=$(echo ${modName} | cut -b2-) | ||
132 | fi | ||
133 | |||
134 | case "${MODULES} " in | ||
135 | *"/${modName}.ko "*) return ;; | ||
136 | niro | 1220 | *"/${modName}.ko.gz "*) return ;; |
137 | niro | 562 | esac |
138 | |||
139 | if echo ${builtins} | egrep -q '(^| )'${modName}'( |$)' | ||
140 | then | ||
141 | echo "module ${modName} assumed to be built in" | ||
142 | return | ||
143 | fi | ||
144 | |||
145 | # special cases | ||
146 | if [[ ${modName} = i2o_block ]] | ||
147 | then | ||
148 | findmodule i2o_core | ||
149 | findmodule -i2o_pci | ||
150 | modName="i2o_block" | ||
151 | elif [[ ${modName} = ppa ]] | ||
152 | then | ||
153 | findmodule parport | ||
154 | findmodule parport_pc | ||
155 | modName="ppa" | ||
156 | elif [[ ${modName} = sbp2 ]] | ||
157 | then | ||
158 | findmodule ieee1394 | ||
159 | findmodule ohci1394 | ||
160 | modName="sbp2" | ||
161 | else | ||
162 | moduledep ${modName} | ||
163 | for i in ${deps} | ||
164 | do | ||
165 | findmodule ${i} | ||
166 | done | ||
167 | fi | ||
168 | |||
169 | niro | 1220 | for modExt in o.gz o ko ko.gz |
170 | niro | 562 | do |
171 | for modDir in /lib/modules/${kernel}/updates /lib/modules/${kernel} | ||
172 | do | ||
173 | if [ -d ${modDir} ] | ||
174 | then | ||
175 | fmPath=$(findone ${modDir} -name ${modName}.${modExt}) | ||
176 | if [ -f "${fmPath}" ] | ||
177 | then | ||
178 | break 2 | ||
179 | fi | ||
180 | fi | ||
181 | done | ||
182 | done | ||
183 | |||
184 | if [ ! -f ${fmPath} ] | ||
185 | then | ||
186 | if [ -n "${skiperrors}" ] | ||
187 | then | ||
188 | return | ||
189 | fi | ||
190 | |||
191 | # ignore the absence of the scsi modules | ||
192 | for n in ${PRESCSIMODS} | ||
193 | do | ||
194 | if [[ ${n} = ${modName} ]] | ||
195 | then | ||
196 | return | ||
197 | fi | ||
198 | done | ||
199 | |||
200 | if [ -n "${allowmissing}" ] | ||
201 | then | ||
202 | echo "WARNING: No module ${modName} found for kernel ${kernel}, continuing anyway" | ||
203 | return | ||
204 | fi | ||
205 | |||
206 | die "No module ${modName} found for kernel ${kernel}, aborting." | ||
207 | fi | ||
208 | |||
209 | # only need to add each module once | ||
210 | MODULES="${MODULES} ${fmPath}" | ||
211 | } | ||
212 | |||
213 | install_kernel_modules() | ||
214 | { | ||
215 | local list="$1" | ||
216 | local module | ||
217 | |||
218 | niro | 664 | # no list found; return |
219 | [[ -z ${list} ]] && return | ||
220 | |||
221 | niro | 562 | while read module args |
222 | do | ||
223 | case "${module}" in | ||
224 | \#*|"") continue ;; | ||
225 | esac | ||
226 | |||
227 | findmodule ${module} | ||
228 | done << EOF | ||
229 | $(cat ${list}; echo) | ||
230 | EOF | ||
231 | |||
232 | # create empty modules.lala file | ||
233 | :> ${DEST}/etc/$(basename ${list}) | ||
234 | |||
235 | # install detected modules | ||
236 | echo "Coping your modules to '${DEST}/lib' ..." | ||
237 | for MODULE in ${MODULES} | ||
238 | do | ||
239 | if [ -x /usr/bin/strip ] && [[ ${NOSTRIP} = false ]] | ||
240 | then | ||
241 | /usr/bin/strip -g ${verbose} ${MODULE} -o ${DEST}/lib/$(basename ${MODULE}) || die | ||
242 | niro | 1220 | # handle gzip compressed modules right |
243 | elif [[ ${MODULE##*.} = gz ]] | ||
244 | then | ||
245 | zcat ${verbose} ${MODULE} > ${DEST}/lib/$(basename ${MODULE} .gz) || die | ||
246 | MODULE="${MODULE/.gz/}" | ||
247 | niro | 562 | else |
248 | cp ${verbose} -a ${MODULE} ${DEST}/lib || die | ||
249 | fi | ||
250 | |||
251 | # generate modules load file | ||
252 | niro | 1220 | local modname i |
253 | modname="${MODULE##*/}" | ||
254 | for i in .o .ko .gz | ||
255 | do | ||
256 | modname="${modname/${i}/}" | ||
257 | done | ||
258 | echo "${modname}" >> ${DEST}/etc/$(basename ${list}) || die | ||
259 | niro | 1876 | |
260 | # get and install firmware files if neccessary | ||
261 | if [ -x $(which modinfo 2> /dev/null) ] | ||
262 | then | ||
263 | local firmware_blobs | ||
264 | local firmware | ||
265 | module=$(echo ${MODULE} | sed "s|.*/||" | sed -e "s/.k\?o.\?g\?z\?$//" -e "s/.gz//") | ||
266 | firmware_blobs=$(modinfo ${module} | grep 'firmware:' | sed 's:^firmware\:.*[[:space:]]\(.*\):\1:') | ||
267 | if [[ ! -z ${firmware_blobs} ]] | ||
268 | then | ||
269 | for firmware in ${firmware_blobs} | ||
270 | do | ||
271 | add_firmware "${firmware}" | ||
272 | done | ||
273 | fi | ||
274 | if [[ ! -z ${FIRMWARE_FILES} ]] | ||
275 | then | ||
276 | for firmware in ${FIRMWARE_FILES} | ||
277 | do | ||
278 | if [ -e ${FIRMWARE_PATH}/${firmware} ] | ||
279 | then | ||
280 | echo "installing firmware '${firmware}'" | ||
281 | install ${verbose} -d ${DEST}/${FIRMWARE_PATH}/${firmware%/*} || die | ||
282 | cp ${verbose} -a ${FIRMWARE_PATH}/${firmware} ${DEST}/${FIRMWARE_PATH}/${firmware%/*} || die | ||
283 | fi | ||
284 | done | ||
285 | fi | ||
286 | else | ||
287 | echo "Warning 'modinfo' not found" | ||
288 | fi | ||
289 | niro | 562 | done |
290 | |||
291 | export ALL_MODULES="${ALL_MODULES} ${MODULES}" | ||
292 | unset MODULES | ||
293 | } | ||
294 | |||
295 | niro | 1876 | add_firmware() |
296 | { | ||
297 | local firmware="$1" | ||
298 | local i | ||
299 | |||
300 | # check if given firmware is already included in FIRMWARE_FILES | ||
301 | for i in ${FIRMWARE_FILES} | ||
302 | do | ||
303 | [[ ${firmware} = ${i} ]] && return 0 | ||
304 | done | ||
305 | |||
306 | # include firmware | ||
307 | FIRMWARE_FILES="${FIRMWARE_FILES} ${firmware}" | ||
308 | } | ||
309 | |||
310 | niro | 562 | # need r00t privs |
311 | [[ $(id -u) != 0 ]] && die "you must be r00t." | ||
312 | |||
313 | # enforce initramfs method as default | ||
314 | [[ -z ${IMAGE_TYPE} ]] && IMAGE_TYPE=initramfs | ||
315 | |||
316 | while [ $# -gt 0 ]; do | ||
317 | case $1 in | ||
318 | --version) | ||
319 | echo "mkinitrd: version ${VERSION}" | ||
320 | exit 0 | ||
321 | ;; | ||
322 | |||
323 | -v) verbose=-v ;; | ||
324 | -f) force=1 ;; | ||
325 | --nocompress) compress="" ;; | ||
326 | --image-version) img_vers=yes ;; | ||
327 | --allow-missing) allowmissing=yes ;; | ||
328 | --noresume) noresume=1 ;; | ||
329 | --help) usage -n ;; | ||
330 | --initramfs) IMAGE_TYPE=initramfs ;; | ||
331 | --loopback) IMAGE_TYPE=loopback ;; | ||
332 | --no-strip) NOSTRIP=true ;; | ||
333 | niro | 664 | --linuxrc) shift; LINUXRC="$1" ;; |
334 | niro | 562 | *) |
335 | if [ -z "${target}" ] | ||
336 | then | ||
337 | target=$1 | ||
338 | elif [ -z "${kernel}" ] | ||
339 | then | ||
340 | kernel=$1 | ||
341 | else | ||
342 | usage | ||
343 | fi | ||
344 | ;; | ||
345 | esac | ||
346 | |||
347 | shift | ||
348 | done | ||
349 | |||
350 | niro | 664 | # no kernel or target given |
351 | if [[ -z ${target} ]] || [[ -z ${kernel} ]] | ||
352 | then | ||
353 | usage | ||
354 | fi | ||
355 | niro | 562 | |
356 | niro | 664 | # die if linuxrc does not exist |
357 | [[ ! -e ${LINUXRC} ]] && die "linuxrc '${LINUXRC}' not found." | ||
358 | |||
359 | niro | 562 | # create basic filesystem layout |
360 | niro | 894 | install -d ${DEST}/{bin,dev,etc,lib,loopfs,proc,sbin,sys,sysroot,usr/bin,usr/sbin} || die |
361 | niro | 562 | |
362 | # install busybox | ||
363 | echo "$(which busybox.mkinitrd)" | ||
364 | install -m0755 $(which busybox.mkinitrd) ${DEST}/bin/busybox || die | ||
365 | for i in '[' ash basename cat cut clear cp dirname echo env false find \ | ||
366 | grep gunzip gzip ln ls loadkmap mkdir mknod more mount mv \ | ||
367 | ps pwd rm rmdir sh sleep test touch true umount uname \ | ||
368 | xargs yes chmod chown | ||
369 | do | ||
370 | # use soft links from now on; | ||
371 | # hardlinks in initramfs apears to be broken on newer kernels | ||
372 | # -> "request module: runaway loop modprobe binfmt-0000" | ||
373 | # see: http://www.gossamer-threads.com/lists/linux/kernel/728042 | ||
374 | ln -s /bin/busybox ${DEST}/bin/${i} || die "${i}" | ||
375 | done | ||
376 | |||
377 | # sbin related | ||
378 | for i in chroot init losetup modprobe pivot_root | ||
379 | do | ||
380 | niro | 894 | ln -s ${DEST}/bin/busybox ${DEST}/sbin/${i} || die "${i}" |
381 | niro | 562 | done |
382 | |||
383 | # install run-init | ||
384 | echo "$(which run-init.mkinitrd)" | ||
385 | install -m0755 $(which run-init.mkinitrd) ${DEST}/sbin/run-init || die | ||
386 | |||
387 | # install insmod.static | ||
388 | niro | 894 | #echo "$(which insmod.static)" |
389 | #install -m0755 $(which insmod.static) ${DEST}/sbin/insmod || die | ||
390 | niro | 562 | |
391 | niro | 703 | # install v86d for uvesafb support if installed |
392 | if which v86d &> /dev/null | ||
393 | then | ||
394 | niro | 894 | echo "$(which v86d)" |
395 | niro | 703 | install -m0755 $(which v86d) ${DEST}/sbin/v86d || die |
396 | fi | ||
397 | |||
398 | niro | 562 | ## install kernel modules ## |
399 | # generic needed | ||
400 | install_kernel_modules "${MODULES_GENERIC}" | ||
401 | |||
402 | # usb | ||
403 | install_kernel_modules "${MODULES_USB}" | ||
404 | |||
405 | # scsi | ||
406 | install_kernel_modules "${MODULES_SCSI}" | ||
407 | |||
408 | # sata | ||
409 | install_kernel_modules "${MODULES_SATA}" | ||
410 | |||
411 | # pata | ||
412 | install_kernel_modules "${MODULES_PATA}" | ||
413 | |||
414 | niro | 664 | # framebuffer |
415 | install_kernel_modules "${MODULES_FRAMEBUFFER}" | ||
416 | |||
417 | niro | 562 | # show all modules |
418 | for i in ${ALL_MODULES} | ||
419 | do | ||
420 | echo ${i} | ||
421 | done | ||
422 | |||
423 | # install linuxrc | ||
424 | install -m0755 ${LINUXRC} ${DEST}/init || die | ||
425 | |||
426 | # create the image | ||
427 | echo "Creating initrd image '${target}' ..." | ||
428 | if [[ ${IMAGE_TYPE} = initramfs ]] | ||
429 | then | ||
430 | (cd "${DEST}" ; find . | cpio --quiet -o -H newc | gzip -9 >${IMAGE}) | ||
431 | cat ${IMAGE} > ${target} || die | ||
432 | fi | ||
433 | |||
434 | if [[ ${IMAGE_TYPE} = loopback ]] | ||
435 | then | ||
436 | MOUNTTMP="$(mktemp -d)" | ||
437 | |||
438 | # create ext2 img | ||
439 | dd if=/dev/zero of=${IMAGE} bs=1024 count=${IMAGESIZE} &> /dev/null || die | ||
440 | mke2fs -m 0 -i 1024 -F ${IMAGE} &> /dev/null || die | ||
441 | mount -o loop ${IMAGE} ${MOUNTTMP} || die | ||
442 | mv ${DEST}/* ${MOUNTTMP} || die | ||
443 | umount ${MOUNTTMP} || die | ||
444 | gzip -9 ${IMAGE} || die | ||
445 | cat ${IMAGE}.gz > ${target} || die | ||
446 | [ -d ${MOUNTTMP} ] && rm -rf ${MOUNTTMP} | ||
447 | |||
448 | # create inird dir for pivot_root | ||
449 | [ ! -d /initrd ] && { install -d /initrd || die; } | ||
450 | fi | ||
451 | |||
452 | # clean up | ||
453 | [ -d ${DEST} ] && rm -rf ${DEST} | ||
454 | [ -f ${IMAGE} ] && rm -f ${IMAGE} | ||
455 | |||
456 | # all went ok at this point | ||
457 | exit 0 |