@@ -972,70 +972,54 @@ def _add_grub_bootloader(
972
972
def _add_limine_bootloader (
973
973
self ,
974
974
boot_partition : disk .PartitionModification ,
975
+ efi_partition : Optional [disk .PartitionModification ],
975
976
root_partition : disk .PartitionModification
976
977
):
977
978
self .pacman .strap ('limine' )
978
- info (f"Limine boot partition: { boot_partition .dev_path } " )
979
979
980
- root_uuid = root_partition . uuid
980
+ info ( f"Limine boot partition: { boot_partition . dev_path } " )
981
981
982
- def create_pacman_hook (contents : str ):
983
- HOOK_DIR = "/etc/pacman.d/hooks"
984
- SysCommand (f"/usr/bin/arch-chroot { self .target } mkdir -p { HOOK_DIR } " )
985
- SysCommand (f"/usr/bin/arch-chroot { self .target } sh -c \" echo '{ contents } ' > { HOOK_DIR } /liminedeploy.hook\" " )
982
+ limine_path = self .target / 'usr' / 'share' / 'limine'
983
+ hook_command = None
986
984
987
985
if SysInfo .has_uefi ():
986
+ if not efi_partition :
987
+ raise ValueError ('Could not detect efi partition' )
988
+ elif not efi_partition .mountpoint :
989
+ raise ValueError ('EFI partition is not mounted' )
990
+
991
+ info (f"Limine EFI partition: { efi_partition .dev_path } " )
992
+
988
993
try :
989
- # The `limine.sys` file, contains stage 3 code.
990
- cmd = f'/usr/bin/arch-chroot' \
991
- f' { self .target } ' \
992
- f' cp' \
993
- f' /usr/share/limine/BOOTX64.EFI' \
994
- f' /boot/EFI/BOOT/'
995
-
996
- SysCommand (cmd , peek_output = True )
997
- except SysCallError as err :
998
- raise DiskError (f"Failed to install Limine BOOTX64.EFI on { boot_partition .dev_path } : { err } " )
994
+ efi_dir_path = self .target / efi_partition .mountpoint .relative_to ('/' ) / 'EFI' / 'BOOT'
995
+ efi_dir_path .mkdir (parents = True , exist_ok = True )
999
996
1000
- # Create the EFI limine pacman hook.
1001
- create_pacman_hook ("""
1002
- [Trigger]
1003
- Operation = Install
1004
- Operation = Upgrade
1005
- Type = Package
1006
- Target = limine
997
+ for file in ('BOOTIA32.EFI' , 'BOOTX64.EFI' ):
998
+ shutil .copy (limine_path / file , efi_dir_path )
999
+ except Exception as err :
1000
+ raise DiskError (f'Failed to install Limine in { self .target } { efi_partition .mountpoint } : { err } ' )
1007
1001
1008
- [Action]
1009
- Description = Deploying Limine after upgrade...
1010
- When = PostTransaction
1011
- Exec = /usr/bin/cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/
1012
- """ )
1002
+ hook_command = f'/usr/bin/cp /usr/share/limine/BOOTIA32.EFI { efi_partition .mountpoint } /EFI/BOOT/' \
1003
+ f' && /usr/bin/cp /usr/share/limine/BOOTX64.EFI { efi_partition .mountpoint } /EFI/BOOT/'
1013
1004
else :
1014
1005
parent_dev_path = disk .device_handler .get_parent_device_path (boot_partition .safe_dev_path )
1015
1006
1016
- try :
1017
- # The `limine.sys` file, contains stage 3 code.
1018
- cmd = f'/usr/bin/arch-chroot' \
1019
- f' { self .target } ' \
1020
- f' cp' \
1021
- f' /usr/share/limine/limine-bios.sys' \
1022
- f' /boot/limine-bios.sys'
1007
+ if unique_path := disk .device_handler .get_unique_path_for_device (parent_dev_path ):
1008
+ parent_dev_path = unique_path
1023
1009
1024
- SysCommand (cmd , peek_output = True )
1010
+ try :
1011
+ # The `limine-bios.sys` file contains stage 3 code.
1012
+ shutil .copy (limine_path / 'limine-bios.sys' , self .target / 'boot' )
1025
1013
1026
1014
# `limine bios-install` deploys the stage 1 and 2 to the disk.
1027
- cmd = f'/usr/bin/arch-chroot' \
1028
- f' { self .target } ' \
1029
- f' limine' \
1030
- f' bios-install' \
1031
- f' { parent_dev_path } '
1015
+ SysCommand (f'/usr/bin/arch-chroot { self .target } limine bios-install { parent_dev_path } ' , peek_output = True )
1016
+ except Exception as err :
1017
+ raise DiskError (f'Failed to install Limine on { parent_dev_path } : { err } ' )
1032
1018
1033
- SysCommand (cmd , peek_output = True )
1034
- except SysCallError as err :
1035
- raise DiskError (f"Failed to install Limine on { boot_partition .dev_path } : { err } " )
1019
+ hook_command = f'/usr/bin/limine bios-install { parent_dev_path } ' \
1020
+ f' && /usr/bin/cp /usr/share/limine/limine-bios.sys /boot/'
1036
1021
1037
- create_pacman_hook (f"""
1038
- [Trigger]
1022
+ hook_contents = f'''[Trigger]
1039
1023
Operation = Install
1040
1024
Operation = Upgrade
1041
1025
Type = Package
@@ -1044,33 +1028,38 @@ def create_pacman_hook(contents: str):
1044
1028
[Action]
1045
1029
Description = Deploying Limine after upgrade...
1046
1030
When = PostTransaction
1047
- # XXX: Kernel name descriptors cannot be used since they are not persistent and
1048
- # can change after each boot.
1049
- Exec = /bin/sh -c \\ "/usr/bin/limine bios-install /dev/disk/by-uuid/{ root_uuid } && /usr/bin/cp /usr/share/limine/limine-bios.sys /boot/\\ "
1050
- """ )
1031
+ Exec = /bin/sh -c "{ hook_command } "
1032
+ '''
1051
1033
1052
- # Limine does not ship with a default configuration file. We are going to
1053
- # create a basic one that is similar to the one GRUB generates.
1054
- try :
1055
- config = f"""
1056
- TIMEOUT=5
1057
-
1058
- :Arch Linux
1059
- PROTOCOL=linux
1060
- KERNEL_PATH=boot:///vmlinuz-linux
1061
- CMDLINE=root=UUID={ root_uuid } rw rootfstype={ root_partition .safe_fs_type .value } loglevel=3
1062
- MODULE_PATH=boot:///initramfs-linux.img
1063
-
1064
- :Arch Linux (fallback)
1065
- PROTOCOL=linux
1066
- KERNEL_PATH=boot:///vmlinuz-linux
1067
- CMDLINE=root=UUID={ root_uuid } rw rootfstype={ root_partition .safe_fs_type .value } loglevel=3
1068
- MODULE_PATH=boot:///initramfs-linux-fallback.img
1069
- """
1070
-
1071
- SysCommand (f"/usr/bin/arch-chroot { self .target } sh -c \" echo '{ config } ' > /boot/limine.cfg\" " )
1072
- except SysCallError as err :
1073
- raise DiskError (f"Could not configure Limine: { err } " )
1034
+ hooks_dir = self .target / 'etc' / 'pacman.d' / 'hooks'
1035
+ hooks_dir .mkdir (parents = True , exist_ok = True )
1036
+
1037
+ hook_path = hooks_dir / '99-limine.hook'
1038
+ hook_path .write_text (hook_contents )
1039
+
1040
+ microcode = []
1041
+
1042
+ if ucode := self ._get_microcode ():
1043
+ microcode = [f'MODULE_PATH=boot:///{ ucode } ' ]
1044
+
1045
+ kernel_params = ' ' .join (self ._get_kernel_params (root_partition ))
1046
+ config_contents = 'TIMEOUT=5\n '
1047
+
1048
+ for kernel in self .kernels :
1049
+ for variant in ('' , '-fallback' ):
1050
+ entry = [
1051
+ f'PROTOCOL=linux' ,
1052
+ f'KERNEL_PATH=boot:///vmlinuz-{ kernel } ' ,
1053
+ * microcode ,
1054
+ f'MODULE_PATH=boot:///initramfs-{ kernel } { variant } .img' ,
1055
+ f'CMDLINE={ kernel_params } ' ,
1056
+ ]
1057
+
1058
+ config_contents += f'\n :Arch Linux ({ kernel } { variant } )\n '
1059
+ config_contents += '\n ' .join ([f' { it } ' for it in entry ]) + '\n '
1060
+
1061
+ config_path = self .target / 'boot' / 'limine.cfg'
1062
+ config_path .write_text (config_contents )
1074
1063
1075
1064
self .helper_flags ['bootloader' ] = "limine"
1076
1065
@@ -1227,7 +1216,7 @@ def add_bootloader(self, bootloader: Bootloader, uki_enabled: bool = False):
1227
1216
case Bootloader .Efistub :
1228
1217
self ._add_efistub_bootloader (boot_partition , root_partition , uki_enabled )
1229
1218
case Bootloader .Limine :
1230
- self ._add_limine_bootloader (boot_partition , root_partition )
1219
+ self ._add_limine_bootloader (boot_partition , efi_partition , root_partition )
1231
1220
1232
1221
def add_additional_packages (self , packages : Union [str , List [str ]]) -> bool :
1233
1222
return self .pacman .strap (packages )
0 commit comments