Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 41 additions & 34 deletions boot-qemu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# pylint: disable=invalid-name

import argparse
import contextlib
import os
from pathlib import Path
import platform
Expand All @@ -14,9 +15,23 @@

base_folder = Path(__file__).resolve().parent
supported_architectures = [
"arm", "arm32_v5", "arm32_v6", "arm32_v7", "arm64", "arm64be", "m68k",
"mips", "mipsel", "ppc32", "ppc32_mac", "ppc64", "ppc64le", "riscv",
"s390", "x86", "x86_64"
"arm",
"arm32_v5",
"arm32_v6",
"arm32_v7",
"arm64",
"arm64be",
"m68k",
"mips",
"mipsel",
"ppc32",
"ppc32_mac",
"ppc64",
"ppc64le",
"riscv",
"s390",
"x86",
"x86_64",
]


Expand Down Expand Up @@ -59,29 +74,29 @@ def parse_arguments():
"--interactive",
"--shell",
action="store_true",
help= # noqa: E251
"Instead of immediately shutting down the machine upon successful boot, pass 'rdinit=/bin/sh' on the kernel command line to allow interacting with the machine via a shell."
help=
"Instead of immediately shutting down the machine upon successful boot, pass 'rdinit=/bin/sh' on the kernel command line to allow interacting with the machine via a shell.",
)
parser.add_argument(
"-k",
"--kernel-location",
required=True,
type=str,
help= # noqa: E251
"Path to kernel image or kernel build folder to search for image in. Can be an absolute or relative path."
help=
"Path to kernel image or kernel build folder to search for image in. Can be an absolute or relative path.",
)
parser.add_argument(
"--no-kvm",
action="store_true",
help= # noqa: E251
"Do not use KVM for acceleration even when supported (only recommended for debugging)."
help=
"Do not use KVM for acceleration even when supported (only recommended for debugging).",
)
parser.add_argument(
"-s",
"--smp",
type=int,
help= # noqa: E251
"Number of processors for virtual machine. By default, only machines spawned with KVM will use multiple vCPUS."
help=
"Number of processors for virtual machine. By default, only machines spawned with KVM will use multiple vCPUS.",
)
parser.add_argument(
"-t",
Expand Down Expand Up @@ -194,7 +209,7 @@ def get_smp_value(args):
# CONFIG_NR_CPUS then get the actual value if possible.
config_nr_cpus = 8
if config_file:
with open(config_file, encoding='utf-8') as file:
with config_file.open(encoding='utf-8') as file:
for line in file:
if "CONFIG_NR_CPUS=" in line:
config_nr_cpus = int(line.split("=", 1)[1])
Expand Down Expand Up @@ -380,19 +395,19 @@ def get_efi_args(guest_arch):
Path("edk2/aarch64/QEMU_EFI.fd"), # Arch Linux (current)
Path("edk2-armvirt/aarch64/QEMU_EFI.fd"), # Arch Linux (old)
Path("qemu-efi-aarch64/QEMU_EFI.fd"), # Debian and Ubuntu
None # Terminator
None, # Terminator
],
"x86_64": [
Path("edk2/x64/OVMF_CODE.fd"), # Arch Linux (current), Fedora
Path("edk2-ovmf/x64/OVMF_CODE.fd"), # Arch Linux (old)
Path("OVMF/OVMF_CODE.fd"), # Debian and Ubuntu
None # Terminator
]
None, # Terminator
],
} # yapf: disable

if guest_arch not in efi_img_locations:
utils.yellow(
f"EFI boot requested for unsupported architecture ('{guest_arch}'), ignoring..."
f"EFI boot requested for unsupported architecture ('{guest_arch}'), ignoring...",
)
return []

Expand Down Expand Up @@ -427,7 +442,7 @@ def get_efi_args(guest_arch):
efi_vars_locations = [
Path("edk2/x64/OVMF_VARS.fd"), # Arch Linux and Fedora
Path("OVMF/OVMF_VARS.fd"), # Debian and Ubuntu
None # Terminator
None, # Terminator
]
for efi_vars_location in efi_vars_locations:
if efi_vars_location is None:
Expand All @@ -446,7 +461,7 @@ def get_efi_args(guest_arch):
"-drive", f"if=pflash,format=raw,file={efi_img_qemu},readonly=on",
"-drive", f"if=pflash,format=raw,file={efi_vars_qemu}",
"-object", "rng-random,filename=/dev/urandom,id=rng0",
"-device", "virtio-rng-pci"
"-device", "virtio-rng-pci",
] # yapf: disable


Expand Down Expand Up @@ -619,10 +634,7 @@ def get_qemu_args(cfg):
elif arch == "x86_64":
qemu_args += ["-cpu", "Nehalem"]

if arch == "x86":
qemu = "qemu-system-i386"
else:
qemu = "qemu-system-x86_64"
qemu = "qemu-system-i386" if arch == "x86" else "qemu-system-x86_64"

# Make sure QEMU is available in PATH, otherwise there is little point to
# continuing.
Expand All @@ -636,18 +648,15 @@ def get_qemu_args(cfg):

# '-dtb'
if dtb:
# If we are in a boot folder, look for them in the dts folder in it
if "boot" in str(kernel):
dtb_dir = "dts"
# If we are in a boot folder, look for them in the dts folder in it.
# Otherwise, assume there is a dtbs folder in the same folder as the
# kernel image (tuxmake)
else:
dtb_dir = "dtbs"
dtb_dir = "dts" if "boot" in str(kernel) else "dtbs"

dtb = kernel.parent.joinpath(dtb_dir, dtb)
if not dtb.exists():
utils.die(
f"'{dtb.stem}' is required for booting but it could not be found at '{dtb}'"
f"'{dtb.stem}' is required for booting but it could not be found at '{dtb}'",
)

qemu_args += ["-dtb", dtb]
Expand Down Expand Up @@ -686,7 +695,7 @@ def get_qemu_args(cfg):
# with subprocess.Popen()
qemu = shutil.which(qemu)

cfg["qemu_cmd"] = [qemu] + qemu_args
cfg["qemu_cmd"] = [qemu, *qemu_args]

return cfg

Expand Down Expand Up @@ -777,11 +786,9 @@ def launch_qemu(cfg):
gdb_cmd += [kernel_location.joinpath("vmlinux")]
gdb_cmd += ["-ex", "target remote :1234"]

with subprocess.Popen(gdb_cmd) as gdb_process:
try:
gdb_process.wait()
except KeyboardInterrupt:
pass
with subprocess.Popen(gdb_cmd) as gdb_process, \
contextlib.suppress(KeyboardInterrupt):
gdb_process.wait()

utils.red("Killing QEMU...")
qemu_process.kill()
Expand Down
8 changes: 4 additions & 4 deletions boot-uml.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ def parse_arguments():
"-i",
"--interactive",
action="store_true",
help= # noqa: E251
"Instead of immediately shutting down upon successful boot, pass 'init=/bin/sh' to the UML executable to allow interacting with UML via a shell."
help=
"Instead of immediately shutting down upon successful boot, pass 'init=/bin/sh' to the UML executable to allow interacting with UML via a shell.",
)
parser.add_argument(
"-k",
"--kernel-location",
required=True,
type=str,
help= # noqa: E251
"Path to UML executable ('linux') or kernel build folder to search for executable in. Can be an absolute or relative path."
help=
"Path to UML executable ('linux') or kernel build folder to search for executable in. Can be an absolute or relative path.",
)

return parser.parse_args()
Expand Down
28 changes: 28 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
select = [
'A', # flake8-builtins
'ARG', # flake8-unused-arguments
'B', # flake8-bugbear
'C4', # flake8-comprehensions
'COM', # flake8-commas
'E', # pycodestyle
'F', # pyflakes
'PIE', # flake8-pie
'PL', # pylint
'PTH', # flake8-use-pathlib
'RET', # flake8-return
'RUF', # ruff
'S', # flake8-bandit
'SIM', # flake8-simplify
'SLF', # flake8-self
'UP', # pyupgrade
'W', # pycodestyle
]
ignore = [
'E501', # line-too-long
'PLR0911', # too-many-return-statments
'PLR0912', # too-many-branches
'PLR0913', # too-many-arguments
'PLR0915', # too-many-statements
'PLR2004', # magic-value-comparison
]
target-version = 'py38'
10 changes: 6 additions & 4 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ def check_cmd(cmd):
cmd (str): External command name or path.
"""
if not shutil.which(cmd):
die(f"The external command '{cmd}' is needed but it could not be found in PATH, please install it!"
)
die(
f"The external command '{cmd}' is needed but it could not be found in PATH, please install it!",
)


def die(string):
Expand Down Expand Up @@ -57,8 +58,9 @@ def get_full_kernel_path(kernel_location, image, arch=None):
# Otherwise, it is in the architecture's boot directory
else:
if not arch:
die(f"Kernel image ('{image}') is in the arch/ directory but 'arch' was not provided!"
)
die(
f"Kernel image ('{image}') is in the arch/ directory but 'arch' was not provided!",
)
kernel = kernel_location.joinpath("arch", arch, "boot", image)

if not kernel.exists():
Expand Down