1*96ff1984SBrad Bishop#
2*96ff1984SBrad Bishop# This program is free software; you can redistribute it and/or modify
3*96ff1984SBrad Bishop# it under the terms of the GNU General Public License version 2 as
4*96ff1984SBrad Bishop# published by the Free Software Foundation.
5*96ff1984SBrad Bishop#
6*96ff1984SBrad Bishop# This program is distributed in the hope that it will be useful,
7*96ff1984SBrad Bishop# but WITHOUT ANY WARRANTY; without even the implied warranty of
8*96ff1984SBrad Bishop# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9*96ff1984SBrad Bishop# GNU General Public License for more details.
10*96ff1984SBrad Bishop#
11*96ff1984SBrad Bishop# You should have received a copy of the GNU General Public License along
12*96ff1984SBrad Bishop# with this program; if not, write to the Free Software Foundation, Inc.,
13*96ff1984SBrad Bishop# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14*96ff1984SBrad Bishop#
15*96ff1984SBrad Bishop# DESCRIPTION
16*96ff1984SBrad Bishop# This implements the 'bootimg-biosplusefi' source plugin class for 'wic'
17*96ff1984SBrad Bishop#
18*96ff1984SBrad Bishop# AUTHORS
19*96ff1984SBrad Bishop# William Bourque <wbourque [at) gmail.com>
20*96ff1984SBrad Bishop
21*96ff1984SBrad Bishopimport types
22*96ff1984SBrad Bishop
23*96ff1984SBrad Bishopfrom wic.pluginbase import SourcePlugin
24*96ff1984SBrad Bishopfrom importlib.machinery import SourceFileLoader
25*96ff1984SBrad Bishop
26*96ff1984SBrad Bishopclass BootimgBiosPlusEFIPlugin(SourcePlugin):
27*96ff1984SBrad Bishop    """
28*96ff1984SBrad Bishop    Create MBR + EFI boot partition
29*96ff1984SBrad Bishop
30*96ff1984SBrad Bishop    This plugin creates a boot partition that contains both
31*96ff1984SBrad Bishop    legacy BIOS and EFI content. It will be able to boot from both.
32*96ff1984SBrad Bishop    This is useful when managing PC fleet with some older machines
33*96ff1984SBrad Bishop    without EFI support.
34*96ff1984SBrad Bishop
35*96ff1984SBrad Bishop    Note it is possible to create an image that can boot from both
36*96ff1984SBrad Bishop    legacy BIOS and EFI by defining two partitions : one with arg
37*96ff1984SBrad Bishop    --source bootimg-efi  and another one with --source bootimg-pcbios.
38*96ff1984SBrad Bishop    However, this method has the obvious downside that it requires TWO
39*96ff1984SBrad Bishop    partitions to be created on the storage device.
40*96ff1984SBrad Bishop    Both partitions will also be marked as "bootable" which does not work on
41*96ff1984SBrad Bishop    most BIOS, has BIOS often uses the "bootable" flag to determine
42*96ff1984SBrad Bishop    what to boot. If you have such a BIOS, you need to manually remove the
43*96ff1984SBrad Bishop    "bootable" flag from the EFI partition for the drive to be bootable.
44*96ff1984SBrad Bishop    Having two partitions also seems to confuse wic : the content of
45*96ff1984SBrad Bishop    the first partition will be duplicated into the second, even though it
46*96ff1984SBrad Bishop    will not be used at all.
47*96ff1984SBrad Bishop
48*96ff1984SBrad Bishop    Also, unlike "isoimage-isohybrid" that also does BIOS and EFI, this plugin
49*96ff1984SBrad Bishop    allows you to have more than only a single rootfs partitions and does
50*96ff1984SBrad Bishop    not turn the rootfs into an initramfs RAM image.
51*96ff1984SBrad Bishop
52*96ff1984SBrad Bishop    This plugin is made to put everything into a single /boot partition so it
53*96ff1984SBrad Bishop    does not have the limitations listed above.
54*96ff1984SBrad Bishop
55*96ff1984SBrad Bishop    The plugin is made so it does tries not to reimplement what's already
56*96ff1984SBrad Bishop    been done in other plugins; as such it imports "bootimg-pcbios"
57*96ff1984SBrad Bishop    and "bootimg-efi".
58*96ff1984SBrad Bishop    Plugin "bootimg-pcbios" is used to generate legacy BIOS boot.
59*96ff1984SBrad Bishop    Plugin "bootimg-efi" is used to generate the UEFI boot. Note that it
60*96ff1984SBrad Bishop    requires a --sourceparams argument to know which loader to use; refer
61*96ff1984SBrad Bishop    to "bootimg-efi" code/documentation for the list of loader.
62*96ff1984SBrad Bishop
63*96ff1984SBrad Bishop    Imports are handled with "SourceFileLoader" from importlib as it is
64*96ff1984SBrad Bishop    otherwise very difficult to import module that has hyphen "-" in their
65*96ff1984SBrad Bishop    filename.
66*96ff1984SBrad Bishop    The SourcePlugin() methods used in the plugins (do_install_disk,
67*96ff1984SBrad Bishop    do_configure_partition, do_prepare_partition) are then called on both,
68*96ff1984SBrad Bishop    beginning by "bootimg-efi".
69*96ff1984SBrad Bishop
70*96ff1984SBrad Bishop    Plugin options, such as "--sourceparams" can still be passed to a
71*96ff1984SBrad Bishop    plugin, as long they does not cause issue in the other plugin.
72*96ff1984SBrad Bishop
73*96ff1984SBrad Bishop    Example wic configuration:
74*96ff1984SBrad Bishop    part /boot --source bootimg-biosplusefi --sourceparams="loader=grub-efi"\\
75*96ff1984SBrad Bishop               --ondisk sda --label os_boot --active --align 1024 --use-uuid
76*96ff1984SBrad Bishop    """
77*96ff1984SBrad Bishop
78*96ff1984SBrad Bishop    name = 'bootimg-biosplusefi'
79*96ff1984SBrad Bishop
80*96ff1984SBrad Bishop    __PCBIOS_MODULE_NAME = "bootimg-pcbios"
81*96ff1984SBrad Bishop    __EFI_MODULE_NAME = "bootimg-efi"
82*96ff1984SBrad Bishop
83*96ff1984SBrad Bishop    __imgEFIObj = None
84*96ff1984SBrad Bishop    __imgBiosObj = None
85*96ff1984SBrad Bishop
86*96ff1984SBrad Bishop    @classmethod
87*96ff1984SBrad Bishop    def __init__(cls):
88*96ff1984SBrad Bishop        """
89*96ff1984SBrad Bishop        Constructor (init)
90*96ff1984SBrad Bishop        """
91*96ff1984SBrad Bishop
92*96ff1984SBrad Bishop        # XXX
93*96ff1984SBrad Bishop        # For some reasons, __init__ constructor is never called.
94*96ff1984SBrad Bishop        # Something to do with how pluginbase works?
95*96ff1984SBrad Bishop        cls.__instanciateSubClasses()
96*96ff1984SBrad Bishop
97*96ff1984SBrad Bishop    @classmethod
98*96ff1984SBrad Bishop    def __instanciateSubClasses(cls):
99*96ff1984SBrad Bishop        """
100*96ff1984SBrad Bishop
101*96ff1984SBrad Bishop        """
102*96ff1984SBrad Bishop
103*96ff1984SBrad Bishop        # Import bootimg-pcbios (class name "BootimgPcbiosPlugin")
104*96ff1984SBrad Bishop        modulePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
105*96ff1984SBrad Bishop                                  cls.__PCBIOS_MODULE_NAME + ".py")
106*96ff1984SBrad Bishop        loader = SourceFileLoader(cls.__PCBIOS_MODULE_NAME, modulePath)
107*96ff1984SBrad Bishop        mod = types.ModuleType(loader.name)
108*96ff1984SBrad Bishop        loader.exec_module(mod)
109*96ff1984SBrad Bishop        cls.__imgBiosObj = mod.BootimgPcbiosPlugin()
110*96ff1984SBrad Bishop
111*96ff1984SBrad Bishop        # Import bootimg-efi (class name "BootimgEFIPlugin")
112*96ff1984SBrad Bishop        modulePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
113*96ff1984SBrad Bishop                                  cls.__EFI_MODULE_NAME + ".py")
114*96ff1984SBrad Bishop        loader = SourceFileLoader(cls.__EFI_MODULE_NAME, modulePath)
115*96ff1984SBrad Bishop        mod = types.ModuleType(loader.name)
116*96ff1984SBrad Bishop        loader.exec_module(mod)
117*96ff1984SBrad Bishop        cls.__imgEFIObj = mod.BootimgEFIPlugin()
118*96ff1984SBrad Bishop
119*96ff1984SBrad Bishop    @classmethod
120*96ff1984SBrad Bishop    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
121*96ff1984SBrad Bishop                        bootimg_dir, kernel_dir, native_sysroot):
122*96ff1984SBrad Bishop        """
123*96ff1984SBrad Bishop        Called after all partitions have been prepared and assembled into a
124*96ff1984SBrad Bishop        disk image.
125*96ff1984SBrad Bishop        """
126*96ff1984SBrad Bishop
127*96ff1984SBrad Bishop        if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
128*96ff1984SBrad Bishop            cls.__instanciateSubClasses()
129*96ff1984SBrad Bishop
130*96ff1984SBrad Bishop        cls.__imgEFIObj.do_install_disk(
131*96ff1984SBrad Bishop            disk,
132*96ff1984SBrad Bishop            disk_name,
133*96ff1984SBrad Bishop            creator,
134*96ff1984SBrad Bishop            workdir,
135*96ff1984SBrad Bishop            oe_builddir,
136*96ff1984SBrad Bishop            bootimg_dir,
137*96ff1984SBrad Bishop            kernel_dir,
138*96ff1984SBrad Bishop            native_sysroot)
139*96ff1984SBrad Bishop
140*96ff1984SBrad Bishop        cls.__imgBiosObj.do_install_disk(
141*96ff1984SBrad Bishop            disk,
142*96ff1984SBrad Bishop            disk_name,
143*96ff1984SBrad Bishop            creator,
144*96ff1984SBrad Bishop            workdir,
145*96ff1984SBrad Bishop            oe_builddir,
146*96ff1984SBrad Bishop            bootimg_dir,
147*96ff1984SBrad Bishop            kernel_dir,
148*96ff1984SBrad Bishop            native_sysroot)
149*96ff1984SBrad Bishop
150*96ff1984SBrad Bishop    @classmethod
151*96ff1984SBrad Bishop    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
152*96ff1984SBrad Bishop                               oe_builddir, bootimg_dir, kernel_dir,
153*96ff1984SBrad Bishop                               native_sysroot):
154*96ff1984SBrad Bishop        """
155*96ff1984SBrad Bishop        Called before do_prepare_partition()
156*96ff1984SBrad Bishop        """
157*96ff1984SBrad Bishop
158*96ff1984SBrad Bishop        if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
159*96ff1984SBrad Bishop            cls.__instanciateSubClasses()
160*96ff1984SBrad Bishop
161*96ff1984SBrad Bishop        cls.__imgEFIObj.do_configure_partition(
162*96ff1984SBrad Bishop            part,
163*96ff1984SBrad Bishop            source_params,
164*96ff1984SBrad Bishop            creator,
165*96ff1984SBrad Bishop            cr_workdir,
166*96ff1984SBrad Bishop            oe_builddir,
167*96ff1984SBrad Bishop            bootimg_dir,
168*96ff1984SBrad Bishop            kernel_dir,
169*96ff1984SBrad Bishop            native_sysroot)
170*96ff1984SBrad Bishop
171*96ff1984SBrad Bishop        cls.__imgBiosObj.do_configure_partition(
172*96ff1984SBrad Bishop            part,
173*96ff1984SBrad Bishop            source_params,
174*96ff1984SBrad Bishop            creator,
175*96ff1984SBrad Bishop            cr_workdir,
176*96ff1984SBrad Bishop            oe_builddir,
177*96ff1984SBrad Bishop            bootimg_dir,
178*96ff1984SBrad Bishop            kernel_dir,
179*96ff1984SBrad Bishop            native_sysroot)
180*96ff1984SBrad Bishop
181*96ff1984SBrad Bishop    @classmethod
182*96ff1984SBrad Bishop    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
183*96ff1984SBrad Bishop                             oe_builddir, bootimg_dir, kernel_dir,
184*96ff1984SBrad Bishop                             rootfs_dir, native_sysroot):
185*96ff1984SBrad Bishop        """
186*96ff1984SBrad Bishop        Called to do the actual content population for a partition i.e. it
187*96ff1984SBrad Bishop        'prepares' the partition to be incorporated into the image.
188*96ff1984SBrad Bishop        """
189*96ff1984SBrad Bishop
190*96ff1984SBrad Bishop        if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
191*96ff1984SBrad Bishop            cls.__instanciateSubClasses()
192*96ff1984SBrad Bishop
193*96ff1984SBrad Bishop        cls.__imgEFIObj.do_prepare_partition(
194*96ff1984SBrad Bishop            part,
195*96ff1984SBrad Bishop            source_params,
196*96ff1984SBrad Bishop            creator,
197*96ff1984SBrad Bishop            cr_workdir,
198*96ff1984SBrad Bishop            oe_builddir,
199*96ff1984SBrad Bishop            bootimg_dir,
200*96ff1984SBrad Bishop            kernel_dir,
201*96ff1984SBrad Bishop            rootfs_dir,
202*96ff1984SBrad Bishop            native_sysroot)
203*96ff1984SBrad Bishop
204*96ff1984SBrad Bishop        cls.__imgBiosObj.do_prepare_partition(
205*96ff1984SBrad Bishop            part,
206*96ff1984SBrad Bishop            source_params,
207*96ff1984SBrad Bishop            creator,
208*96ff1984SBrad Bishop            cr_workdir,
209*96ff1984SBrad Bishop            oe_builddir,
210*96ff1984SBrad Bishop            bootimg_dir,
211*96ff1984SBrad Bishop            kernel_dir,
212*96ff1984SBrad Bishop            rootfs_dir,
213*96ff1984SBrad Bishop            native_sysroot)
214