summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/utils/bios.py53
-rw-r--r--src/utils/boot.py18
2 files changed, 70 insertions, 1 deletions
diff --git a/src/utils/bios.py b/src/utils/bios.py
new file mode 100644
index 0000000..e064ca0
--- /dev/null
+++ b/src/utils/bios.py
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2023 Soleta Networks <info@soleta.eu>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+import logging
+import os
+
+
+def get_grub_boot_params(mountpoint, device):
+ grub_conf = f'{mountpoint}/etc/default/grub'
+ res = []
+
+ with open(grub_conf, 'r') as f:
+ for line in f:
+ if line.find('=') == -1:
+ continue
+ key, value = line.split('=', 1)
+ if key == 'GRUB_CMDLINE_LINUX' or key == 'GRUB_CMDLINE_LINUE_DEFAULT':
+ value = value.replace('\n', '')
+ value = value.strip('"')
+ res.append(value)
+ res.append(f'root={device}')
+ return " ".join(res)
+
+def get_vmlinuz_path(mountpoint):
+ linuz_dir = os.path.join(mountpoint, 'boot')
+ target_file = None
+
+ for file in sorted(os.listdir(linuz_dir)):
+ if file.startswith('vmlinuz-'):
+ target_file = file
+
+ if not target_file:
+ raise FileNotFoundError('vmlinuz not found in {initrd_dir}')
+
+ return os.path.join(linuz_dir, target_file)
+
+def get_initrd_path(mountpoint):
+ initrd_dir = os.path.join(mountpoint, 'boot')
+ target_file = None
+
+ for file in sorted(os.listdir(initrd_dir)):
+ if file.startswith('initrd.img-') or file.startswith('initramfs-') and file.endswith('.img'):
+ target_file = file
+
+ if not target_file:
+ raise FileNotFoundError('initrd not found in {initrd_dir}')
+
+ return os.path.join(initrd_dir, target_file)
diff --git a/src/utils/boot.py b/src/utils/boot.py
index 07a29ba..724fc06 100644
--- a/src/utils/boot.py
+++ b/src/utils/boot.py
@@ -14,6 +14,7 @@ import subprocess
from src.utils.probe import OSFamily, get_os_family, get_linux_distro_id, os_probe
from src.utils.disk import get_partition_device, get_efi_partition
+from src.utils.bios import *
from src.utils.uefi import *
from src.utils.fs import *
@@ -27,7 +28,22 @@ def _boot_bios_linux(disk, part, mountpoint):
if not get_linux_distro_id(mountpoint) == 'ubuntu':
raise NotImplementedError(f'{os_probe(mountpoint)} detected, only Ubuntu is supported for legacy BIOS boot')
- _boot_bios_legacy(disk, part, mountpoint)
+ kernel_path = get_vmlinuz_path(mountpoint)
+ initrd_path = get_initrd_path(mountpoint)
+
+ device = get_partition_device(disk, part)
+ grub_boot_params = get_grub_boot_params(mountpoint, device)
+
+ kexec_cmd = f'kexec -l {kernel_path} --append="{grub_boot_params}" --initrd="{initrd_path}"'
+ kexec_reboot_cmd = 'kexec -e'
+
+ logging.info(f'Booting with: {kexec_cmd}')
+ try:
+ subprocess.run(shlex.split(kexec_cmd), check=True, text=True)
+ subprocess.run(shlex.split(kexec_reboot_cmd), check=True, text=True)
+ except subprocess.CalledProcessError as e:
+ logging.error(f'Error processing kexec: {e}')
+ raise e
def _boot_bios_windows(disk, part, mountpoint):
logging.info(f'Booting Windows system')