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