1eb8dc403SDave Cobbley# ex:ts=4:sw=4:sts=4:et
2eb8dc403SDave Cobbley# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3eb8dc403SDave Cobbley
4eb8dc403SDave Cobbley# This program is free software; you can redistribute it and/or modify
5eb8dc403SDave Cobbley# it under the terms of the GNU General Public License version 2 as
6eb8dc403SDave Cobbley# published by the Free Software Foundation.
7eb8dc403SDave Cobbley#
8eb8dc403SDave Cobbley# This program is distributed in the hope that it will be useful,
9eb8dc403SDave Cobbley# but WITHOUT ANY WARRANTY; without even the implied warranty of
10eb8dc403SDave Cobbley# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11eb8dc403SDave Cobbley# GNU General Public License for more details.
12eb8dc403SDave Cobbley#
13eb8dc403SDave Cobbley# You should have received a copy of the GNU General Public License along
14eb8dc403SDave Cobbley# with this program; if not, write to the Free Software Foundation, Inc.,
15eb8dc403SDave Cobbley# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16eb8dc403SDave Cobbley#
17eb8dc403SDave Cobbley# DESCRIPTION
18eb8dc403SDave Cobbley# This implements the 'isoimage-isohybrid' source plugin class for 'wic'
19eb8dc403SDave Cobbley#
20eb8dc403SDave Cobbley# AUTHORS
21eb8dc403SDave Cobbley# Mihaly Varga <mihaly.varga (at] ni.com>
22eb8dc403SDave Cobbley
23eb8dc403SDave Cobbleyimport glob
24eb8dc403SDave Cobbleyimport logging
25eb8dc403SDave Cobbleyimport os
26eb8dc403SDave Cobbleyimport re
27eb8dc403SDave Cobbleyimport shutil
28eb8dc403SDave Cobbley
29eb8dc403SDave Cobbleyfrom wic import WicError
30eb8dc403SDave Cobbleyfrom wic.engine import get_custom_config
31eb8dc403SDave Cobbleyfrom wic.pluginbase import SourcePlugin
32eb8dc403SDave Cobbleyfrom wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
33eb8dc403SDave Cobbley
34eb8dc403SDave Cobbleylogger = logging.getLogger('wic')
35eb8dc403SDave Cobbley
36eb8dc403SDave Cobbleyclass IsoImagePlugin(SourcePlugin):
37eb8dc403SDave Cobbley    """
38eb8dc403SDave Cobbley    Create a bootable ISO image
39eb8dc403SDave Cobbley
40eb8dc403SDave Cobbley    This plugin creates a hybrid, legacy and EFI bootable ISO image. The
41eb8dc403SDave Cobbley    generated image can be used on optical media as well as USB media.
42eb8dc403SDave Cobbley
43eb8dc403SDave Cobbley    Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not
44eb8dc403SDave Cobbley    implemented yet) as bootloader. The plugin creates the directories required
45eb8dc403SDave Cobbley    by bootloaders and populates them by creating and configuring the
46eb8dc403SDave Cobbley    bootloader files.
47eb8dc403SDave Cobbley
48eb8dc403SDave Cobbley    Example kickstart file:
49eb8dc403SDave Cobbley    part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
50*1a4b7ee2SBrad Bishop    image_name= IsoImage" --ondisk cd --label LIVECD
51eb8dc403SDave Cobbley    bootloader  --timeout=10  --append=" "
52eb8dc403SDave Cobbley
53eb8dc403SDave Cobbley    In --sourceparams "loader" specifies the bootloader used for booting in EFI
54eb8dc403SDave Cobbley    mode, while "image_name" specifies the name of the generated image. In the
55eb8dc403SDave Cobbley    example above, wic creates an ISO image named IsoImage-cd.direct (default
56eb8dc403SDave Cobbley    extension added by direct imeger plugin) and a file named IsoImage-cd.iso
57eb8dc403SDave Cobbley    """
58eb8dc403SDave Cobbley
59eb8dc403SDave Cobbley    name = 'isoimage-isohybrid'
60eb8dc403SDave Cobbley
61eb8dc403SDave Cobbley    @classmethod
62eb8dc403SDave Cobbley    def do_configure_syslinux(cls, creator, cr_workdir):
63eb8dc403SDave Cobbley        """
64eb8dc403SDave Cobbley        Create loader-specific (syslinux) config
65eb8dc403SDave Cobbley        """
66eb8dc403SDave Cobbley        splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg")
67eb8dc403SDave Cobbley        if os.path.exists(splash):
68eb8dc403SDave Cobbley            splashline = "menu background splash.jpg"
69eb8dc403SDave Cobbley        else:
70eb8dc403SDave Cobbley            splashline = ""
71eb8dc403SDave Cobbley
72eb8dc403SDave Cobbley        bootloader = creator.ks.bootloader
73eb8dc403SDave Cobbley
74eb8dc403SDave Cobbley        syslinux_conf = ""
75eb8dc403SDave Cobbley        syslinux_conf += "PROMPT 0\n"
76eb8dc403SDave Cobbley        syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10)
77eb8dc403SDave Cobbley        syslinux_conf += "\n"
78eb8dc403SDave Cobbley        syslinux_conf += "ALLOWOPTIONS 1\n"
79eb8dc403SDave Cobbley        syslinux_conf += "SERIAL 0 115200\n"
80eb8dc403SDave Cobbley        syslinux_conf += "\n"
81eb8dc403SDave Cobbley        if splashline:
82eb8dc403SDave Cobbley            syslinux_conf += "%s\n" % splashline
83eb8dc403SDave Cobbley        syslinux_conf += "DEFAULT boot\n"
84eb8dc403SDave Cobbley        syslinux_conf += "LABEL boot\n"
85eb8dc403SDave Cobbley
86eb8dc403SDave Cobbley        kernel = "/bzImage"
87eb8dc403SDave Cobbley        syslinux_conf += "KERNEL " + kernel + "\n"
88eb8dc403SDave Cobbley        syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
89eb8dc403SDave Cobbley                             % bootloader.append
90eb8dc403SDave Cobbley
91eb8dc403SDave Cobbley        logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
92eb8dc403SDave Cobbley                     cr_workdir)
93eb8dc403SDave Cobbley
94eb8dc403SDave Cobbley        with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
95eb8dc403SDave Cobbley            cfg.write(syslinux_conf)
96eb8dc403SDave Cobbley
97eb8dc403SDave Cobbley    @classmethod
98eb8dc403SDave Cobbley    def do_configure_grubefi(cls, part, creator, target_dir):
99eb8dc403SDave Cobbley        """
100eb8dc403SDave Cobbley        Create loader-specific (grub-efi) config
101eb8dc403SDave Cobbley        """
102eb8dc403SDave Cobbley        configfile = creator.ks.bootloader.configfile
103eb8dc403SDave Cobbley        if configfile:
104eb8dc403SDave Cobbley            grubefi_conf = get_custom_config(configfile)
105eb8dc403SDave Cobbley            if grubefi_conf:
106eb8dc403SDave Cobbley                logger.debug("Using custom configuration file %s for grub.cfg",
107eb8dc403SDave Cobbley                             configfile)
108eb8dc403SDave Cobbley            else:
109eb8dc403SDave Cobbley                raise WicError("configfile is specified "
110eb8dc403SDave Cobbley                               "but failed to get it from %s", configfile)
111eb8dc403SDave Cobbley        else:
112eb8dc403SDave Cobbley            splash = os.path.join(target_dir, "splash.jpg")
113eb8dc403SDave Cobbley            if os.path.exists(splash):
114eb8dc403SDave Cobbley                splashline = "menu background splash.jpg"
115eb8dc403SDave Cobbley            else:
116eb8dc403SDave Cobbley                splashline = ""
117eb8dc403SDave Cobbley
118eb8dc403SDave Cobbley            bootloader = creator.ks.bootloader
119eb8dc403SDave Cobbley
120eb8dc403SDave Cobbley            grubefi_conf = ""
121eb8dc403SDave Cobbley            grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
122eb8dc403SDave Cobbley            grubefi_conf += "--parity=no --stop=1\n"
123eb8dc403SDave Cobbley            grubefi_conf += "default=boot\n"
124eb8dc403SDave Cobbley            grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
125eb8dc403SDave Cobbley            grubefi_conf += "\n"
126eb8dc403SDave Cobbley            grubefi_conf += "search --set=root --label %s " % part.label
127eb8dc403SDave Cobbley            grubefi_conf += "\n"
128eb8dc403SDave Cobbley            grubefi_conf += "menuentry 'boot'{\n"
129eb8dc403SDave Cobbley
130eb8dc403SDave Cobbley            kernel = "/bzImage"
131eb8dc403SDave Cobbley
132eb8dc403SDave Cobbley            grubefi_conf += "linux %s rootwait %s\n" \
133eb8dc403SDave Cobbley                            % (kernel, bootloader.append)
134eb8dc403SDave Cobbley            grubefi_conf += "initrd /initrd \n"
135eb8dc403SDave Cobbley            grubefi_conf += "}\n"
136eb8dc403SDave Cobbley
137eb8dc403SDave Cobbley            if splashline:
138eb8dc403SDave Cobbley                grubefi_conf += "%s\n" % splashline
139eb8dc403SDave Cobbley
140eb8dc403SDave Cobbley        cfg_path = os.path.join(target_dir, "grub.cfg")
141eb8dc403SDave Cobbley        logger.debug("Writing grubefi config %s", cfg_path)
142eb8dc403SDave Cobbley
143eb8dc403SDave Cobbley        with open(cfg_path, "w") as cfg:
144eb8dc403SDave Cobbley            cfg.write(grubefi_conf)
145eb8dc403SDave Cobbley
146eb8dc403SDave Cobbley    @staticmethod
147eb8dc403SDave Cobbley    def _build_initramfs_path(rootfs_dir, cr_workdir):
148eb8dc403SDave Cobbley        """
149eb8dc403SDave Cobbley        Create path for initramfs image
150eb8dc403SDave Cobbley        """
151eb8dc403SDave Cobbley
152eb8dc403SDave Cobbley        initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD")
153eb8dc403SDave Cobbley        if not initrd:
154eb8dc403SDave Cobbley            initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
155eb8dc403SDave Cobbley            if not initrd_dir:
156eb8dc403SDave Cobbley                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.")
157eb8dc403SDave Cobbley
158eb8dc403SDave Cobbley            image_name = get_bitbake_var("IMAGE_BASENAME")
159eb8dc403SDave Cobbley            if not image_name:
160eb8dc403SDave Cobbley                raise WicError("Couldn't find IMAGE_BASENAME, exiting.")
161eb8dc403SDave Cobbley
162eb8dc403SDave Cobbley            image_type = get_bitbake_var("INITRAMFS_FSTYPES")
163eb8dc403SDave Cobbley            if not image_type:
164eb8dc403SDave Cobbley                raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")
165eb8dc403SDave Cobbley
166eb8dc403SDave Cobbley            machine = os.path.basename(initrd_dir)
167eb8dc403SDave Cobbley
168eb8dc403SDave Cobbley            pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
169eb8dc403SDave Cobbley            files = glob.glob(pattern)
170eb8dc403SDave Cobbley            if files:
171eb8dc403SDave Cobbley                initrd = files[0]
172eb8dc403SDave Cobbley
173eb8dc403SDave Cobbley        if not initrd or not os.path.exists(initrd):
174eb8dc403SDave Cobbley            # Create initrd from rootfs directory
175eb8dc403SDave Cobbley            initrd = "%s/initrd.cpio.gz" % cr_workdir
176eb8dc403SDave Cobbley            initrd_dir = "%s/INITRD" % cr_workdir
177eb8dc403SDave Cobbley            shutil.copytree("%s" % rootfs_dir, \
178eb8dc403SDave Cobbley                            "%s" % initrd_dir, symlinks=True)
179eb8dc403SDave Cobbley
180eb8dc403SDave Cobbley            if os.path.isfile("%s/init" % rootfs_dir):
181eb8dc403SDave Cobbley                shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir)
182eb8dc403SDave Cobbley            elif os.path.lexists("%s/init" % rootfs_dir):
183eb8dc403SDave Cobbley                os.symlink(os.readlink("%s/init" % rootfs_dir), \
184eb8dc403SDave Cobbley                            "%s/init" % initrd_dir)
185eb8dc403SDave Cobbley            elif os.path.isfile("%s/sbin/init" % rootfs_dir):
186eb8dc403SDave Cobbley                shutil.copy2("%s/sbin/init" % rootfs_dir, \
187eb8dc403SDave Cobbley                            "%s" % initrd_dir)
188eb8dc403SDave Cobbley            elif os.path.lexists("%s/sbin/init" % rootfs_dir):
189eb8dc403SDave Cobbley                os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \
190eb8dc403SDave Cobbley                            "%s/init" % initrd_dir)
191eb8dc403SDave Cobbley            else:
192eb8dc403SDave Cobbley                raise WicError("Couldn't find or build initrd, exiting.")
193eb8dc403SDave Cobbley
194*1a4b7ee2SBrad Bishop            exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
195*1a4b7ee2SBrad Bishop                     % (initrd_dir, cr_workdir), as_shell=True)
196*1a4b7ee2SBrad Bishop            exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
197eb8dc403SDave Cobbley            shutil.rmtree(initrd_dir)
198eb8dc403SDave Cobbley
199eb8dc403SDave Cobbley        return initrd
200eb8dc403SDave Cobbley
201eb8dc403SDave Cobbley    @classmethod
202eb8dc403SDave Cobbley    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
203eb8dc403SDave Cobbley                               oe_builddir, bootimg_dir, kernel_dir,
204eb8dc403SDave Cobbley                               native_sysroot):
205eb8dc403SDave Cobbley        """
206eb8dc403SDave Cobbley        Called before do_prepare_partition(), creates loader-specific config
207eb8dc403SDave Cobbley        """
208eb8dc403SDave Cobbley        isodir = "%s/ISO/" % cr_workdir
209eb8dc403SDave Cobbley
210eb8dc403SDave Cobbley        if os.path.exists(isodir):
211eb8dc403SDave Cobbley            shutil.rmtree(isodir)
212eb8dc403SDave Cobbley
213eb8dc403SDave Cobbley        install_cmd = "install -d %s " % isodir
214eb8dc403SDave Cobbley        exec_cmd(install_cmd)
215eb8dc403SDave Cobbley
216eb8dc403SDave Cobbley        # Overwrite the name of the created image
217eb8dc403SDave Cobbley        logger.debug(source_params)
218eb8dc403SDave Cobbley        if 'image_name' in source_params and \
219eb8dc403SDave Cobbley                    source_params['image_name'].strip():
220eb8dc403SDave Cobbley            creator.name = source_params['image_name'].strip()
221eb8dc403SDave Cobbley            logger.debug("The name of the image is: %s", creator.name)
222eb8dc403SDave Cobbley
223eb8dc403SDave Cobbley    @classmethod
224eb8dc403SDave Cobbley    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
225eb8dc403SDave Cobbley                             oe_builddir, bootimg_dir, kernel_dir,
226eb8dc403SDave Cobbley                             rootfs_dir, native_sysroot):
227eb8dc403SDave Cobbley        """
228eb8dc403SDave Cobbley        Called to do the actual content population for a partition i.e. it
229eb8dc403SDave Cobbley        'prepares' the partition to be incorporated into the image.
230eb8dc403SDave Cobbley        In this case, prepare content for a bootable ISO image.
231eb8dc403SDave Cobbley        """
232eb8dc403SDave Cobbley
233eb8dc403SDave Cobbley        isodir = "%s/ISO" % cr_workdir
234eb8dc403SDave Cobbley
235eb8dc403SDave Cobbley        if part.rootfs_dir is None:
236eb8dc403SDave Cobbley            if not 'ROOTFS_DIR' in rootfs_dir:
237eb8dc403SDave Cobbley                raise WicError("Couldn't find --rootfs-dir, exiting.")
238eb8dc403SDave Cobbley            rootfs_dir = rootfs_dir['ROOTFS_DIR']
239eb8dc403SDave Cobbley        else:
240eb8dc403SDave Cobbley            if part.rootfs_dir in rootfs_dir:
241eb8dc403SDave Cobbley                rootfs_dir = rootfs_dir[part.rootfs_dir]
242eb8dc403SDave Cobbley            elif part.rootfs_dir:
243eb8dc403SDave Cobbley                rootfs_dir = part.rootfs_dir
244eb8dc403SDave Cobbley            else:
245eb8dc403SDave Cobbley                raise WicError("Couldn't find --rootfs-dir=%s connection "
246eb8dc403SDave Cobbley                               "or it is not a valid path, exiting." %
247eb8dc403SDave Cobbley                               part.rootfs_dir)
248eb8dc403SDave Cobbley
249eb8dc403SDave Cobbley        if not os.path.isdir(rootfs_dir):
250eb8dc403SDave Cobbley            rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
251eb8dc403SDave Cobbley        if not os.path.isdir(rootfs_dir):
252eb8dc403SDave Cobbley            raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
253eb8dc403SDave Cobbley
254eb8dc403SDave Cobbley        part.rootfs_dir = rootfs_dir
255eb8dc403SDave Cobbley        deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
256eb8dc403SDave Cobbley        img_iso_dir = get_bitbake_var("ISODIR")
257eb8dc403SDave Cobbley
258eb8dc403SDave Cobbley        # Remove the temporary file created by part.prepare_rootfs()
259eb8dc403SDave Cobbley        if os.path.isfile(part.source_file):
260eb8dc403SDave Cobbley            os.remove(part.source_file)
261eb8dc403SDave Cobbley
262eb8dc403SDave Cobbley        # Support using a different initrd other than default
263eb8dc403SDave Cobbley        if source_params.get('initrd'):
264eb8dc403SDave Cobbley            initrd = source_params['initrd']
265eb8dc403SDave Cobbley            if not deploy_dir:
266eb8dc403SDave Cobbley                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
267eb8dc403SDave Cobbley            cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir)
268eb8dc403SDave Cobbley            exec_cmd(cp_cmd)
269eb8dc403SDave Cobbley        else:
270eb8dc403SDave Cobbley            # Prepare initial ramdisk
271eb8dc403SDave Cobbley            initrd = "%s/initrd" % deploy_dir
272eb8dc403SDave Cobbley            if not os.path.isfile(initrd):
273eb8dc403SDave Cobbley                initrd = "%s/initrd" % img_iso_dir
274eb8dc403SDave Cobbley            if not os.path.isfile(initrd):
275eb8dc403SDave Cobbley                initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir)
276eb8dc403SDave Cobbley
277eb8dc403SDave Cobbley        install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir)
278eb8dc403SDave Cobbley        exec_cmd(install_cmd)
279eb8dc403SDave Cobbley
280eb8dc403SDave Cobbley        # Remove the temporary file created by _build_initramfs_path function
281eb8dc403SDave Cobbley        if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir):
282eb8dc403SDave Cobbley            os.remove("%s/initrd.cpio.gz" % cr_workdir)
283eb8dc403SDave Cobbley
284eb8dc403SDave Cobbley        # Install bzImage
285eb8dc403SDave Cobbley        install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
286eb8dc403SDave Cobbley                      (kernel_dir, isodir)
287eb8dc403SDave Cobbley        exec_cmd(install_cmd)
288eb8dc403SDave Cobbley
289eb8dc403SDave Cobbley        #Create bootloader for efi boot
290eb8dc403SDave Cobbley        try:
291eb8dc403SDave Cobbley            target_dir = "%s/EFI/BOOT" % isodir
292eb8dc403SDave Cobbley            if os.path.exists(target_dir):
293eb8dc403SDave Cobbley                shutil.rmtree(target_dir)
294eb8dc403SDave Cobbley
295eb8dc403SDave Cobbley            os.makedirs(target_dir)
296eb8dc403SDave Cobbley
297eb8dc403SDave Cobbley            if source_params['loader'] == 'grub-efi':
298eb8dc403SDave Cobbley                # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
299eb8dc403SDave Cobbley                # didn't contains it
300eb8dc403SDave Cobbley                target_arch = get_bitbake_var("TARGET_SYS")
301eb8dc403SDave Cobbley                if not target_arch:
302eb8dc403SDave Cobbley                    raise WicError("Coludn't find target architecture")
303eb8dc403SDave Cobbley
304eb8dc403SDave Cobbley                if re.match("x86_64", target_arch):
305c4ea075dSBrad Bishop                    grub_src_image = "grub-efi-bootx64.efi"
306c4ea075dSBrad Bishop                    grub_dest_image = "bootx64.efi"
307eb8dc403SDave Cobbley                elif re.match('i.86', target_arch):
308c4ea075dSBrad Bishop                    grub_src_image = "grub-efi-bootia32.efi"
309c4ea075dSBrad Bishop                    grub_dest_image = "bootia32.efi"
310eb8dc403SDave Cobbley                else:
311eb8dc403SDave Cobbley                    raise WicError("grub-efi is incompatible with target %s" %
312eb8dc403SDave Cobbley                                   target_arch)
313eb8dc403SDave Cobbley
314c4ea075dSBrad Bishop                grub_target = os.path.join(target_dir, grub_dest_image)
315eb8dc403SDave Cobbley                if not os.path.isfile(grub_target):
316c4ea075dSBrad Bishop                    grub_src = os.path.join(deploy_dir, grub_src_image)
317eb8dc403SDave Cobbley                    if not os.path.exists(grub_src):
318eb8dc403SDave Cobbley                        raise WicError("Grub loader %s is not found in %s. "
319*1a4b7ee2SBrad Bishop                                       "Please build grub-efi first" % (grub_src_image, deploy_dir))
320eb8dc403SDave Cobbley                    shutil.copy(grub_src, grub_target)
321eb8dc403SDave Cobbley
322eb8dc403SDave Cobbley                if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
323eb8dc403SDave Cobbley                    cls.do_configure_grubefi(part, creator, target_dir)
324eb8dc403SDave Cobbley
325eb8dc403SDave Cobbley            else:
326eb8dc403SDave Cobbley                raise WicError("unrecognized bootimg-efi loader: %s" %
327eb8dc403SDave Cobbley                               source_params['loader'])
328eb8dc403SDave Cobbley        except KeyError:
329eb8dc403SDave Cobbley            raise WicError("bootimg-efi requires a loader, none specified")
330eb8dc403SDave Cobbley
331eb8dc403SDave Cobbley        # Create efi.img that contains bootloader files for EFI booting
332eb8dc403SDave Cobbley        # if ISODIR didn't exist or didn't contains it
333eb8dc403SDave Cobbley        if os.path.isfile("%s/efi.img" % img_iso_dir):
334eb8dc403SDave Cobbley            install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \
335eb8dc403SDave Cobbley                (img_iso_dir, isodir)
336eb8dc403SDave Cobbley            exec_cmd(install_cmd)
337eb8dc403SDave Cobbley        else:
338eb8dc403SDave Cobbley            du_cmd = "du -bks %s/EFI" % isodir
339eb8dc403SDave Cobbley            out = exec_cmd(du_cmd)
340eb8dc403SDave Cobbley            blocks = int(out.split()[0])
341eb8dc403SDave Cobbley            # Add some extra space for file system overhead
342eb8dc403SDave Cobbley            blocks += 100
343eb8dc403SDave Cobbley            logger.debug("Added 100 extra blocks to %s to get to %d "
344eb8dc403SDave Cobbley                         "total blocks", part.mountpoint, blocks)
345eb8dc403SDave Cobbley
346eb8dc403SDave Cobbley            # dosfs image for EFI boot
347eb8dc403SDave Cobbley            bootimg = "%s/efi.img" % isodir
348eb8dc403SDave Cobbley
349eb8dc403SDave Cobbley            dosfs_cmd = 'mkfs.vfat -n "EFIimg" -S 512 -C %s %d' \
350eb8dc403SDave Cobbley                        % (bootimg, blocks)
351eb8dc403SDave Cobbley            exec_native_cmd(dosfs_cmd, native_sysroot)
352eb8dc403SDave Cobbley
353eb8dc403SDave Cobbley            mmd_cmd = "mmd -i %s ::/EFI" % bootimg
354eb8dc403SDave Cobbley            exec_native_cmd(mmd_cmd, native_sysroot)
355eb8dc403SDave Cobbley
356eb8dc403SDave Cobbley            mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \
357eb8dc403SDave Cobbley                        % (bootimg, isodir)
358eb8dc403SDave Cobbley            exec_native_cmd(mcopy_cmd, native_sysroot)
359eb8dc403SDave Cobbley
360eb8dc403SDave Cobbley            chmod_cmd = "chmod 644 %s" % bootimg
361eb8dc403SDave Cobbley            exec_cmd(chmod_cmd)
362eb8dc403SDave Cobbley
363eb8dc403SDave Cobbley        # Prepare files for legacy boot
364eb8dc403SDave Cobbley        syslinux_dir = get_bitbake_var("STAGING_DATADIR")
365eb8dc403SDave Cobbley        if not syslinux_dir:
366eb8dc403SDave Cobbley            raise WicError("Couldn't find STAGING_DATADIR, exiting.")
367eb8dc403SDave Cobbley
368eb8dc403SDave Cobbley        if os.path.exists("%s/isolinux" % isodir):
369eb8dc403SDave Cobbley            shutil.rmtree("%s/isolinux" % isodir)
370eb8dc403SDave Cobbley
371eb8dc403SDave Cobbley        install_cmd = "install -d %s/isolinux" % isodir
372eb8dc403SDave Cobbley        exec_cmd(install_cmd)
373eb8dc403SDave Cobbley
374eb8dc403SDave Cobbley        cls.do_configure_syslinux(creator, cr_workdir)
375eb8dc403SDave Cobbley
376eb8dc403SDave Cobbley        install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
377eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/ldlinux.sys" % isodir
378eb8dc403SDave Cobbley        exec_cmd(install_cmd)
379eb8dc403SDave Cobbley
380eb8dc403SDave Cobbley        install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
381eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
382eb8dc403SDave Cobbley        exec_cmd(install_cmd)
383eb8dc403SDave Cobbley
384eb8dc403SDave Cobbley        install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
385eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/isolinux.bin" % isodir
386eb8dc403SDave Cobbley        exec_cmd(install_cmd)
387eb8dc403SDave Cobbley
388eb8dc403SDave Cobbley        install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
389eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/ldlinux.c32" % isodir
390eb8dc403SDave Cobbley        exec_cmd(install_cmd)
391eb8dc403SDave Cobbley
392eb8dc403SDave Cobbley        #create ISO image
393eb8dc403SDave Cobbley        iso_img = "%s/tempiso_img.iso" % cr_workdir
394eb8dc403SDave Cobbley        iso_bootimg = "isolinux/isolinux.bin"
395eb8dc403SDave Cobbley        iso_bootcat = "isolinux/boot.cat"
396eb8dc403SDave Cobbley        efi_img = "efi.img"
397eb8dc403SDave Cobbley
398eb8dc403SDave Cobbley        mkisofs_cmd = "mkisofs -V %s " % part.label
399eb8dc403SDave Cobbley        mkisofs_cmd += "-o %s -U " % iso_img
400eb8dc403SDave Cobbley        mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
401eb8dc403SDave Cobbley        mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
402eb8dc403SDave Cobbley        mkisofs_cmd += "-boot-info-table -eltorito-alt-boot "
403eb8dc403SDave Cobbley        mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img
404eb8dc403SDave Cobbley        mkisofs_cmd += "-no-emul-boot %s " % isodir
405eb8dc403SDave Cobbley
406eb8dc403SDave Cobbley        logger.debug("running command: %s", mkisofs_cmd)
407eb8dc403SDave Cobbley        exec_native_cmd(mkisofs_cmd, native_sysroot)
408eb8dc403SDave Cobbley
409eb8dc403SDave Cobbley        shutil.rmtree(isodir)
410eb8dc403SDave Cobbley
411eb8dc403SDave Cobbley        du_cmd = "du -Lbks %s" % iso_img
412eb8dc403SDave Cobbley        out = exec_cmd(du_cmd)
413eb8dc403SDave Cobbley        isoimg_size = int(out.split()[0])
414eb8dc403SDave Cobbley
415eb8dc403SDave Cobbley        part.size = isoimg_size
416eb8dc403SDave Cobbley        part.source_file = iso_img
417eb8dc403SDave Cobbley
418eb8dc403SDave Cobbley    @classmethod
419eb8dc403SDave Cobbley    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
420eb8dc403SDave Cobbley                        bootimg_dir, kernel_dir, native_sysroot):
421eb8dc403SDave Cobbley        """
422eb8dc403SDave Cobbley        Called after all partitions have been prepared and assembled into a
423eb8dc403SDave Cobbley        disk image.  In this case, we insert/modify the MBR using isohybrid
424eb8dc403SDave Cobbley        utility for booting via BIOS from disk storage devices.
425eb8dc403SDave Cobbley        """
426eb8dc403SDave Cobbley
427eb8dc403SDave Cobbley        iso_img = "%s.p1" % disk.path
428eb8dc403SDave Cobbley        full_path = creator._full_path(workdir, disk_name, "direct")
429eb8dc403SDave Cobbley        full_path_iso = creator._full_path(workdir, disk_name, "iso")
430eb8dc403SDave Cobbley
431eb8dc403SDave Cobbley        isohybrid_cmd = "isohybrid -u %s" % iso_img
432eb8dc403SDave Cobbley        logger.debug("running command: %s", isohybrid_cmd)
433eb8dc403SDave Cobbley        exec_native_cmd(isohybrid_cmd, native_sysroot)
434eb8dc403SDave Cobbley
435eb8dc403SDave Cobbley        # Replace the image created by direct plugin with the one created by
436eb8dc403SDave Cobbley        # mkisofs command. This is necessary because the iso image created by
437eb8dc403SDave Cobbley        # mkisofs has a very specific MBR is system area of the ISO image, and
438eb8dc403SDave Cobbley        # direct plugin adds and configures an another MBR.
439eb8dc403SDave Cobbley        logger.debug("Replaceing the image created by direct plugin\n")
440eb8dc403SDave Cobbley        os.remove(disk.path)
441eb8dc403SDave Cobbley        shutil.copy2(iso_img, full_path_iso)
442eb8dc403SDave Cobbley        shutil.copy2(full_path_iso, full_path)
443