Skip to content

Commit da19fcd

Browse files
committed
Extend validate_bootloader_layout with UEFI-dependent checks
Add is_uefi parameter and three new validations: Systemd-boot, Efistub and rEFInd require UEFI; Efistub additionally requires a FAT boot partition. Move the rEFInd UEFI-only check out of GlobalMenu so guided.py and Installer silent-install paths get the same coverage.
1 parent de43019 commit da19fcd

4 files changed

Lines changed: 34 additions & 10 deletions

File tree

archinstall/lib/bootloader/utils.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
class BootloaderValidationFailureKind(Enum):
1010
LimineNonFatBoot = auto()
1111
LimineLayout = auto()
12+
BootloaderRequiresUefi = auto()
13+
EfistubNonFatBoot = auto()
1214

1315

1416
@dataclass(frozen=True)
@@ -17,9 +19,13 @@ class BootloaderValidationFailure:
1719
description: str
1820

1921

22+
_UEFI_ONLY_BOOTLOADERS = (Bootloader.Systemd, Bootloader.Efistub, Bootloader.Refind)
23+
24+
2025
def validate_bootloader_layout(
2126
bootloader_config: BootloaderConfiguration | None,
2227
disk_config: DiskLayoutConfiguration | None,
28+
is_uefi: bool,
2329
) -> BootloaderValidationFailure | None:
2430
"""Validate bootloader configuration against disk layout.
2531
@@ -29,12 +35,32 @@ def validate_bootloader_layout(
2935
if not (bootloader_config and disk_config):
3036
return None
3137

32-
if bootloader_config.bootloader == Bootloader.Limine:
33-
boot_part = next(
34-
(p for m in disk_config.device_modifications if (p := m.get_boot_partition())),
35-
None,
38+
bootloader = bootloader_config.bootloader
39+
40+
if bootloader == Bootloader.NO_BOOTLOADER:
41+
return None
42+
43+
if bootloader in _UEFI_ONLY_BOOTLOADERS and not is_uefi:
44+
return BootloaderValidationFailure(
45+
kind=BootloaderValidationFailureKind.BootloaderRequiresUefi,
46+
description=f'{bootloader.value} requires a UEFI system.',
3647
)
3748

49+
boot_part = next(
50+
(p for m in disk_config.device_modifications if (p := m.get_boot_partition())),
51+
None,
52+
)
53+
54+
if bootloader == Bootloader.Efistub:
55+
# The UEFI firmware reads the kernel directly from the boot partition,
56+
# which must be FAT.
57+
if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()):
58+
return BootloaderValidationFailure(
59+
kind=BootloaderValidationFailureKind.EfistubNonFatBoot,
60+
description='Efistub does not support booting with a non-FAT boot partition.',
61+
)
62+
63+
if bootloader == Bootloader.Limine:
3864
# Limine reads its config and kernels from the boot partition, which
3965
# must be FAT.
4066
if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()):

archinstall/lib/global_menu.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,6 @@ def _validate_bootloader(self) -> str | None:
461461
if not bootloader_config or bootloader_config.bootloader == Bootloader.NO_BOOTLOADER:
462462
return None
463463

464-
bootloader = bootloader_config.bootloader
465-
466464
if disk_config := self._item_group.find_by_key('disk_config').value:
467465
for layout in disk_config.device_modifications:
468466
if root_partition := layout.get_root_partition():
@@ -490,10 +488,7 @@ def _validate_bootloader(self) -> str | None:
490488
if efi_partition.fs_type is None or not efi_partition.fs_type.is_fat():
491489
return 'ESP must be formatted as a FAT filesystem'
492490

493-
if bootloader == Bootloader.Refind and not self._uefi:
494-
return 'rEFInd can only be used on UEFI systems'
495-
496-
if failure := validate_bootloader_layout(bootloader_config, disk_config):
491+
if failure := validate_bootloader_layout(bootloader_config, disk_config, self._uefi):
497492
return failure.description
498493

499494
return None

archinstall/lib/installer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,7 @@ def _add_limine_bootloader(
14721472
if failure := validate_bootloader_layout(
14731473
BootloaderConfiguration(bootloader=Bootloader.Limine, uki=uki_enabled),
14741474
self._disk_config,
1475+
SysInfo.has_uefi(),
14751476
):
14761477
raise DiskError(failure.description)
14771478

archinstall/scripts/guided.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from archinstall.lib.disk.utils import disk_layouts
1212
from archinstall.lib.general.general_menu import PostInstallationAction, select_post_installation
1313
from archinstall.lib.global_menu import GlobalMenu
14+
from archinstall.lib.hardware import SysInfo
1415
from archinstall.lib.installer import Installer, accessibility_tools_in_use, run_custom_user_commands
1516
from archinstall.lib.menu.util import delayed_warning
1617
from archinstall.lib.mirror.mirror_handler import MirrorListHandler
@@ -217,6 +218,7 @@ def main(arch_config_handler: ArchConfigHandler | None = None) -> None:
217218
if failure := validate_bootloader_layout(
218219
arch_config_handler.config.bootloader_config,
219220
arch_config_handler.config.disk_config,
221+
SysInfo.has_uefi(),
220222
):
221223
error(failure.description)
222224
return

0 commit comments

Comments
 (0)