blob: 607356ad1311fb47c246b9db6b5cd18e897216de [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
Patrick Williams92b42cb2022-09-03 06:53:57 -05002# Copyright OpenEmbedded Contributors
3#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005#
6# DESCRIPTION
7# This implements the 'isoimage-isohybrid' source plugin class for 'wic'
8#
9# AUTHORS
10# Mihaly Varga <mihaly.varga (at] ni.com>
11
Brad Bishop6e60e8b2018-02-01 10:27:11 -050012import glob
13import logging
Patrick Williamsc124f4f2015-09-15 14:41:29 -050014import os
15import re
16import shutil
17
Brad Bishop6e60e8b2018-02-01 10:27:11 -050018from wic import WicError
19from wic.engine import get_custom_config
Patrick Williamsc124f4f2015-09-15 14:41:29 -050020from wic.pluginbase import SourcePlugin
Brad Bishopd7bf8c12018-02-25 22:55:05 -050021from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
Brad Bishop6e60e8b2018-02-01 10:27:11 -050022
23logger = logging.getLogger('wic')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050024
25class IsoImagePlugin(SourcePlugin):
26 """
27 Create a bootable ISO image
28
29 This plugin creates a hybrid, legacy and EFI bootable ISO image. The
30 generated image can be used on optical media as well as USB media.
31
32 Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not
33 implemented yet) as bootloader. The plugin creates the directories required
34 by bootloaders and populates them by creating and configuring the
35 bootloader files.
36
37 Example kickstart file:
38 part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080039 image_name= IsoImage" --ondisk cd --label LIVECD
Patrick Williamsc124f4f2015-09-15 14:41:29 -050040 bootloader --timeout=10 --append=" "
41
42 In --sourceparams "loader" specifies the bootloader used for booting in EFI
43 mode, while "image_name" specifies the name of the generated image. In the
44 example above, wic creates an ISO image named IsoImage-cd.direct (default
45 extension added by direct imeger plugin) and a file named IsoImage-cd.iso
46 """
47
48 name = 'isoimage-isohybrid'
49
50 @classmethod
51 def do_configure_syslinux(cls, creator, cr_workdir):
52 """
53 Create loader-specific (syslinux) config
54 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -060055 splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056 if os.path.exists(splash):
57 splashline = "menu background splash.jpg"
58 else:
59 splashline = ""
60
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050061 bootloader = creator.ks.bootloader
Patrick Williamsc124f4f2015-09-15 14:41:29 -050062
63 syslinux_conf = ""
64 syslinux_conf += "PROMPT 0\n"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050065 syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066 syslinux_conf += "\n"
67 syslinux_conf += "ALLOWOPTIONS 1\n"
68 syslinux_conf += "SERIAL 0 115200\n"
69 syslinux_conf += "\n"
70 if splashline:
71 syslinux_conf += "%s\n" % splashline
72 syslinux_conf += "DEFAULT boot\n"
73 syslinux_conf += "LABEL boot\n"
74
Brad Bishop15ae2502019-06-18 21:44:24 -040075 kernel = get_bitbake_var("KERNEL_IMAGETYPE")
Brad Bishop96ff1982019-08-19 13:50:42 -040076 if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
77 if get_bitbake_var("INITRAMFS_IMAGE"):
78 kernel = "%s-%s.bin" % \
79 (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
80
Brad Bishop15ae2502019-06-18 21:44:24 -040081 syslinux_conf += "KERNEL /" + kernel + "\n"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050082 syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
83 % bootloader.append
Patrick Williamsc124f4f2015-09-15 14:41:29 -050084
Brad Bishop6e60e8b2018-02-01 10:27:11 -050085 logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
86 cr_workdir)
87
Patrick Williamsc124f4f2015-09-15 14:41:29 -050088 with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
89 cfg.write(syslinux_conf)
90
91 @classmethod
Brad Bishopd7bf8c12018-02-25 22:55:05 -050092 def do_configure_grubefi(cls, part, creator, target_dir):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093 """
94 Create loader-specific (grub-efi) config
95 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -060096 configfile = creator.ks.bootloader.configfile
97 if configfile:
98 grubefi_conf = get_custom_config(configfile)
99 if grubefi_conf:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500100 logger.debug("Using custom configuration file %s for grub.cfg",
101 configfile)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600102 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500103 raise WicError("configfile is specified "
104 "but failed to get it from %s", configfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500105 else:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500106 splash = os.path.join(target_dir, "splash.jpg")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600107 if os.path.exists(splash):
108 splashline = "menu background splash.jpg"
109 else:
110 splashline = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600112 bootloader = creator.ks.bootloader
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500113
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600114 grubefi_conf = ""
115 grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
116 grubefi_conf += "--parity=no --stop=1\n"
117 grubefi_conf += "default=boot\n"
118 grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
119 grubefi_conf += "\n"
120 grubefi_conf += "search --set=root --label %s " % part.label
121 grubefi_conf += "\n"
122 grubefi_conf += "menuentry 'boot'{\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123
Brad Bishop15ae2502019-06-18 21:44:24 -0400124 kernel = get_bitbake_var("KERNEL_IMAGETYPE")
Brad Bishop96ff1982019-08-19 13:50:42 -0400125 if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
126 if get_bitbake_var("INITRAMFS_IMAGE"):
127 kernel = "%s-%s.bin" % \
128 (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500129
Brad Bishop15ae2502019-06-18 21:44:24 -0400130 grubefi_conf += "linux /%s rootwait %s\n" \
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600131 % (kernel, bootloader.append)
132 grubefi_conf += "initrd /initrd \n"
133 grubefi_conf += "}\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500134
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600135 if splashline:
136 grubefi_conf += "%s\n" % splashline
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500137
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500138 cfg_path = os.path.join(target_dir, "grub.cfg")
139 logger.debug("Writing grubefi config %s", cfg_path)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500140
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500141 with open(cfg_path, "w") as cfg:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 cfg.write(grubefi_conf)
143
144 @staticmethod
145 def _build_initramfs_path(rootfs_dir, cr_workdir):
146 """
147 Create path for initramfs image
148 """
149
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500150 initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 if not initrd:
152 initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
153 if not initrd_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500154 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155
156 image_name = get_bitbake_var("IMAGE_BASENAME")
157 if not image_name:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500158 raise WicError("Couldn't find IMAGE_BASENAME, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159
160 image_type = get_bitbake_var("INITRAMFS_FSTYPES")
161 if not image_type:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500162 raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500163
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500164 machine = os.path.basename(initrd_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500165
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500166 pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
167 files = glob.glob(pattern)
168 if files:
169 initrd = files[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500170
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500171 if not initrd or not os.path.exists(initrd):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500172 # Create initrd from rootfs directory
173 initrd = "%s/initrd.cpio.gz" % cr_workdir
174 initrd_dir = "%s/INITRD" % cr_workdir
175 shutil.copytree("%s" % rootfs_dir, \
176 "%s" % initrd_dir, symlinks=True)
177
178 if os.path.isfile("%s/init" % rootfs_dir):
179 shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir)
180 elif os.path.lexists("%s/init" % rootfs_dir):
181 os.symlink(os.readlink("%s/init" % rootfs_dir), \
182 "%s/init" % initrd_dir)
183 elif os.path.isfile("%s/sbin/init" % rootfs_dir):
184 shutil.copy2("%s/sbin/init" % rootfs_dir, \
185 "%s" % initrd_dir)
186 elif os.path.lexists("%s/sbin/init" % rootfs_dir):
187 os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \
188 "%s/init" % initrd_dir)
189 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500190 raise WicError("Couldn't find or build initrd, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500191
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800192 exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
193 % (initrd_dir, cr_workdir), as_shell=True)
194 exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 shutil.rmtree(initrd_dir)
196
197 return initrd
198
199 @classmethod
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500200 def do_configure_partition(cls, part, source_params, creator, cr_workdir,
201 oe_builddir, bootimg_dir, kernel_dir,
202 native_sysroot):
203 """
204 Called before do_prepare_partition(), creates loader-specific config
205 """
206 isodir = "%s/ISO/" % cr_workdir
207
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500208 if os.path.exists(isodir):
209 shutil.rmtree(isodir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500210
211 install_cmd = "install -d %s " % isodir
212 exec_cmd(install_cmd)
213
214 # Overwrite the name of the created image
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500215 logger.debug(source_params)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500216 if 'image_name' in source_params and \
217 source_params['image_name'].strip():
218 creator.name = source_params['image_name'].strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500219 logger.debug("The name of the image is: %s", creator.name)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500220
Andrew Geissler6ce62a22020-11-30 19:58:47 -0600221 @staticmethod
222 def _install_payload(source_params, iso_dir):
223 """
224 Copies contents of payload directory (as specified in 'payload_dir' param) into iso_dir
225 """
226
227 if source_params.get('payload_dir'):
228 payload_dir = source_params['payload_dir']
229
230 logger.debug("Payload directory: %s", payload_dir)
231 shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
232
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 @classmethod
234 def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
235 oe_builddir, bootimg_dir, kernel_dir,
236 rootfs_dir, native_sysroot):
237 """
238 Called to do the actual content population for a partition i.e. it
239 'prepares' the partition to be incorporated into the image.
240 In this case, prepare content for a bootable ISO image.
241 """
242
243 isodir = "%s/ISO" % cr_workdir
244
Andrew Geissler6ce62a22020-11-30 19:58:47 -0600245 cls._install_payload(source_params, isodir)
246
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500247 if part.rootfs_dir is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500248 if not 'ROOTFS_DIR' in rootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500249 raise WicError("Couldn't find --rootfs-dir, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 rootfs_dir = rootfs_dir['ROOTFS_DIR']
251 else:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500252 if part.rootfs_dir in rootfs_dir:
253 rootfs_dir = rootfs_dir[part.rootfs_dir]
254 elif part.rootfs_dir:
255 rootfs_dir = part.rootfs_dir
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500256 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500257 raise WicError("Couldn't find --rootfs-dir=%s connection "
258 "or it is not a valid path, exiting." %
259 part.rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500260
261 if not os.path.isdir(rootfs_dir):
262 rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
263 if not os.path.isdir(rootfs_dir):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500264 raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500265
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500266 part.rootfs_dir = rootfs_dir
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500267 deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500268 img_iso_dir = get_bitbake_var("ISODIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500269
270 # Remove the temporary file created by part.prepare_rootfs()
271 if os.path.isfile(part.source_file):
272 os.remove(part.source_file)
273
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500274 # Support using a different initrd other than default
275 if source_params.get('initrd'):
276 initrd = source_params['initrd']
277 if not deploy_dir:
278 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
279 cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir)
280 exec_cmd(cp_cmd)
281 else:
282 # Prepare initial ramdisk
283 initrd = "%s/initrd" % deploy_dir
284 if not os.path.isfile(initrd):
285 initrd = "%s/initrd" % img_iso_dir
286 if not os.path.isfile(initrd):
287 initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500288
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500289 install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500290 exec_cmd(install_cmd)
291
292 # Remove the temporary file created by _build_initramfs_path function
293 if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir):
294 os.remove("%s/initrd.cpio.gz" % cr_workdir)
295
Brad Bishop15ae2502019-06-18 21:44:24 -0400296 kernel = get_bitbake_var("KERNEL_IMAGETYPE")
Brad Bishop96ff1982019-08-19 13:50:42 -0400297 if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
298 if get_bitbake_var("INITRAMFS_IMAGE"):
299 kernel = "%s-%s.bin" % \
300 (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
Brad Bishop15ae2502019-06-18 21:44:24 -0400301
302 install_cmd = "install -m 0644 %s/%s %s/%s" % \
303 (kernel_dir, kernel, isodir, kernel)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304 exec_cmd(install_cmd)
305
306 #Create bootloader for efi boot
307 try:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500308 target_dir = "%s/EFI/BOOT" % isodir
309 if os.path.exists(target_dir):
310 shutil.rmtree(target_dir)
311
312 os.makedirs(target_dir)
313
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500314 if source_params['loader'] == 'grub-efi':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500315 # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
316 # didn't contains it
317 target_arch = get_bitbake_var("TARGET_SYS")
318 if not target_arch:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500319 raise WicError("Coludn't find target architecture")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500320
321 if re.match("x86_64", target_arch):
Brad Bishopc4ea0752018-11-15 14:30:15 -0800322 grub_src_image = "grub-efi-bootx64.efi"
323 grub_dest_image = "bootx64.efi"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500324 elif re.match('i.86', target_arch):
Brad Bishopc4ea0752018-11-15 14:30:15 -0800325 grub_src_image = "grub-efi-bootia32.efi"
326 grub_dest_image = "bootia32.efi"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500327 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500328 raise WicError("grub-efi is incompatible with target %s" %
329 target_arch)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500330
Brad Bishopc4ea0752018-11-15 14:30:15 -0800331 grub_target = os.path.join(target_dir, grub_dest_image)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500332 if not os.path.isfile(grub_target):
Brad Bishopc4ea0752018-11-15 14:30:15 -0800333 grub_src = os.path.join(deploy_dir, grub_src_image)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500334 if not os.path.exists(grub_src):
335 raise WicError("Grub loader %s is not found in %s. "
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800336 "Please build grub-efi first" % (grub_src_image, deploy_dir))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500337 shutil.copy(grub_src, grub_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500338
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500339 if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
340 cls.do_configure_grubefi(part, creator, target_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500341
342 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500343 raise WicError("unrecognized bootimg-efi loader: %s" %
344 source_params['loader'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500345 except KeyError:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500346 raise WicError("bootimg-efi requires a loader, none specified")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500347
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500348 # Create efi.img that contains bootloader files for EFI booting
349 # if ISODIR didn't exist or didn't contains it
350 if os.path.isfile("%s/efi.img" % img_iso_dir):
351 install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \
352 (img_iso_dir, isodir)
353 exec_cmd(install_cmd)
354 else:
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500355 # Default to 100 blocks of extra space for file system overhead
356 esp_extra_blocks = int(source_params.get('esp_extra_blocks', '100'))
357
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500358 du_cmd = "du -bks %s/EFI" % isodir
359 out = exec_cmd(du_cmd)
360 blocks = int(out.split()[0])
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500361 blocks += esp_extra_blocks
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500362 logger.debug("Added 100 extra blocks to %s to get to %d "
363 "total blocks", part.mountpoint, blocks)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500364
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365 # dosfs image for EFI boot
366 bootimg = "%s/efi.img" % isodir
367
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500368 esp_label = source_params.get('esp_label', 'EFIimg')
369
370 dosfs_cmd = 'mkfs.vfat -n \'%s\' -S 512 -C %s %d' \
371 % (esp_label, bootimg, blocks)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500372 exec_native_cmd(dosfs_cmd, native_sysroot)
373
374 mmd_cmd = "mmd -i %s ::/EFI" % bootimg
375 exec_native_cmd(mmd_cmd, native_sysroot)
376
377 mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \
378 % (bootimg, isodir)
379 exec_native_cmd(mcopy_cmd, native_sysroot)
380
381 chmod_cmd = "chmod 644 %s" % bootimg
382 exec_cmd(chmod_cmd)
383
384 # Prepare files for legacy boot
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500385 syslinux_dir = get_bitbake_var("STAGING_DATADIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500386 if not syslinux_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500387 raise WicError("Couldn't find STAGING_DATADIR, exiting.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500388
389 if os.path.exists("%s/isolinux" % isodir):
390 shutil.rmtree("%s/isolinux" % isodir)
391
392 install_cmd = "install -d %s/isolinux" % isodir
393 exec_cmd(install_cmd)
394
395 cls.do_configure_syslinux(creator, cr_workdir)
396
397 install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
398 install_cmd += "%s/isolinux/ldlinux.sys" % isodir
399 exec_cmd(install_cmd)
400
401 install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
402 install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
403 exec_cmd(install_cmd)
404
405 install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
406 install_cmd += "%s/isolinux/isolinux.bin" % isodir
407 exec_cmd(install_cmd)
408
409 install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
410 install_cmd += "%s/isolinux/ldlinux.c32" % isodir
411 exec_cmd(install_cmd)
412
413 #create ISO image
414 iso_img = "%s/tempiso_img.iso" % cr_workdir
415 iso_bootimg = "isolinux/isolinux.bin"
416 iso_bootcat = "isolinux/boot.cat"
417 efi_img = "efi.img"
418
419 mkisofs_cmd = "mkisofs -V %s " % part.label
420 mkisofs_cmd += "-o %s -U " % iso_img
421 mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
422 mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
423 mkisofs_cmd += "-boot-info-table -eltorito-alt-boot "
424 mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img
425 mkisofs_cmd += "-no-emul-boot %s " % isodir
426
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500427 logger.debug("running command: %s", mkisofs_cmd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500428 exec_native_cmd(mkisofs_cmd, native_sysroot)
429
430 shutil.rmtree(isodir)
431
432 du_cmd = "du -Lbks %s" % iso_img
433 out = exec_cmd(du_cmd)
434 isoimg_size = int(out.split()[0])
435
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500436 part.size = isoimg_size
437 part.source_file = iso_img
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500438
439 @classmethod
440 def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
441 bootimg_dir, kernel_dir, native_sysroot):
442 """
443 Called after all partitions have been prepared and assembled into a
444 disk image. In this case, we insert/modify the MBR using isohybrid
445 utility for booting via BIOS from disk storage devices.
446 """
447
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500448 iso_img = "%s.p1" % disk.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500449 full_path = creator._full_path(workdir, disk_name, "direct")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 full_path_iso = creator._full_path(workdir, disk_name, "iso")
451
452 isohybrid_cmd = "isohybrid -u %s" % iso_img
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500453 logger.debug("running command: %s", isohybrid_cmd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500454 exec_native_cmd(isohybrid_cmd, native_sysroot)
455
456 # Replace the image created by direct plugin with the one created by
457 # mkisofs command. This is necessary because the iso image created by
458 # mkisofs has a very specific MBR is system area of the ISO image, and
459 # direct plugin adds and configures an another MBR.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500460 logger.debug("Replaceing the image created by direct plugin\n")
461 os.remove(disk.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500462 shutil.copy2(iso_img, full_path_iso)
463 shutil.copy2(full_path_iso, full_path)