Skip to content

Commit

Permalink
Support more configuration options with Limine
Browse files Browse the repository at this point in the history
  • Loading branch information
48cf committed Nov 18, 2023
1 parent 3177997 commit a49a992
Showing 1 changed file with 50 additions and 75 deletions.
125 changes: 50 additions & 75 deletions archinstall/lib/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -976,14 +976,12 @@ def _add_limine_bootloader(
root_partition: disk.PartitionModification
):
self.pacman.strap('limine')

info(f"Limine boot partition: {boot_partition.dev_path}")

root_uuid = root_partition.uuid

def create_pacman_hook(contents: str):
HOOK_DIR = "/etc/pacman.d/hooks"
SysCommand(f"/usr/bin/arch-chroot {self.target} mkdir -p {HOOK_DIR}")
SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"echo '{contents}' > {HOOK_DIR}/liminedeploy.hook\"")
limine_path = self.target / 'usr' / 'share' / 'limine'
hook_command = None

if SysInfo.has_uefi():
if not efi_partition:
Expand All @@ -992,65 +990,35 @@ def create_pacman_hook(contents: str):
info(f"Limine EFI partition: {efi_partition.dev_path}")

try:
cmd = f'/usr/bin/arch-chroot' \
f' {self.target}' \
f' mkdir' \
f' -p' \
f' {efi_partition.mountpoint}/EFI/BOOT'

SysCommand(cmd, peek_output=True)

cmd = f'/usr/bin/arch-chroot' \
f' {self.target}' \
f' cp' \
f' /usr/share/limine/BOOTX64.EFI' \
f' {efi_partition.mountpoint}/EFI/BOOT/'
efi_dir_path = self.target / efi_partition.mountpoint.relative_to('/') / 'EFI' / 'BOOT'
efi_dir_path.mkdir(parents=True, exist_ok=True)

SysCommand(cmd, peek_output=True)
except SysCallError as err:
raise DiskError(f"Failed to install Limine BOOTX64.EFI on {boot_partition.dev_path}: {err}")

# Create the EFI limine pacman hook.
create_pacman_hook(f"""
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = limine
for file in ('BOOTIA32.EFI', 'BOOTX64.EFI'):
shutil.copy(limine_path / file, efi_dir_path)
except Exception as err:
raise DiskError(f'Failed to install Limine in {self.target}{efi_partition.mountpoint}: {err}')

[Action]
Description = Deploying Limine after upgrade...
When = PostTransaction
Exec = /usr/bin/cp /usr/share/limine/BOOTX64.EFI {efi_partition.mountpoint}/EFI/BOOT/
""")
hook_command = f'/usr/bin/cp /usr/share/limine/BOOTIA32.EFI {efi_partition.mountpoint}/EFI/BOOT/' \
f' && /usr/bin/cp /usr/share/limine/BOOTX64.EFI {efi_partition.mountpoint}/EFI/BOOT/'
else:
parent_dev_path = disk.device_handler.get_parent_device_path(boot_partition.safe_dev_path)

if unique_path := disk.device_handler.get_unique_path_for_device(parent_dev_path):
parent_dev_path = unique_path

try:
# The `limine-bios.sys` file contains stage 3 code.
cmd = f'/usr/bin/arch-chroot' \
f' {self.target}' \
f' cp' \
f' /usr/share/limine/limine-bios.sys' \
f' /boot/limine-bios.sys'

SysCommand(cmd, peek_output=True)
shutil.copy(limine_path / 'limine-bios.sys', self.target / 'boot')

# `limine bios-install` deploys the stage 1 and 2 to the disk.
cmd = f'/usr/bin/arch-chroot' \
f' {self.target}' \
f' limine' \
f' bios-install' \
f' {parent_dev_path}'
SysCommand(f'/usr/bin/arch-chroot {self.target} limine bios-install {parent_dev_path}', peek_output=True)
except Exception as err:
raise DiskError(f'Failed to install Limine on {parent_dev_path}: {err}')

SysCommand(cmd, peek_output=True)
except SysCallError as err:
raise DiskError(f"Failed to install Limine on {boot_partition.dev_path}: {err}")
hook_command = f'/usr/bin/limine bios-install {parent_dev_path}' \
f' && /usr/bin/cp /usr/share/limine/limine-bios.sys /boot/'

create_pacman_hook(f"""
[Trigger]
hook_contents = f'''[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Expand All @@ -1059,31 +1027,38 @@ def create_pacman_hook(contents: str):
[Action]
Description = Deploying Limine after upgrade...
When = PostTransaction
Exec = /bin/sh -c \\"/usr/bin/limine bios-install {parent_dev_path} && /usr/bin/cp /usr/share/limine/limine-bios.sys /boot/\\"
""")
Exec = /bin/sh -c "{hook_command}"
'''

# Limine does not ship with a default configuration file. We are going to
# create a basic one that is similar to the one GRUB generates.
try:
config = f"""
TIMEOUT=5
:Arch Linux
PROTOCOL=linux
KERNEL_PATH=boot:///vmlinuz-linux
CMDLINE=root=UUID={root_uuid} rw rootfstype={root_partition.safe_fs_type.value} loglevel=3
MODULE_PATH=boot:///initramfs-linux.img
:Arch Linux (fallback)
PROTOCOL=linux
KERNEL_PATH=boot:///vmlinuz-linux
CMDLINE=root=UUID={root_uuid} rw rootfstype={root_partition.safe_fs_type.value} loglevel=3
MODULE_PATH=boot:///initramfs-linux-fallback.img
"""

SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"echo '{config}' > /boot/limine.cfg\"")
except SysCallError as err:
raise DiskError(f"Could not configure Limine: {err}")
hooks_dir = self.target / 'etc' / 'pacman.d' / 'hooks'
hooks_dir.mkdir(parents=True, exist_ok=True)

hook_path = hooks_dir / '99-limine.hook'
hook_path.write_text(hook_contents)

microcode = []

if ucode := self._get_microcode():
microcode = [f'MODULE_PATH=boot:///{ucode}']

kernel_params = ' '.join(self._get_kernel_params(root_partition))
config_contents = 'TIMEOUT=5\n'

for kernel in self.kernels:
for variant in ('', '-fallback'):
entry = [
f'PROTOCOL=linux',
f'KERNEL_PATH=boot:///vmlinuz-{kernel}',
*microcode,
f'MODULE_PATH=boot:///initramfs-{kernel}{variant}.img',
f'CMDLINE={kernel_params}',
]

config_contents += f'\n:Arch Linux ({kernel}{variant})\n'
config_contents += '\n'.join([f' {it}' for it in entry]) + '\n'

config_path = self.target / 'boot' / 'limine.cfg'
config_path.write_text(config_contents)

self.helper_flags['bootloader'] = "limine"

Expand Down

0 comments on commit a49a992

Please sign in to comment.