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.

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