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.

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