From fe0a2cdb7cd86b1b6bc10a8cfe94427569a64bde Mon Sep 17 00:00:00 2001 From: Steffen Winterfeldt Date: Thu, 20 Aug 2026 16:44:12 +0200 Subject: [PATCH 1/7] support s390x iso boot config --- kiwi/bootloader/config/__init__.py | 10 ++-- kiwi/bootloader/config/iso_s390x.py | 72 +++++++++++++++++++++++++++++ kiwi/schema/kiwi.rnc | 2 +- kiwi/schema/kiwi.rng | 1 + 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 kiwi/bootloader/config/iso_s390x.py diff --git a/kiwi/bootloader/config/__init__.py b/kiwi/bootloader/config/__init__.py index db94efd8259..e0611953285 100644 --- a/kiwi/bootloader/config/__init__.py +++ b/kiwi/bootloader/config/__init__.py @@ -27,6 +27,7 @@ from kiwi.bootloader.config.systemd_boot import BootLoaderSystemdBoot from kiwi.bootloader.config.custom import BootLoaderConfigCustom from kiwi.bootloader.config.zipl import BootLoaderZipl + from kiwi.bootloader.config.iso_s390x import BootLoaderIsoS390x @overload @@ -63,16 +64,16 @@ def create_boot_loader_config( @overload def create_boot_loader_config( - *, name: str, xml_state: object, root_dir: str, + *, name: Literal["iso_s390x"], xml_state: object, root_dir: str, boot_dir: str = None, custom_args: Dict = None -) -> "Union[BootLoaderConfigGrub2, BootLoaderSystemdBoot, BootLoaderZipl]": +) -> "BootLoaderIsoS390x": ... # pragma: nocover def create_boot_loader_config( *, name: str, xml_state: object, root_dir: str, boot_dir: str = None, custom_args: Dict = None -) -> "Union[BootLoaderConfigGrub2, BootLoaderSystemdBoot, BootLoaderZipl, BootLoaderConfigCustom]": +) -> "Union[BootLoaderConfigGrub2, BootLoaderSystemdBoot, BootLoaderZipl, BootLoaderConfigCustom, BootLoaderIsoS390x]": if name in ("grub2", "grub2_s390x_emu"): from kiwi.bootloader.config.grub2 import BootLoaderConfigGrub2 @@ -83,6 +84,9 @@ def create_boot_loader_config( if name == "zipl": from kiwi.bootloader.config.zipl import BootLoaderZipl return BootLoaderZipl(xml_state, root_dir, boot_dir, custom_args) + if name == "iso_s390x": + from kiwi.bootloader.config.iso_s390x import BootLoaderIsoS390x + return BootLoaderIsoS390x(xml_state, root_dir, boot_dir, custom_args) if name == "custom": from kiwi.bootloader.config.custom import BootLoaderConfigCustom return BootLoaderConfigCustom(xml_state, root_dir, boot_dir, custom_args) diff --git a/kiwi/bootloader/config/iso_s390x.py b/kiwi/bootloader/config/iso_s390x.py new file mode 100644 index 00000000000..4a0c3897cd0 --- /dev/null +++ b/kiwi/bootloader/config/iso_s390x.py @@ -0,0 +1,72 @@ +# Copyright (c) 2026 SUSE Software Solutions Germany GmbH. All rights reserved. +# +# This file is part of kiwi. +# +# kiwi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# kiwi 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 kiwi. If not, see +# +import os +import glob +import logging +from typing import Dict + +# project +from kiwi.system.identifier import SystemIdentifier +from kiwi.bootloader.config.base import BootLoaderConfigBase + +import kiwi.defaults as defaults + +log = logging.getLogger('kiwi') + +class BootLoaderIsoS390x(BootLoaderConfigBase): + """ + **s390x iso bootloader configuration.** + """ + def setup_disk_boot_images( + self, boot_uuid, efi_uuid=None, lookup_path=None + ) -> None: + log.info('XXX iso_s390x: setup_disk_boot_images') + + def setup_disk_image_config( + self, boot_uuid: str = '', root_uuid: str = '', hypervisor: str = '', + kernel: str = '', initrd: str = '', boot_options: Dict[str, str] = {} + ) -> None: + log.info('XXX iso_s390x: setup_disk_image_config') + + def setup_install_boot_images( + self, mbrid: SystemIdentifier, lookup_path: str = '' + ) -> None: + log.info('XXX iso_s390x: setup_install_boot_images -- Creating s390x install boot images from template') + + def setup_install_image_config( + self, mbrid: SystemIdentifier, hypervisor: str = '', + kernel: str = '', initrd: str = '' + ) -> None: + log.info('XXX iso_s390x: setup_install_image_config -- Creating s390x install image config from template') + + def setup_live_boot_images( + self, mbrid: SystemIdentifier, lookup_path: str = '' + ) -> None: + log.info('XXX iso_s390x: setup_live_boot_images -- Creating s390x live boot images from template') + + def setup_live_image_config( + self, mbrid: SystemIdentifier, hypervisor: str = '', + kernel: str = '', initrd: str = '' + ) -> None: + log.info('XXX iso_s390x: setup_live_image_config -- Creating s390x live image config file from template') + + def setup_sysconfig_bootloader(self) -> None: + log.info('XXX iso_s390x: setup_sysconfig_bootloader') + + def write(self) -> None: + log.info('XXX iso_s390x: write') diff --git a/kiwi/schema/kiwi.rnc b/kiwi/schema/kiwi.rnc index 3d228b5d690..9b18a0b0ba8 100644 --- a/kiwi/schema/kiwi.rnc +++ b/kiwi/schema/kiwi.rnc @@ -3030,7 +3030,7 @@ div { ## user which can be done by using the editbootinstall and ## editbootconfig custom scripts attribute name { - "grub2" | "grub2_s390x_emu" | "systemd_boot" | "custom" | "zipl" + "grub2" | "grub2_s390x_emu" | "systemd_boot" | "custom" | "zipl" | "iso_s390x" } >> sch:pattern [ id = "loader_name" is-a = "bootloader_image_type" sch:param [ name = "attr" value = "name" ] diff --git a/kiwi/schema/kiwi.rng b/kiwi/schema/kiwi.rng index 8591bc14738..fa6d2284d94 100644 --- a/kiwi/schema/kiwi.rng +++ b/kiwi/schema/kiwi.rng @@ -4568,6 +4568,7 @@ editbootconfig custom scripts systemd_boot custom zipl + iso_s390x From e22a565bb99e61ef53f031c78a2138b104082f00 Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Thu, 20 Aug 2026 15:00:08 +0000 Subject: [PATCH 2/7] Add unit test for BootLoaderIsoS390x Add a test case to cover the instantiation of the newly added iso_s390x bootloader configuration class. --- test/unit/bootloader/config/init_test.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/unit/bootloader/config/init_test.py b/test/unit/bootloader/config/init_test.py index c3bbf3f5009..488b9985818 100644 --- a/test/unit/bootloader/config/init_test.py +++ b/test/unit/bootloader/config/init_test.py @@ -58,3 +58,13 @@ def test_bootloader_config_custom(self, mock_custom): mock_custom.assert_called_once_with( xml_state, 'root_dir', None, None ) + + @patch('kiwi.bootloader.config.iso_s390x.BootLoaderIsoS390x') + def test_bootloader_config_iso_s390x(self, mock_iso_s390x): + xml_state = Mock() + create_boot_loader_config( + name='iso_s390x', xml_state=xml_state, root_dir='root_dir' + ) + mock_iso_s390x.assert_called_once_with( + xml_state, 'root_dir', None, None + ) From 2b507248aaa2b33d8ee0c7a5d8b9e2e9fadc3380 Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Thu, 20 Aug 2026 18:39:28 +0000 Subject: [PATCH 3/7] Do not override iso_s390x bootloader to grub2 in live builder Allow the newly added 'iso_s390x' bootloader configuration to be preserved during live image building, rather than overwriting it with 'grub2'. --- kiwi/builder/live.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kiwi/builder/live.py b/kiwi/builder/live.py index 4cb4916685a..5d00772fabc 100644 --- a/kiwi/builder/live.py +++ b/kiwi/builder/live.py @@ -73,7 +73,7 @@ def __init__( root_dir: str, custom_args: Dict = None ): self.bootloader = xml_state.get_build_type_bootloader_name() - if self.bootloader != 'systemd_boot': + if self.bootloader not in ('systemd_boot', 'iso_s390x'): self.bootloader = 'grub2' self.root_filesystem_verity_blocks = \ xml_state.build_type.get_verity_blocks() From 8d9490ea74d4a99890dda8515d48a4e0415a31ec Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Mon, 31 Aug 2026 15:50:57 +0000 Subject: [PATCH 4/7] iso_s390x: add bootloader config implementation --- kiwi/bootloader/config/iso_s390x.py | 202 +++++++++++++++++++++++++--- 1 file changed, 187 insertions(+), 15 deletions(-) diff --git a/kiwi/bootloader/config/iso_s390x.py b/kiwi/bootloader/config/iso_s390x.py index 4a0c3897cd0..16c912b4c34 100644 --- a/kiwi/bootloader/config/iso_s390x.py +++ b/kiwi/bootloader/config/iso_s390x.py @@ -18,55 +18,227 @@ import os import glob import logging +import struct +import shutil from typing import Dict +from textwrap import dedent # project from kiwi.system.identifier import SystemIdentifier from kiwi.bootloader.config.base import BootLoaderConfigBase - -import kiwi.defaults as defaults +from kiwi.path import Path log = logging.getLogger('kiwi') + class BootLoaderIsoS390x(BootLoaderConfigBase): """ **s390x iso bootloader configuration.** """ + def post_init(self, custom_args: Dict = {}) -> None: + self.custom_args = custom_args + self.cmdline = self.get_boot_cmdline(None) or '' + self.config_files: Dict[str, str] = {} + self.lookup_path = '' + + def write_meta_data( + self, root_device: str = None, write_device: str = None, boot_options: str = '' + ) -> None: + self.cmdline = ' '.join( + [self.get_boot_cmdline(root_device, write_device), boot_options] + ).strip() + def setup_disk_boot_images( - self, boot_uuid, efi_uuid=None, lookup_path=None + self, boot_uuid: str, efi_uuid: str = None, lookup_path: str = None ) -> None: - log.info('XXX iso_s390x: setup_disk_boot_images') + pass def setup_disk_image_config( self, boot_uuid: str = '', root_uuid: str = '', hypervisor: str = '', kernel: str = '', initrd: str = '', boot_options: Dict[str, str] = {} ) -> None: - log.info('XXX iso_s390x: setup_disk_image_config') + pass def setup_install_boot_images( self, mbrid: SystemIdentifier, lookup_path: str = '' ) -> None: - log.info('XXX iso_s390x: setup_install_boot_images -- Creating s390x install boot images from template') + log.info('Creating s390x install boot images') + self.lookup_path = lookup_path def setup_install_image_config( - self, mbrid: SystemIdentifier, hypervisor: str = '', - kernel: str = '', initrd: str = '' + self, mbrid: SystemIdentifier, hypervisor: str = 'xen.gz', + kernel: str = 'linux', initrd: str = 'initrd' ) -> None: - log.info('XXX iso_s390x: setup_install_image_config -- Creating s390x install image config from template') + log.info('Creating s390x install image config from template') + self._prepare_config_files() def setup_live_boot_images( self, mbrid: SystemIdentifier, lookup_path: str = '' ) -> None: - log.info('XXX iso_s390x: setup_live_boot_images -- Creating s390x live boot images from template') + log.info('Creating s390x live boot images') + self.lookup_path = lookup_path def setup_live_image_config( - self, mbrid: SystemIdentifier, hypervisor: str = '', - kernel: str = '', initrd: str = '' + self, mbrid: SystemIdentifier, hypervisor: str = 'xen.gz', + kernel: str = 'linux', initrd: str = 'initrd' ) -> None: - log.info('XXX iso_s390x: setup_live_image_config -- Creating s390x live image config file from template') + log.info('Creating s390x live image config file from template') + self._prepare_config_files() def setup_sysconfig_bootloader(self) -> None: - log.info('XXX iso_s390x: setup_sysconfig_bootloader') + pass + + def _prepare_config_files(self) -> None: + relative_loader_path = self.get_boot_path('iso').lstrip('/') + + initrd_ofs_ofs = 0x0001040c + initrd_siz_ofs = 0x00010414 + initrd_ofs = 0x01000000 + parmfile_ofs = 0x00010480 + + # ensure it's never empty, add trailing space + parmfile_content = self.cmdline.strip() + " " + parmfile_hmc_content = f"{self.cmdline} console=ttyS1".strip() + " " + + suse_ins_content = dedent(f"""\ + * SUSE Linux for IBM z Systems Installation System + linux 0x00000000 + initrd.off 0x{initrd_ofs_ofs:08x} + initrd.siz 0x{initrd_siz_ofs:08x} + initrd 0x{initrd_ofs:08x} + parmfile 0x{parmfile_ofs:08x} + """) + + media_suse_ins_content = dedent(f"""\ + * SUSE Linux for IBM z Systems Installation System + {relative_loader_path}/linux 0x00000000 + {relative_loader_path}/initrd.off 0x{initrd_ofs_ofs:08x} + {relative_loader_path}/initrd.siz 0x{initrd_siz_ofs:08x} + {relative_loader_path}/initrd 0x{initrd_ofs:08x} + {relative_loader_path}/parmfile 0x{parmfile_ofs:08x} + """) + + media_susehmc_ins_content = dedent(f"""\ + * SUSE Linux for IBM z Systems Installation System via HMC + {relative_loader_path}/linux 0x00000000 + {relative_loader_path}/initrd.off 0x{initrd_ofs_ofs:08x} + {relative_loader_path}/initrd.siz 0x{initrd_siz_ofs:08x} + {relative_loader_path}/initrd 0x{initrd_ofs:08x} + {relative_loader_path}/parmfile.hmc 0x{parmfile_ofs:08x} + """) + + # Note: The following file has spaces at the end of the lines to make them exactly 80 chars wide. + sles_exec_content = dedent("""\ + /* REXX LOAD EXEC FOR SUSE LINUX S/390 VM GUESTS */ + /* LOADS SUSE LINUX S/390 FILES INTO READER */ + SAY '' + SAY 'LOADING SLES FILES INTO READER...' + 'CP CLOSE RDR' + 'PURGE RDR ALL' + 'SPOOL PUNCH * RDR' + 'PUNCH SLES LINUX A (NOH' + 'PUNCH SLES PARMFILE A (NOH' + 'PUNCH SLES INITRD A (NOH' + 'IPL 00C' + """) + + self.config_files[os.path.join(relative_loader_path, 'parmfile')] = parmfile_content + self.config_files[os.path.join(relative_loader_path, 'parmfile.hmc')] = parmfile_hmc_content + self.config_files[os.path.join(relative_loader_path, 'suse.ins')] = suse_ins_content + self.config_files['suse.ins'] = media_suse_ins_content + self.config_files['susehmc.ins'] = media_susehmc_ins_content + self.config_files[os.path.join(relative_loader_path, 'sles.exec')] = sles_exec_content + + def _create_s390x_boot_images(self, loader_path: str) -> None: + initrd_ofs_ofs = 0x0001040c + initrd_siz_ofs = 0x00010414 + initrd_ofs = 0x01000000 + parmfile_ofs = 0x00010480 + + kernel_dest = os.path.join(loader_path, 'linux') + initrd_dest = os.path.join(loader_path, 'initrd') + + if os.path.exists(kernel_dest) and os.path.exists(initrd_dest): + initrd_size = os.path.getsize(initrd_dest) + + initrd_off_data = struct.pack('>I', initrd_ofs) + with open(os.path.join(loader_path, 'initrd.off'), 'wb') as f: + f.write(initrd_off_data) + + initrd_siz_data = struct.pack('>I', initrd_size) + with open(os.path.join(loader_path, 'initrd.siz'), 'wb') as f: + f.write(initrd_siz_data) + + with open(kernel_dest, 'rb') as f: + cd_ikr_data = bytearray(f.read()) + + def write_at_offset(data: bytearray, offset: int, payload: bytes) -> None: + if len(data) < offset + len(payload): + data.extend(b'\x00' * (offset + len(payload) - len(data))) + data[offset:offset+len(payload)] = payload + + write_at_offset(cd_ikr_data, initrd_ofs_ofs, initrd_off_data) + write_at_offset(cd_ikr_data, initrd_siz_ofs, initrd_siz_data) + write_at_offset(cd_ikr_data, parmfile_ofs, b'\x00' * 512) + + parmfile_content = self.cmdline + write_at_offset(cd_ikr_data, parmfile_ofs, parmfile_content.encode('utf-8')) + + with open(initrd_dest, 'rb') as f: + initrd_bytes = f.read() + write_at_offset(cd_ikr_data, initrd_ofs, initrd_bytes) + + write_at_offset(cd_ikr_data, 4, b'\x80\x01\x00\x00') + + padding_size = -initrd_size & 0xfff + if padding_size > 0: + cd_ikr_data.extend(b'\x00' * padding_size) + + with open(os.path.join(loader_path, 'cd.ikr'), 'wb') as f: + f.write(cd_ikr_data) + log.info("Created s390x boot image: cd.ikr") + else: + log.info( + "Skipping cd.ikr creation because kernel and initrd are not yet present " + "in the boot loader directory." + ) + + with open(os.path.join(loader_path, 'zipl.map'), 'wb') as f: + f.write(b'\x00' * (4096 * 4)) + log.info("Created zipl.map") + + def setup_s390x_boot_images(self, kernel_file: str, initrd_file: str) -> None: + """ + Setup s390x boot images (linux, initrd, cd.ikr, zipl.map) + from the finalized kernel and initrd files. + """ + log.info('Setting up s390x boot images') + loader_path = os.path.join( + self.boot_dir, self.get_boot_path('iso').lstrip('/') + ) + Path.create(loader_path) + + kernel_dest = os.path.join(loader_path, 'linux') + initrd_dest = os.path.join(loader_path, 'initrd') + + shutil.copy(kernel_file, kernel_dest) + shutil.copy(initrd_file, initrd_dest) + log.info(f"Copied kernel to {kernel_dest} and initrd to {initrd_dest}") + + self._create_s390x_boot_images(loader_path) def write(self) -> None: - log.info('XXX iso_s390x: write') + log.info('Writing s390x bootloader configuration') + loader_path = os.path.join( + self.boot_dir, self.get_boot_path('iso').lstrip('/') + ) + Path.create(loader_path) + + for filename, content in self.config_files.items(): + filepath = os.path.join(self.boot_dir, filename.lstrip('/')) + Path.create(os.path.dirname(filepath)) + with open(filepath, 'w') as f: + f.write(content) + log.info(f"Created configuration file {filepath}") + + self._create_s390x_boot_images(loader_path) From edf1d2c88cc16e11d61f816f9f6b4f98e63cc92e Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Mon, 31 Aug 2026 15:50:59 +0000 Subject: [PATCH 5/7] builder: integrate iso_s390x bootloader --- kiwi/builder/install.py | 3 ++- kiwi/builder/live.py | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/kiwi/builder/install.py b/kiwi/builder/install.py index d15bb01a73b..c2a0b5f5d7c 100644 --- a/kiwi/builder/install.py +++ b/kiwi/builder/install.py @@ -163,7 +163,8 @@ def create_install_iso(self) -> None: 'efi_partition_table': self.firmware.get_partition_table_type(), 'gpt_hybrid_mbr': self.firmware.gpt_hybrid_mbr, 'ofw_mode': self.firmware.ofw_mode(), - 'legacy_bios_mode': self.firmware.legacy_bios_mode() + 'legacy_bios_mode': self.firmware.legacy_bios_mode(), + 'bootloader': self.bootloader } } diff --git a/kiwi/builder/live.py b/kiwi/builder/live.py index 5d00772fabc..504e6f58c4b 100644 --- a/kiwi/builder/live.py +++ b/kiwi/builder/live.py @@ -32,6 +32,7 @@ from kiwi.bootloader.config import create_boot_loader_config from kiwi.bootloader.config.grub2 import BootLoaderConfigGrub2 from kiwi.bootloader.config.systemd_boot import BootLoaderSystemdBoot +from kiwi.bootloader.config.iso_s390x import BootLoaderIsoS390x from kiwi.bootloader.config.base import BootLoaderConfigBase from kiwi.filesystem import FileSystem from kiwi.filesystem.isofs import FileSystemIsoFs @@ -135,7 +136,8 @@ def __init__( 'efi_mode': self.firmware.efi_mode(), 'efi_partition_table': self.firmware.get_partition_table_type(), 'gpt_hybrid_mbr': self.firmware.gpt_hybrid_mbr, - 'legacy_bios_mode': self.firmware.legacy_bios_mode() + 'legacy_bios_mode': self.firmware.legacy_bios_mode(), + 'bootloader': self.bootloader } } @@ -465,7 +467,9 @@ def create(self) -> Result: def create_live_iso_boot_images( self, - bootloader_config: Union[BootLoaderConfigGrub2, BootLoaderSystemdBoot], + bootloader_config: Union[ + BootLoaderConfigGrub2, BootLoaderSystemdBoot, BootLoaderIsoS390x + ], modules: List[str] = [] ) -> None: live_dracut_modules = Defaults.get_live_dracut_modules_from_flag( @@ -482,6 +486,15 @@ def create_live_iso_boot_images( self.boot_image.create_initrd(self.mbrid) # Clean up leftover dracut config file (which can break installs) os.unlink(self.root_dir + '/etc/dracut.conf.d/02-livecd.conf') + if self.bootloader == 'iso_s390x': + from kiwi.system.kernel import Kernel + kernel = Kernel(self.boot_image.boot_root_directory) + kernel_info = kernel.get_kernel() + if kernel_info and self.boot_image.initrd_filename: + bootloader_config.setup_s390x_boot_images( + kernel_file=kernel_info.filename, + initrd_file=self.boot_image.initrd_filename + ) if self.bootloader == 'systemd_boot': # make sure the initrd name follows the dracut # naming conventions From 5e9b8eaad80c6c5784e7940547ae02a69d83639b Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Mon, 31 Aug 2026 15:51:01 +0000 Subject: [PATCH 6/7] xorriso: add iso_s390x boot support --- kiwi/bootloader/config/iso_s390x.py | 3 +-- kiwi/iso_tools/xorriso.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/kiwi/bootloader/config/iso_s390x.py b/kiwi/bootloader/config/iso_s390x.py index 16c912b4c34..0d69191c76c 100644 --- a/kiwi/bootloader/config/iso_s390x.py +++ b/kiwi/bootloader/config/iso_s390x.py @@ -16,7 +16,6 @@ # along with kiwi. If not, see # import os -import glob import logging import struct import shutil @@ -175,7 +174,7 @@ def _create_s390x_boot_images(self, loader_path: str) -> None: def write_at_offset(data: bytearray, offset: int, payload: bytes) -> None: if len(data) < offset + len(payload): data.extend(b'\x00' * (offset + len(payload) - len(data))) - data[offset:offset+len(payload)] = payload + data[offset:offset + len(payload)] = payload write_at_offset(cd_ikr_data, initrd_ofs_ofs, initrd_off_data) write_at_offset(cd_ikr_data, initrd_siz_ofs, initrd_siz_data) diff --git a/kiwi/iso_tools/xorriso.py b/kiwi/iso_tools/xorriso.py index f532584aae6..24e8be3d169 100644 --- a/kiwi/iso_tools/xorriso.py +++ b/kiwi/iso_tools/xorriso.py @@ -74,7 +74,9 @@ def init_iso_creation_parameters( :param list custom_args: custom ISO meta data """ legacy_bios_mode = True + bootloader = None if custom_args: + bootloader = custom_args.get('bootloader') application_id = \ custom_args.get('application_id') or custom_args.get('mbr_id') if application_id: @@ -109,6 +111,15 @@ def init_iso_creation_parameters( '-compliance', 'no_emul_toc' ] + if bootloader == 'iso_s390x': + loader_file = '/'.join([self.boot_path, 'loader', 'cd.ikr']) + self.iso_loaders += [ + '-boot_image', 'any', f'bin_path={loader_file}', + '-boot_image', 'any', 'boot_info_table=off', + '-boot_image', 'any', 'load_size=512' + ] + return + if Defaults.is_x86_arch(self.arch) and legacy_bios_mode: mbr_file = os.sep.join( [ From 70f988ca2df21c30744420430a7445ba7e86588a Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Mon, 7 Sep 2026 18:20:40 +0200 Subject: [PATCH 7/7] default to iso_s390x for iso creation on s390x --- kiwi/builder/install.py | 4 ++-- kiwi/builder/live.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kiwi/builder/install.py b/kiwi/builder/install.py index c2a0b5f5d7c..0fa806f382d 100644 --- a/kiwi/builder/install.py +++ b/kiwi/builder/install.py @@ -71,8 +71,8 @@ def __init__( self.runtime_config = RuntimeConfig() self.arch = Defaults.get_platform_name() self.bootloader = xml_state.get_build_type_bootloader_name() - if self.bootloader != 'systemd_boot': - self.bootloader = 'grub2' + if self.bootloader not in ('custom', 'iso_s390x', 'systemd_boot'): + self.bootloader = 'grub2' if self.arch != 's390x' else 'iso_s390x' self.root_dir = root_dir self.target_dir = target_dir self.xml_state = xml_state diff --git a/kiwi/builder/live.py b/kiwi/builder/live.py index 504e6f58c4b..d81a61b6800 100644 --- a/kiwi/builder/live.py +++ b/kiwi/builder/live.py @@ -73,12 +73,12 @@ def __init__( self, xml_state: XMLState, target_dir: str, root_dir: str, custom_args: Dict = None ): + self.arch = Defaults.get_platform_name() self.bootloader = xml_state.get_build_type_bootloader_name() - if self.bootloader not in ('systemd_boot', 'iso_s390x'): - self.bootloader = 'grub2' + if self.bootloader not in ('custom', 'iso_s390x', 'systemd_boot'): + self.bootloader = 'grub2' if self.arch != 's390x' else 'iso_s390x' self.root_filesystem_verity_blocks = \ xml_state.build_type.get_verity_blocks() - self.arch = Defaults.get_platform_name() self.root_dir = root_dir self.target_dir = target_dir self.xml_state = xml_state @@ -486,7 +486,7 @@ def create_live_iso_boot_images( self.boot_image.create_initrd(self.mbrid) # Clean up leftover dracut config file (which can break installs) os.unlink(self.root_dir + '/etc/dracut.conf.d/02-livecd.conf') - if self.bootloader == 'iso_s390x': + if self.arch == 's390x': from kiwi.system.kernel import Kernel kernel = Kernel(self.boot_image.boot_root_directory) kernel_info = kernel.get_kernel()