image-live.bbclass 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. # Copyright (C) 2004, Advanced Micro Devices, Inc. All Rights Reserved
  2. # Released under the MIT license (see packages/COPYING)
  3. # Creates a bootable image using syslinux, your kernel and an optional
  4. # initrd
  5. #
  6. # End result is two things:
  7. #
  8. # 1. A .hddimg file which is an msdos filesystem containing syslinux, a kernel,
  9. # an initrd and a rootfs image. These can be written to harddisks directly and
  10. # also booted on USB flash disks (write them there with dd).
  11. #
  12. # 2. A CD .iso image
  13. # Boot process is that the initrd will boot and process which label was selected
  14. # in syslinux. Actions based on the label are then performed (e.g. installing to
  15. # an hdd)
  16. # External variables (also used by syslinux.bbclass)
  17. # ${INITRD} - indicates a list of filesystem images to concatenate and use as an initrd (optional)
  18. # ${HDDIMG_ID} - FAT image volume-id
  19. # ${ROOTFS} - indicates a filesystem image to include as the root filesystem (optional)
  20. inherit live-vm-common image-artifact-names
  21. do_bootimg[depends] += "dosfstools-native:do_populate_sysroot \
  22. mtools-native:do_populate_sysroot \
  23. cdrtools-native:do_populate_sysroot \
  24. virtual/kernel:do_deploy \
  25. ${MLPREFIX}syslinux:do_populate_sysroot \
  26. syslinux-native:do_populate_sysroot \
  27. ${PN}:do_image_${@d.getVar('LIVE_ROOTFS_TYPE').replace('-', '_')} \
  28. "
  29. LABELS_LIVE ?= "boot install"
  30. ROOT_LIVE ?= "root=/dev/ram0"
  31. INITRD_IMAGE_LIVE ?= "${MLPREFIX}core-image-minimal-initramfs"
  32. INITRD_LIVE ?= "${DEPLOY_DIR_IMAGE}/${INITRD_IMAGE_LIVE}-${MACHINE}.${INITRAMFS_FSTYPES}"
  33. LIVE_ROOTFS_TYPE ?= "ext4"
  34. ROOTFS ?= "${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.${LIVE_ROOTFS_TYPE}"
  35. IMAGE_TYPEDEP_live = "${LIVE_ROOTFS_TYPE}"
  36. IMAGE_TYPEDEP_iso = "${LIVE_ROOTFS_TYPE}"
  37. IMAGE_TYPEDEP_hddimg = "${LIVE_ROOTFS_TYPE}"
  38. IMAGE_TYPES_MASKED += "live hddimg iso"
  39. python() {
  40. image_b = d.getVar('IMAGE_BASENAME')
  41. initrd_i = d.getVar('INITRD_IMAGE_LIVE')
  42. if image_b == initrd_i:
  43. bb.error('INITRD_IMAGE_LIVE %s cannot use image live, hddimg or iso.' % initrd_i)
  44. bb.fatal('Check IMAGE_FSTYPES and INITRAMFS_FSTYPES settings.')
  45. elif initrd_i:
  46. d.appendVarFlag('do_bootimg', 'depends', ' %s:do_image_complete' % initrd_i)
  47. }
  48. HDDDIR = "${S}/hddimg"
  49. ISODIR = "${S}/iso"
  50. EFIIMGDIR = "${S}/efi_img"
  51. COMPACT_ISODIR = "${S}/iso.z"
  52. ISOLINUXDIR ?= "/isolinux"
  53. ISO_BOOTIMG = "isolinux/isolinux.bin"
  54. ISO_BOOTCAT = "isolinux/boot.cat"
  55. MKISOFS_OPTIONS = "-no-emul-boot -boot-load-size 4 -boot-info-table"
  56. BOOTIMG_VOLUME_ID ?= "boot"
  57. BOOTIMG_EXTRA_SPACE ?= "512"
  58. populate_live() {
  59. populate_kernel $1
  60. if [ -s "${ROOTFS}" ]; then
  61. install -m 0644 ${ROOTFS} $1/rootfs.img
  62. fi
  63. }
  64. build_iso() {
  65. # Only create an ISO if we have an INITRD and the live or iso image type was selected
  66. if [ -z "${INITRD}" ] || [ "${@bb.utils.contains_any('IMAGE_FSTYPES', 'live iso', '1', '0', d)}" != "1" ]; then
  67. bbnote "ISO image will not be created."
  68. return
  69. fi
  70. # ${INITRD} is a list of multiple filesystem images
  71. for fs in ${INITRD}
  72. do
  73. if [ ! -s "$fs" ]; then
  74. bbwarn "ISO image will not be created. $fs is invalid."
  75. return
  76. fi
  77. done
  78. populate_live ${ISODIR}
  79. if [ "${PCBIOS}" = "1" ]; then
  80. syslinux_iso_populate ${ISODIR}
  81. fi
  82. if [ "${EFI}" = "1" ]; then
  83. efi_iso_populate ${ISODIR}
  84. build_fat_img ${EFIIMGDIR} ${ISODIR}/efi.img
  85. fi
  86. # EFI only
  87. if [ "${PCBIOS}" != "1" ] && [ "${EFI}" = "1" ] ; then
  88. # Work around bug in isohybrid where it requires isolinux.bin
  89. # In the boot catalog, even though it is not used
  90. mkdir -p ${ISODIR}/${ISOLINUXDIR}
  91. install -m 0644 ${STAGING_DATADIR}/syslinux/isolinux.bin ${ISODIR}${ISOLINUXDIR}
  92. fi
  93. # We used to have support for zisofs; this is a relic of that
  94. mkisofs_compress_opts="-r"
  95. # Check the size of ${ISODIR}/rootfs.img, use mkisofs -iso-level 3
  96. # when it exceeds 3.8GB, the specification is 4G - 1 bytes, we need
  97. # leave a few space for other files.
  98. mkisofs_iso_level=""
  99. if [ -n "${ROOTFS}" ] && [ -s "${ROOTFS}" ]; then
  100. rootfs_img_size=`stat -c '%s' ${ISODIR}/rootfs.img`
  101. # 4080218931 = 3.8 * 1024 * 1024 * 1024
  102. if [ $rootfs_img_size -gt 4080218931 ]; then
  103. bbnote "${ISODIR}/rootfs.img execeeds 3.8GB, using '-iso-level 3' for mkisofs"
  104. mkisofs_iso_level="-iso-level 3"
  105. fi
  106. fi
  107. if [ "${PCBIOS}" = "1" ] && [ "${EFI}" != "1" ] ; then
  108. # PCBIOS only media
  109. mkisofs -V ${BOOTIMG_VOLUME_ID} \
  110. -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
  111. -b ${ISO_BOOTIMG} -c ${ISO_BOOTCAT} \
  112. $mkisofs_compress_opts \
  113. ${MKISOFS_OPTIONS} $mkisofs_iso_level ${ISODIR}
  114. else
  115. # EFI only OR EFI+PCBIOS
  116. mkisofs -A ${BOOTIMG_VOLUME_ID} -V ${BOOTIMG_VOLUME_ID} \
  117. -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
  118. -b ${ISO_BOOTIMG} -c ${ISO_BOOTCAT} \
  119. $mkisofs_compress_opts ${MKISOFS_OPTIONS} $mkisofs_iso_level \
  120. -eltorito-alt-boot -eltorito-platform efi \
  121. -b efi.img -no-emul-boot \
  122. ${ISODIR}
  123. isohybrid_args="-u"
  124. fi
  125. isohybrid $isohybrid_args ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso
  126. }
  127. build_fat_img() {
  128. FATSOURCEDIR=$1
  129. FATIMG=$2
  130. # Calculate the size required for the final image including the
  131. # data and filesystem overhead.
  132. # Sectors: 512 bytes
  133. # Blocks: 1024 bytes
  134. # Determine the sector count just for the data
  135. SECTORS=$(expr $(du --apparent-size -ks ${FATSOURCEDIR} | cut -f 1) \* 2)
  136. # Account for the filesystem overhead. This includes directory
  137. # entries in the clusters as well as the FAT itself.
  138. # Assumptions:
  139. # FAT32 (12 or 16 may be selected by mkdosfs, but the extra
  140. # padding will be minimal on those smaller images and not
  141. # worth the logic here to caclulate the smaller FAT sizes)
  142. # < 16 entries per directory
  143. # 8.3 filenames only
  144. # 32 bytes per dir entry
  145. DIR_BYTES=$(expr $(find ${FATSOURCEDIR} | tail -n +2 | wc -l) \* 32)
  146. # 32 bytes for every end-of-directory dir entry
  147. DIR_BYTES=$(expr $DIR_BYTES + $(expr $(find ${FATSOURCEDIR} -type d | tail -n +2 | wc -l) \* 32))
  148. # 4 bytes per FAT entry per sector of data
  149. FAT_BYTES=$(expr $SECTORS \* 4)
  150. # 4 bytes per FAT entry per end-of-cluster list
  151. FAT_BYTES=$(expr $FAT_BYTES + $(expr $(find ${FATSOURCEDIR} -type d | tail -n +2 | wc -l) \* 4))
  152. # Use a ceiling function to determine FS overhead in sectors
  153. DIR_SECTORS=$(expr $(expr $DIR_BYTES + 511) / 512)
  154. # There are two FATs on the image
  155. FAT_SECTORS=$(expr $(expr $(expr $FAT_BYTES + 511) / 512) \* 2)
  156. SECTORS=$(expr $SECTORS + $(expr $DIR_SECTORS + $FAT_SECTORS))
  157. # Determine the final size in blocks accounting for some padding
  158. BLOCKS=$(expr $(expr $SECTORS / 2) + ${BOOTIMG_EXTRA_SPACE})
  159. # mkdosfs will sometimes use FAT16 when it is not appropriate,
  160. # resulting in a boot failure from SYSLINUX. Use FAT32 for
  161. # images larger than 512MB, otherwise let mkdosfs decide.
  162. if [ $(expr $BLOCKS / 1024) -gt 512 ]; then
  163. FATSIZE="-F 32"
  164. fi
  165. # mkdosfs will fail if ${FATIMG} exists. Since we are creating an
  166. # new image, it is safe to delete any previous image.
  167. if [ -e ${FATIMG} ]; then
  168. rm ${FATIMG}
  169. fi
  170. if [ -z "${HDDIMG_ID}" ]; then
  171. mkdosfs ${FATSIZE} -n ${BOOTIMG_VOLUME_ID} ${MKDOSFS_EXTRAOPTS} -C ${FATIMG} \
  172. ${BLOCKS}
  173. else
  174. mkdosfs ${FATSIZE} -n ${BOOTIMG_VOLUME_ID} ${MKDOSFS_EXTRAOPTS} -C ${FATIMG} \
  175. ${BLOCKS} -i ${HDDIMG_ID}
  176. fi
  177. # Copy FATSOURCEDIR recursively into the image file directly
  178. mcopy -i ${FATIMG} -s ${FATSOURCEDIR}/* ::/
  179. }
  180. build_hddimg() {
  181. # Create an HDD image
  182. if [ "${@bb.utils.contains_any('IMAGE_FSTYPES', 'live hddimg', '1', '0', d)}" = "1" ] ; then
  183. populate_live ${HDDDIR}
  184. if [ "${PCBIOS}" = "1" ]; then
  185. syslinux_hddimg_populate ${HDDDIR}
  186. fi
  187. if [ "${EFI}" = "1" ]; then
  188. efi_hddimg_populate ${HDDDIR}
  189. fi
  190. # Check the size of ${HDDDIR}/rootfs.img, error out if it
  191. # exceeds 4GB, it is the single file's max size of FAT fs.
  192. if [ -f ${HDDDIR}/rootfs.img ]; then
  193. rootfs_img_size=`stat -c '%s' ${HDDDIR}/rootfs.img`
  194. max_size=`expr 4 \* 1024 \* 1024 \* 1024`
  195. if [ $rootfs_img_size -ge $max_size ]; then
  196. bberror "${HDDDIR}/rootfs.img rootfs size is greather than or equal to 4GB,"
  197. bberror "and this doesn't work on a FAT filesystem. You can either:"
  198. bberror "1) Reduce the size of rootfs.img, or,"
  199. bbfatal "2) Use wic, vmdk or vdi instead of hddimg\n"
  200. fi
  201. fi
  202. build_fat_img ${HDDDIR} ${IMGDEPLOYDIR}/${IMAGE_NAME}.hddimg
  203. if [ "${PCBIOS}" = "1" ]; then
  204. syslinux_hddimg_install
  205. fi
  206. chmod 644 ${IMGDEPLOYDIR}/${IMAGE_NAME}.hddimg
  207. fi
  208. }
  209. python do_bootimg() {
  210. set_live_vm_vars(d, 'LIVE')
  211. if d.getVar("PCBIOS") == "1":
  212. bb.build.exec_func('build_syslinux_cfg', d)
  213. if d.getVar("EFI") == "1":
  214. bb.build.exec_func('build_efi_cfg', d)
  215. bb.build.exec_func('build_hddimg', d)
  216. bb.build.exec_func('build_iso', d)
  217. bb.build.exec_func('create_symlinks', d)
  218. }
  219. do_bootimg[subimages] = "hddimg iso"
  220. do_bootimg[imgsuffix] = "."
  221. addtask bootimg before do_image_complete