Skip to content

Commit

Permalink
Merge pull request #2590 from OSInside/efi_only
Browse files Browse the repository at this point in the history
Add new eficsm type attribute
  • Loading branch information
Conan-Kudo authored Jul 11, 2024
2 parents 09ad272 + dd8fd58 commit 1453d93
Show file tree
Hide file tree
Showing 18 changed files with 130 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<rpm-check-signatures>false</rpm-check-signatures>
<bootsplash-theme>breeze</bootsplash-theme>
<bootloader-theme>openSUSE</bootloader-theme>
<type image="oem" filesystem="ext3" kernelcmdline="console=ttyS0" firmware="uefi" format="vmdk">
<type image="oem" filesystem="ext3" kernelcmdline="console=ttyS0" firmware="uefi" eficsm="false" format="vmdk">
<oemconfig>
<oem-resize>false</oem-resize>
</oemconfig>
Expand Down
2 changes: 1 addition & 1 deletion build-tests/x86/tumbleweed/test-image-live/appliance.kiwi
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</type>
</preferences>
<preferences profiles="Secure">
<type image="iso" flags="overlay" firmware="uefi" kernelcmdline="console=ttyS0" hybridpersistent_filesystem="ext4" hybridpersistent="true" mediacheck="true">
<type image="iso" flags="overlay" firmware="uefi" eficsm="false" kernelcmdline="console=ttyS0" hybridpersistent_filesystem="ext4" hybridpersistent="true" mediacheck="true">
<bootloader name="grub2" console="serial" timeout="10"/>
</type>
</preferences>
Expand Down
35 changes: 29 additions & 6 deletions doc/source/image_description/elements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ bootpartsize="nonNegativeInteger":
specifies the size in MB. If not set the boot partition
size is set to 200 MB

eficsm="true|false":
For images with an EFI layout, specify if the legacy
CSM (BIOS) mode should be supported or not. By default
CSM mode is enabled.

efipartsize="nonNegativeInteger":
For images with an EFI fat partition this attribute
specifies the size in MB. If not set the EFI partition
Expand Down Expand Up @@ -483,14 +488,32 @@ editbootinstall="file_path":
filesystem="btrfs|ext2|ext3|ext4|squashfs|xfs":
The root filesystem

firmware="efi|uefi":
Specifies the boot firmware of the appliance, supported
options are: `bios`, `ec2`, `efi`, `uefi`, `ofw` and `opal`.
This attribute is used to differentiate the image according to the
firmware which boots up the system. It mostly impacts the disk
layout and the partition table type. By default `bios` is used on x86,
firmware="efi|uefi|bios|ec2|ofw|opal":
Specifies the boot firmware of the appliance. This attribute is
used to differentiate the image according to the firmware which
boots up the system. It mostly impacts the disk layout and the
partition table type. By default `bios` is used on x86,
`ofw` on PowerPC and `efi` on ARM.

* `efi`
Standard EFI layout

* `uefi`
Standard EFI layout for secure boot

* `bios`
Standard BIOS layout for x86

* `ec2`
Standard BIOS layout for x86 using Xen grub modules for old
style Xen boot in Amazon EC2

* `ofw`
Standard PPC layout

* `opal`
Standard openPOWER PPC64 layout. kexec based boot process

force_mbr="true|false":
Boolean parameter to force the usage of a MBR partition
table even if the system would default to GPT. This is occasionally
Expand Down
7 changes: 7 additions & 0 deletions kiwi/bootloader/install/grub2.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ def install_required(self):
'No grub boot code installation on %s', self.arch
)
return False
elif self.firmware.efi_mode() and not self.firmware.legacy_bios_mode():
# In EFI mode without CSM, no install
# of grub2 boot code makes sense
log.info(
'No grub boot code installation in EFI only mode'
)
return False
return True

def install(self):
Expand Down
3 changes: 2 additions & 1 deletion kiwi/builder/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ def create_install_iso(self) -> None:
'volume_id': self.iso_volume_id,
'mbr_id': self.mbrid.get_id(),
'efi_mode': self.firmware.efi_mode(),
'ofw_mode': self.firmware.ofw_mode()
'ofw_mode': self.firmware.ofw_mode(),
'legacy_bios_mode': self.firmware.legacy_bios_mode()
}
}

Expand Down
3 changes: 2 additions & 1 deletion kiwi/builder/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ def create(self) -> Result:
'preparer': Defaults.get_preparer(),
'volume_id': self.volume_id,
'mbr_id': self.mbrid.get_id(),
'efi_mode': self.firmware.efi_mode()
'efi_mode': self.firmware.efi_mode(),
'legacy_bios_mode': self.firmware.legacy_bios_mode()
}
}

Expand Down
2 changes: 1 addition & 1 deletion kiwi/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ def get_firmware_types():
:rtype: dict
"""
return {
'x86_64': ['efi', 'uefi', 'bios', 'ec2hvm', 'ec2'],
'x86_64': ['efi', 'uefi', 'bios', 'ec2'],
'i586': ['bios'],
'i686': ['bios'],
'ix86': ['bios'],
Expand Down
11 changes: 8 additions & 3 deletions kiwi/firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def __init__(self, xml_state):
self.firmware = xml_state.build_type.get_firmware()
self.efipart_mbytes = xml_state.build_type.get_efipartsize()
self.efi_partition_table = xml_state.build_type.get_efiparttable()
self.efi_csm = True if xml_state.build_type.get_eficsm() is None \
else xml_state.build_type.get_eficsm()

if not self.firmware:
self.firmware = Defaults.get_default_firmware(self.arch)
Expand Down Expand Up @@ -75,7 +77,7 @@ def get_partition_table_type(self):
else:
return 'msdos'

def legacy_bios_mode(self):
def legacy_bios_mode(self) -> bool:
"""
Check if the legacy boot from BIOS systems should be activated
Expand All @@ -84,14 +86,16 @@ def legacy_bios_mode(self):
:rtype: bool
"""
if self.get_partition_table_type() == 'gpt':
if self.arch == 'x86_64' or re.match('i.86', self.arch):
if (self.arch == 'x86_64' or re.match('i.86', self.arch)) and \
(self.firmware == 'efi' or self.firmware == 'uefi') and \
self.efi_csm:
return True
else:
return False
else:
return False

def efi_mode(self):
def efi_mode(self) -> str:
"""
Check if EFI mode is requested
Expand All @@ -101,6 +105,7 @@ def efi_mode(self):
"""
if self.firmware in Defaults.get_efi_capable_firmware_names():
return self.firmware
return ''

def ec2_mode(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions kiwi/iso_tools/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import shutil
import logging
from typing import (
Dict, List
Dict, List, Union
)

# project
Expand Down Expand Up @@ -61,7 +61,7 @@ def get_tool_name(self) -> str:
raise NotImplementedError

def init_iso_creation_parameters(
self, custom_args: Dict[str, str] = None
self, custom_args: Dict[str, Union[str, bool]] = None
) -> None:
"""
Create a set of standard parameters for the main loader
Expand Down
17 changes: 10 additions & 7 deletions kiwi/iso_tools/xorriso.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import os
import logging
from typing import (
Dict, List, Optional
Dict, List, Optional, Union
)

# project
Expand Down Expand Up @@ -66,36 +66,39 @@ def get_tool_name(self) -> str:
raise KiwiIsoToolError('xorriso tool not found')

def init_iso_creation_parameters(
self, custom_args: Optional[Dict[str, str]] = None
self, custom_args: Optional[Dict[str, Union[str, bool]]] = None
) -> None:
"""
Create a set of standard parameters
:param list custom_args: custom ISO meta data
"""
legacy_bios_mode = True
if custom_args:
if 'mbr_id' in custom_args:
self.iso_parameters += [
'-application_id', custom_args['mbr_id']
'-application_id', format(custom_args['mbr_id'])
]
if 'publisher' in custom_args:
self.iso_parameters += [
'-publisher', custom_args['publisher']
'-publisher', format(custom_args['publisher'])
]
if 'preparer' in custom_args:
self.iso_parameters += [
'-preparer_id', custom_args['preparer']
'-preparer_id', format(custom_args['preparer'])
]
if 'volume_id' in custom_args:
self.iso_parameters += [
'-volid', custom_args['volume_id']
'-volid', format(custom_args['volume_id'])
]
if 'legacy_bios_mode' in custom_args:
legacy_bios_mode = bool(custom_args['legacy_bios_mode'])
catalog_file = self.boot_path + '/boot.catalog'
self.iso_parameters += [
'-joliet', 'on', '-padding', '0'
]

if Defaults.is_x86_arch(self.arch):
if Defaults.is_x86_arch(self.arch) and legacy_bios_mode:
mbr_file = os.sep.join(
[
self.source_dir, self.boot_path, 'loader',
Expand Down
10 changes: 10 additions & 0 deletions kiwi/schema/kiwi.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,15 @@ div {
sch:param [ name = "attr" value = "efipartsize" ]
sch:param [ name = "types" value = "oem" ]
]
k.type.eficsm.attribute =
## For images with an EFI layout, specify if the legacy
## CSM (BIOS) mode should be supported or not. By default
## CSM mode is enabled
attribute eficsm { xsd:boolean }
>> sch:pattern [ id = "eficsm" is-a = "image_type"
sch:param [ name = "attr" value = "eficsm" ]
sch:param [ name = "types" value = "oem iso" ]
]
k.type.efifatimagesize.attribute =
## For ISO images (live and install) the EFI boot requires
## an embedded FAT image. This attribute specifies the size
Expand Down Expand Up @@ -2235,6 +2244,7 @@ div {
k.type.bootpartsize.attribute? &
k.type.efipartsize.attribute? &
k.type.efifatimagesize.attribute? &
k.type.eficsm.attribute? &
k.type.efiparttable.attribute? &
k.type.dosparttable_extended_layout.attribute? &
k.type.bootprofile.attribute? &
Expand Down
15 changes: 15 additions & 0 deletions kiwi/schema/kiwi.rng
Original file line number Diff line number Diff line change
Expand Up @@ -2293,6 +2293,18 @@ size is set to 20 MB</a:documentation>
<sch:param name="types" value="oem"/>
</sch:pattern>
</define>
<define name="k.type.eficsm.attribute">
<attribute name="eficsm">
<a:documentation>For images with an EFI layout, specify if the legacy
CSM (BIOS) mode should be supported or not. By default
CSM mode is enabled</a:documentation>
<data type="boolean"/>
</attribute>
<sch:pattern id="eficsm" is-a="image_type">
<sch:param name="attr" value="eficsm"/>
<sch:param name="types" value="oem iso"/>
</sch:pattern>
</define>
<define name="k.type.efifatimagesize.attribute">
<attribute name="efifatimagesize">
<a:documentation>For ISO images (live and install) the EFI boot requires
Expand Down Expand Up @@ -3192,6 +3204,9 @@ kiwi-ng result bundle ...</a:documentation>
<optional>
<ref name="k.type.efifatimagesize.attribute"/>
</optional>
<optional>
<ref name="k.type.eficsm.attribute"/>
</optional>
<optional>
<ref name="k.type.efiparttable.attribute"/>
</optional>
Expand Down
19 changes: 17 additions & 2 deletions kiwi/xml_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#
# Generated by generateDS.py version 2.29.24.
# Python 3.11.9 (main, Apr 18 2024, 16:44:43) [GCC]
# Python 3.11.8 (main, Feb 29 2024, 12:19:47) [GCC]
#
# Command line options:
# ('-f', '')
Expand Down Expand Up @@ -3067,7 +3067,7 @@ class type_(GeneratedsSuper):
"""The Image Type of the Logical Extend"""
subclass = None
superclass = None
def __init__(self, boot=None, bootfilesystem=None, firmware=None, bootkernel=None, bootpartition=None, bootpartsize=None, efipartsize=None, efifatimagesize=None, efiparttable=None, dosparttable_extended_layout=None, bootprofile=None, btrfs_quota_groups=None, btrfs_root_is_snapshot=None, btrfs_root_is_subvolume=None, btrfs_set_default_volume=None, btrfs_root_is_readonly_snapshot=None, compressed=None, devicepersistency=None, editbootconfig=None, editbootinstall=None, filesystem=None, flags=None, format=None, formatoptions=None, fsmountoptions=None, fscreateoptions=None, squashfscompression=None, gcelicense=None, hybridpersistent=None, hybridpersistent_filesystem=None, gpt_hybrid_mbr=None, force_mbr=None, initrd_system=None, image=None, metadata_path=None, installboot=None, install_continue_on_timeout=None, installprovidefailsafe=None, installiso=None, installstick=None, installpxe=None, mediacheck=None, kernelcmdline=None, luks=None, luks_version=None, luksOS=None, luks_randomize=None, luks_pbkdf=None, mdraid=None, overlayroot=None, overlayroot_write_partition=None, overlayroot_readonly_partsize=None, verity_blocks=None, embed_verity_metadata=None, standalone_integrity=None, embed_integrity_metadata=None, integrity_legacy_hmac=None, integrity_metadata_key_description=None, integrity_keyfile=None, primary=None, ramonly=None, rootfs_label=None, spare_part=None, spare_part_mountpoint=None, spare_part_fs=None, spare_part_fs_attributes=None, spare_part_is_last=None, target_blocksize=None, target_removable=None, selinux_policy=None, vga=None, vhdfixedtag=None, volid=None, wwid_wait_timeout=None, derived_from=None, delta_root=None, ensure_empty_tmpdirs=None, xen_server=None, publisher=None, disk_start_sector=None, root_clone=None, boot_clone=None, bundle_format=None, bootloader=None, containerconfig=None, machine=None, oemconfig=None, size=None, systemdisk=None, partitions=None, vagrantconfig=None, installmedia=None, luksformat=None):
def __init__(self, boot=None, bootfilesystem=None, firmware=None, bootkernel=None, bootpartition=None, bootpartsize=None, efipartsize=None, efifatimagesize=None, eficsm=None, efiparttable=None, dosparttable_extended_layout=None, bootprofile=None, btrfs_quota_groups=None, btrfs_root_is_snapshot=None, btrfs_root_is_subvolume=None, btrfs_set_default_volume=None, btrfs_root_is_readonly_snapshot=None, compressed=None, devicepersistency=None, editbootconfig=None, editbootinstall=None, filesystem=None, flags=None, format=None, formatoptions=None, fsmountoptions=None, fscreateoptions=None, squashfscompression=None, gcelicense=None, hybridpersistent=None, hybridpersistent_filesystem=None, gpt_hybrid_mbr=None, force_mbr=None, initrd_system=None, image=None, metadata_path=None, installboot=None, install_continue_on_timeout=None, installprovidefailsafe=None, installiso=None, installstick=None, installpxe=None, mediacheck=None, kernelcmdline=None, luks=None, luks_version=None, luksOS=None, luks_randomize=None, luks_pbkdf=None, mdraid=None, overlayroot=None, overlayroot_write_partition=None, overlayroot_readonly_partsize=None, verity_blocks=None, embed_verity_metadata=None, standalone_integrity=None, embed_integrity_metadata=None, integrity_legacy_hmac=None, integrity_metadata_key_description=None, integrity_keyfile=None, primary=None, ramonly=None, rootfs_label=None, spare_part=None, spare_part_mountpoint=None, spare_part_fs=None, spare_part_fs_attributes=None, spare_part_is_last=None, target_blocksize=None, target_removable=None, selinux_policy=None, vga=None, vhdfixedtag=None, volid=None, wwid_wait_timeout=None, derived_from=None, delta_root=None, ensure_empty_tmpdirs=None, xen_server=None, publisher=None, disk_start_sector=None, root_clone=None, boot_clone=None, bundle_format=None, bootloader=None, containerconfig=None, machine=None, oemconfig=None, size=None, systemdisk=None, partitions=None, vagrantconfig=None, installmedia=None, luksformat=None):
self.original_tagname_ = None
self.boot = _cast(None, boot)
self.bootfilesystem = _cast(None, bootfilesystem)
Expand All @@ -3077,6 +3077,7 @@ def __init__(self, boot=None, bootfilesystem=None, firmware=None, bootkernel=Non
self.bootpartsize = _cast(int, bootpartsize)
self.efipartsize = _cast(int, efipartsize)
self.efifatimagesize = _cast(int, efifatimagesize)
self.eficsm = _cast(bool, eficsm)
self.efiparttable = _cast(None, efiparttable)
self.dosparttable_extended_layout = _cast(bool, dosparttable_extended_layout)
self.bootprofile = _cast(None, bootprofile)
Expand Down Expand Up @@ -3269,6 +3270,8 @@ def get_efipartsize(self): return self.efipartsize
def set_efipartsize(self, efipartsize): self.efipartsize = efipartsize
def get_efifatimagesize(self): return self.efifatimagesize
def set_efifatimagesize(self, efifatimagesize): self.efifatimagesize = efifatimagesize
def get_eficsm(self): return self.eficsm
def set_eficsm(self, eficsm): self.eficsm = eficsm
def get_efiparttable(self): return self.efiparttable
def set_efiparttable(self, efiparttable): self.efiparttable = efiparttable
def get_dosparttable_extended_layout(self): return self.dosparttable_extended_layout
Expand Down Expand Up @@ -3523,6 +3526,9 @@ def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='
if self.efifatimagesize is not None and 'efifatimagesize' not in already_processed:
already_processed.add('efifatimagesize')
outfile.write(' efifatimagesize="%s"' % self.gds_format_integer(self.efifatimagesize, input_name='efifatimagesize'))
if self.eficsm is not None and 'eficsm' not in already_processed:
already_processed.add('eficsm')
outfile.write(' eficsm="%s"' % self.gds_format_boolean(self.eficsm, input_name='eficsm'))
if self.efiparttable is not None and 'efiparttable' not in already_processed:
already_processed.add('efiparttable')
outfile.write(' efiparttable=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.efiparttable), input_name='efiparttable')), ))
Expand Down Expand Up @@ -3835,6 +3841,15 @@ def buildAttributes(self, node, attrs, already_processed):
raise_parse_error(node, 'Bad integer attribute: %s' % exp)
if self.efifatimagesize < 0:
raise_parse_error(node, 'Invalid NonNegativeInteger')
value = find_attr_value_('eficsm', node)
if value is not None and 'eficsm' not in already_processed:
already_processed.add('eficsm')
if value in ('true', '1'):
self.eficsm = True
elif value in ('false', '0'):
self.eficsm = False
else:
raise_parse_error(node, 'Bad boolean attribute')
value = find_attr_value_('efiparttable', node)
if value is not None and 'efiparttable' not in already_processed:
already_processed.add('efiparttable')
Expand Down
8 changes: 4 additions & 4 deletions test/unit/bootloader/config/grub2_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def setup(self, mock_theme, mock_firmware):
return_value=None
)
self.firmware.efi_mode = Mock(
return_value=None
return_value=''
)
mock_firmware.return_value = self.firmware

Expand Down Expand Up @@ -1381,7 +1381,7 @@ def test_setup_disk_boot_images_xen_guest(
Defaults.set_platform_name('x86_64')
mock_get_boot_path.return_value = '/boot'
self.firmware.efi_mode = Mock(
return_value=None
return_value=''
)
self.bootloader.xen_guest = True
self.os_exists['root_dir/boot/grub2/fonts/unicode.pf2'] = False
Expand Down Expand Up @@ -1417,7 +1417,7 @@ def test_setup_disk_boot_images_ppc(
mock_get_boot_path.return_value = '/boot'
self.bootloader.arch = 'ppc64le'
self.firmware.efi_mode = Mock(
return_value=None
return_value=''
)
self.bootloader.xen_guest = False
self.os_exists['root_dir/boot/grub2/fonts/unicode.pf2'] = False
Expand Down Expand Up @@ -1448,7 +1448,7 @@ def test_setup_disk_boot_images_s390(
mock_get_boot_path.return_value = '/boot'
self.bootloader.arch = 's390x'
self.firmware.efi_mode = Mock(
return_value=None
return_value=''
)
self.bootloader.xen_guest = False
self.os_exists['root_dir/boot/grub2/fonts/unicode.pf2'] = False
Expand Down
11 changes: 11 additions & 0 deletions test/unit/bootloader/install/grub2_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ def test_install_required_ppc_opal(self):
)
assert self.bootloader.install_required() is False

def test_install_required_efi_no_csm(self):
self.bootloader.arch = 'x86_64'
self.bootloader.firmware = mock.Mock()
self.bootloader.firmware.efi_mode = mock.Mock(
return_value='efi'
)
self.bootloader.firmware.legacy_bios_mode = mock.Mock(
return_value=False
)
assert self.bootloader.install_required() is False

def test_install_required_arm64(self):
self.bootloader.arch = 'arm64'
assert self.bootloader.install_required() is False
Expand Down
Loading

0 comments on commit 1453d93

Please sign in to comment.