214 lines
7.3 KiB
Python
214 lines
7.3 KiB
Python
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License version 2 as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
#
|
|
# DESCRIPTION
|
|
# This implements the 'bootimg-biosplusefi' source plugin class for 'wic'
|
|
#
|
|
# AUTHORS
|
|
# William Bourque <wbourque [at) gmail.com>
|
|
|
|
import types
|
|
|
|
from wic.pluginbase import SourcePlugin
|
|
from importlib.machinery import SourceFileLoader
|
|
|
|
class BootimgBiosPlusEFIPlugin(SourcePlugin):
|
|
"""
|
|
Create MBR + EFI boot partition
|
|
|
|
This plugin creates a boot partition that contains both
|
|
legacy BIOS and EFI content. It will be able to boot from both.
|
|
This is useful when managing PC fleet with some older machines
|
|
without EFI support.
|
|
|
|
Note it is possible to create an image that can boot from both
|
|
legacy BIOS and EFI by defining two partitions : one with arg
|
|
--source bootimg-efi and another one with --source bootimg-pcbios.
|
|
However, this method has the obvious downside that it requires TWO
|
|
partitions to be created on the storage device.
|
|
Both partitions will also be marked as "bootable" which does not work on
|
|
most BIOS, has BIOS often uses the "bootable" flag to determine
|
|
what to boot. If you have such a BIOS, you need to manually remove the
|
|
"bootable" flag from the EFI partition for the drive to be bootable.
|
|
Having two partitions also seems to confuse wic : the content of
|
|
the first partition will be duplicated into the second, even though it
|
|
will not be used at all.
|
|
|
|
Also, unlike "isoimage-isohybrid" that also does BIOS and EFI, this plugin
|
|
allows you to have more than only a single rootfs partitions and does
|
|
not turn the rootfs into an initramfs RAM image.
|
|
|
|
This plugin is made to put everything into a single /boot partition so it
|
|
does not have the limitations listed above.
|
|
|
|
The plugin is made so it does tries not to reimplement what's already
|
|
been done in other plugins; as such it imports "bootimg-pcbios"
|
|
and "bootimg-efi".
|
|
Plugin "bootimg-pcbios" is used to generate legacy BIOS boot.
|
|
Plugin "bootimg-efi" is used to generate the UEFI boot. Note that it
|
|
requires a --sourceparams argument to know which loader to use; refer
|
|
to "bootimg-efi" code/documentation for the list of loader.
|
|
|
|
Imports are handled with "SourceFileLoader" from importlib as it is
|
|
otherwise very difficult to import module that has hyphen "-" in their
|
|
filename.
|
|
The SourcePlugin() methods used in the plugins (do_install_disk,
|
|
do_configure_partition, do_prepare_partition) are then called on both,
|
|
beginning by "bootimg-efi".
|
|
|
|
Plugin options, such as "--sourceparams" can still be passed to a
|
|
plugin, as long they does not cause issue in the other plugin.
|
|
|
|
Example wic configuration:
|
|
part /boot --source bootimg-biosplusefi --sourceparams="loader=grub-efi"\\
|
|
--ondisk sda --label os_boot --active --align 1024 --use-uuid
|
|
"""
|
|
|
|
name = 'bootimg-biosplusefi'
|
|
|
|
__PCBIOS_MODULE_NAME = "bootimg-pcbios"
|
|
__EFI_MODULE_NAME = "bootimg-efi"
|
|
|
|
__imgEFIObj = None
|
|
__imgBiosObj = None
|
|
|
|
@classmethod
|
|
def __init__(cls):
|
|
"""
|
|
Constructor (init)
|
|
"""
|
|
|
|
# XXX
|
|
# For some reasons, __init__ constructor is never called.
|
|
# Something to do with how pluginbase works?
|
|
cls.__instanciateSubClasses()
|
|
|
|
@classmethod
|
|
def __instanciateSubClasses(cls):
|
|
"""
|
|
|
|
"""
|
|
|
|
# Import bootimg-pcbios (class name "BootimgPcbiosPlugin")
|
|
modulePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
|
cls.__PCBIOS_MODULE_NAME + ".py")
|
|
loader = SourceFileLoader(cls.__PCBIOS_MODULE_NAME, modulePath)
|
|
mod = types.ModuleType(loader.name)
|
|
loader.exec_module(mod)
|
|
cls.__imgBiosObj = mod.BootimgPcbiosPlugin()
|
|
|
|
# Import bootimg-efi (class name "BootimgEFIPlugin")
|
|
modulePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
|
cls.__EFI_MODULE_NAME + ".py")
|
|
loader = SourceFileLoader(cls.__EFI_MODULE_NAME, modulePath)
|
|
mod = types.ModuleType(loader.name)
|
|
loader.exec_module(mod)
|
|
cls.__imgEFIObj = mod.BootimgEFIPlugin()
|
|
|
|
@classmethod
|
|
def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
|
|
bootimg_dir, kernel_dir, native_sysroot):
|
|
"""
|
|
Called after all partitions have been prepared and assembled into a
|
|
disk image.
|
|
"""
|
|
|
|
if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
|
|
cls.__instanciateSubClasses()
|
|
|
|
cls.__imgEFIObj.do_install_disk(
|
|
disk,
|
|
disk_name,
|
|
creator,
|
|
workdir,
|
|
oe_builddir,
|
|
bootimg_dir,
|
|
kernel_dir,
|
|
native_sysroot)
|
|
|
|
cls.__imgBiosObj.do_install_disk(
|
|
disk,
|
|
disk_name,
|
|
creator,
|
|
workdir,
|
|
oe_builddir,
|
|
bootimg_dir,
|
|
kernel_dir,
|
|
native_sysroot)
|
|
|
|
@classmethod
|
|
def do_configure_partition(cls, part, source_params, creator, cr_workdir,
|
|
oe_builddir, bootimg_dir, kernel_dir,
|
|
native_sysroot):
|
|
"""
|
|
Called before do_prepare_partition()
|
|
"""
|
|
|
|
if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
|
|
cls.__instanciateSubClasses()
|
|
|
|
cls.__imgEFIObj.do_configure_partition(
|
|
part,
|
|
source_params,
|
|
creator,
|
|
cr_workdir,
|
|
oe_builddir,
|
|
bootimg_dir,
|
|
kernel_dir,
|
|
native_sysroot)
|
|
|
|
cls.__imgBiosObj.do_configure_partition(
|
|
part,
|
|
source_params,
|
|
creator,
|
|
cr_workdir,
|
|
oe_builddir,
|
|
bootimg_dir,
|
|
kernel_dir,
|
|
native_sysroot)
|
|
|
|
@classmethod
|
|
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
|
|
oe_builddir, bootimg_dir, kernel_dir,
|
|
rootfs_dir, native_sysroot):
|
|
"""
|
|
Called to do the actual content population for a partition i.e. it
|
|
'prepares' the partition to be incorporated into the image.
|
|
"""
|
|
|
|
if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
|
|
cls.__instanciateSubClasses()
|
|
|
|
cls.__imgEFIObj.do_prepare_partition(
|
|
part,
|
|
source_params,
|
|
creator,
|
|
cr_workdir,
|
|
oe_builddir,
|
|
bootimg_dir,
|
|
kernel_dir,
|
|
rootfs_dir,
|
|
native_sysroot)
|
|
|
|
cls.__imgBiosObj.do_prepare_partition(
|
|
part,
|
|
source_params,
|
|
creator,
|
|
cr_workdir,
|
|
oe_builddir,
|
|
bootimg_dir,
|
|
kernel_dir,
|
|
rootfs_dir,
|
|
native_sysroot)
|