mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
6.6 KiB

  1. #!/bin/bash
  2. kernel=`uname -r`
  3. targetdir=`mktemp -d`
  4. empty=0
  5. rootdir=""
  6. cross_compile=""
  7. initrdfs="cramfs"
  8. block_size=""
  9. ramdisk_size=8192
  10. # Successfully tested combinations: <arch> <blocksize> <initrdfs>
  11. # ARM (QEMU) 1024 ext2fs
  12. # ARM (QEMU) 4096 cramfs
  13. # x86 (QEMU) 1024 ext2fs
  14. # x86 (QEMU) 4096 cramfs
  15. for P in find sed grep xargs mkdir cp mknod mount sort uniq tr file rm ln \
  16. mount umount readelf ; do
  17. if ! type -p "$P" > /dev/null ; then
  18. echo "Can't find required program '$P'! Aborting..."
  19. exit 1
  20. fi
  21. done
  22. while [ ${#} -gt 0 ] ; do
  23. case "${1}" in
  24. empty) empty=1 ;;
  25. -root)
  26. if [ -d "${2}/" ]; then
  27. rootdir="${2%/}" ; shift
  28. else
  29. echo "Can't open ${2}: No such directory."
  30. echo "Usage: ${0} [ kernel-version ]"
  31. exit 1
  32. fi
  33. ;;
  34. -cross) cross_compile="${2}" ; shift ;;
  35. -bs) block_size="${2}" ; shift ;;
  36. -fs)
  37. case "${2}" in
  38. ext2fs|ext3fs|cramfs|ramfs) initrdfs="${2}" ; shift ;;
  39. *)
  40. echo "Filesystem ${2} not supported as initrd filesystem."
  41. exit 1
  42. ;;
  43. esac
  44. ;;
  45. *)
  46. if [ -d "${rootdir}/lib/modules/${1}" ]; then
  47. kernel="${1}"
  48. echo "kernel ${kernel}"
  49. else
  50. echo "Can't open ${rootdir}/lib/modules/${1}: No such directory."
  51. echo "Usage: ${0} [ kernel-version ]"
  52. exit 1
  53. fi
  54. ;;
  55. esac
  56. shift
  57. done
  58. case ${initrdfs} in
  59. ext2fs|ext3fs|cramfs)
  60. initrd_img="${rootdir}/boot/initrd-${kernel}.img"
  61. ;;
  62. ramfs)
  63. initrd_img="${rootdir}/boot/initrd-${kernel}.cpio"
  64. ;;
  65. esac
  66. add_module_to_initrd() {
  67. module="${1}"
  68. parameter="${2}"
  69. module=${module/.ko/} # just in case, shouldn't be
  70. module="`find ${rootdir}/lib/modules/${kernel} -name "${module}.o" -o -name "${module}.ko"`"
  71. [ -f "${targetdir}/${module}" ] && return # skip dupes
  72. echo "Adding ${module}."
  73. mkdir -p ${targetdir}/${module%/*}
  74. cp ${module} ${targetdir}/${module}
  75. echo "/sbin/insmod ${module} ${parameter}" >> ${targetdir}/etc/conf/kernel
  76. }
  77. echo "Creating ${initrd_img} ..."
  78. mkdir -p ${targetdir}/etc/conf
  79. if [ "${empty}" = 0 ] ; then
  80. grep '^modprobe ' ${rootdir}/etc/conf/kernel | grep -v 'no-initrd' | \
  81. sed 's,[ ]#.*,,' | \
  82. while read a b c; do
  83. module="$( find ${rootdir}/lib/modules/${kernel}/ -name "${b}.o" -o -name "${b}.ko" )"
  84. if [ -z "${module}" ] ; then
  85. echo "$0: ${b} is no longer a module in ${kernel}" >&2
  86. echo "$0: Please either adjust /etc/conf/kernel or the configuration for the kernel V${kernel}" >&2
  87. continue
  88. fi
  89. modinfo ${module} 2> /dev/null | grep ^depends: | \
  90. while read a b; do
  91. [ -z "${b}" ] && continue
  92. b="${b//,/ }"
  93. for module in ${b} ; do
  94. add_module_to_initrd "${b}"
  95. done
  96. done
  97. add_module_to_initrd "${b}" "${c}"
  98. done
  99. fi
  100. mkdir -p ${targetdir}/{dev,root,tmp,proc,sys}
  101. mknod ${targetdir}/dev/ram0 b 1 0
  102. mknod ${targetdir}/dev/null c 1 3
  103. mknod ${targetdir}/dev/zero c 1 5
  104. mknod ${targetdir}/dev/tty c 5 0
  105. mknod ${targetdir}/dev/console c 5 1
  106. # this copies a set of programs and the necessary libraries into a
  107. # chroot environment
  108. echo -n "Checking necessary fsck programs ... "
  109. while read dev a mnt b fs c ; do
  110. [ -e "${rootdir}/sbin/fsck.${fs}" ] && echo "/sbin/fsck.${fs} /sbin/fsck.${fs}"
  111. done < <( mount ) | sort | uniq >/etc/conf/initrd/initrd_fsck
  112. echo "/sbin/fsck /sbin/fsck" >>/etc/conf/initrd/initrd_fsck
  113. echo "done"
  114. libdirs="${rootdir}/lib `sed -e"s,^\(.*\),${rootdir}\1," ${rootdir}/etc/ld.so.conf | tr '\n' ' '`"
  115. needed_libs() {
  116. local x="${1}" library
  117. ${cross_compile}readelf -d ${x} 2>/dev/null | grep "(NEEDED)" |
  118. sed -e"s,.*Shared library: \[\(.*\)\],\1," |
  119. while read library ; do
  120. find ${libdirs} -name "${library}" 2>/dev/null |
  121. sed -e "s,^${rootdir},,g" | tr '\n' ' '
  122. done
  123. }
  124. echo -n "Copying other files ... "
  125. for x in ${rootdir}/etc/conf/initrd/initrd_* ; do
  126. [ -f ${x} ] || continue
  127. while read file target ; do
  128. file="${rootdir}/${file}"
  129. if [ ! -e ${file} ] ; then
  130. echo "${file} is requested by ${x} but doesn't exist!" >&2
  131. continue
  132. fi
  133. while read f ; do
  134. tfile=${targetdir}/${target}${f#${file}}
  135. [ -e ${tfile} ] && continue
  136. if [ -d ${f} -a ! -L ${f} ] ; then
  137. mkdir -p ${tfile}
  138. continue
  139. else
  140. mkdir -p ${tfile%/*}
  141. fi
  142. # if [ -b ${f} -o -c ${f} -o -p ${f} -o -L ${f} ] ; then
  143. cp -a ${f} ${tfile}
  144. # else
  145. # cp ${f} ${tfile}
  146. # fi
  147. file -L ${f} | grep -q ELF || continue
  148. libs="${libs} `needed_libs ${f}`"
  149. done < <( find "${file}" )
  150. done < ${x}
  151. done
  152. echo "done"
  153. echo -n "Copying required libraries ... "
  154. while [ -n "${libs}" ] ; do
  155. oldlibs=${libs}
  156. libs=""
  157. for x in ${oldlibs} ; do
  158. [ -e ${targetdir}/${x} ] && continue
  159. mkdir -p ${targetdir}/${x%/*}
  160. cp ${rootdir}/${x} ${targetdir}/${x}
  161. file -L ${rootdir}/${x} | grep -q ELF || continue
  162. for y in `needed_libs ${rootdir}/${x}` ; do
  163. [ ! -e "${targetdir}/${y}" ] && libs="${libs} ${y}"
  164. done
  165. done
  166. done
  167. echo "done"
  168. echo "Creating links for identical files ..."
  169. while read ck fn
  170. do
  171. # don't link empty files...
  172. if [ "${oldck}" = "${ck}" -a -s "${fn}" ] ; then
  173. echo "\`- Found ${fn#${targetdir}} -> ${oldfn#${targetdir}}."
  174. rm ${fn} ; ln -s /${oldfn#${targetdir}} ${fn}
  175. else
  176. oldck=${ck} ; oldfn=${fn}
  177. fi
  178. done < <( find ${targetdir} -type f | xargs md5sum | sort )
  179. # though this is not clean, it helps avoid a warning from fsck about
  180. # it being unable to determine wether a filesystem is mounted.
  181. ln -s /proc/mounts ${targetdir}/etc/mtab
  182. echo "Creating initrd filesystem image (${initrdfs}): "
  183. case "${initrdfs}" in
  184. cramfs)
  185. [ "${block_size}" == "" ] && block_size=4096
  186. /sbin/mkfs.cramfs -b ${block_size} ${targetdir} ${initrd_img}
  187. ;;
  188. ramfs)
  189. # cp -a ${targetdir}/{linuxrc,init}
  190. ( cd ${targetdir} ; find | cpio -o -c > ${initrd_img} ; )
  191. ;;
  192. ext2fs|ext3fs)
  193. [ "${block_size}" == "" ] && block_size=1024
  194. block_count=$(( ( 1024 * ${ramdisk_size} ) / ${block_size} ))
  195. echo "Creating temporary files."
  196. tmpdir=`mktemp -d` ; mkdir -p ${tmpdir}
  197. dd if=/dev/zero of=${initrd_img} bs=${block_size} count=${block_count} &> /dev/null
  198. tmpdev="`losetup -f 2>/dev/null`"
  199. if [ -z "${tmpdev}" ] ; then
  200. for x in /dev/loop* /dev/loop/* ; do
  201. [ -b "${x}" ] || continue
  202. losetup ${x} 2>&1 >/dev/null || tmpdev="${x}"
  203. [ -n "${tmpdev}" ] && break
  204. done
  205. if [ -z "${tmpdev}" ] ; then
  206. echo "No free loopback device found!"
  207. rm -f ${tmpfile} ; rmdir ${tmpdir}; exit 1
  208. fi
  209. fi
  210. echo "Using loopback device ${tmpdev}."
  211. losetup "${tmpdev}" ${initrd_img}
  212. echo "Writing initrd image file."
  213. /sbin/mkfs.${initrdfs:0:4} -b ${block_size} -m 0 -N 360 -q ${tmpdev} &> /dev/null
  214. mount -t ${initrdfs:0:4} ${tmpdev} ${tmpdir}
  215. rmdir ${tmpdir}/lost+found/
  216. cp -a ${targetdir}/* ${tmpdir}
  217. umount ${tmpdir}
  218. echo "Removing temporary files."
  219. losetup -d ${tmpdev}
  220. rm -rf ${tmpdir}
  221. ;;
  222. esac
  223. echo "Compressing initrd image file."
  224. gzip -9 -c ${initrd_img} > ${initrd_img}.gz
  225. rm -rf ${targetdir}
  226. echo "Done."