From e39165ba2e40091db35ac15783e7943666309cd7 Mon Sep 17 00:00:00 2001 From: Julia Vassiliki Date: Thu, 16 Jul 2026 11:26:34 +1000 Subject: [PATCH 1/2] build_sdk: fix config overriding Previously duplicate config values would cause multiple `-DKernelOption` values being passed on the command line, and then it was up to CMake shenanigans for how this behaves, especially if they were incompatible options. Instead, merge the dictionaries and so later-options are more important. In order of priority, we have: - Common kernel options for all arches - The kernel arch option - Any common arch-specific kernel options - Board-specific kernel options Signed-off-by: Julia Vassiliki --- build_sdk.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/build_sdk.py b/build_sdk.py index 3019bd526..92b6d341b 100644 --- a/build_sdk.py +++ b/build_sdk.py @@ -39,7 +39,7 @@ TRIPLE_X86_64 = "x86_64-linux-gnu" KERNEL_CONFIG_TYPE = Union[bool, str] -KERNEL_OPTIONS = Dict[str, Union[bool, str]] +KERNEL_OPTIONS = Dict[str, Union[bool, str, int, Path]] DEFAULT_X86_NUM_CPUS = 16 @@ -115,8 +115,8 @@ def to_str(self) -> str: else: raise Exception(f"Unsupported arch {self}") - def as_kernel_arch_config(self) -> tuple[str, str]: - return ("KernelSel4Arch", self.to_str()) + def as_kernel_arch_config(self) -> dict[str, str]: + return {"KernelSel4Arch": self.to_str()} KERNEL_OPTIONS_ARCH = Dict[KernelArch, KERNEL_OPTIONS] @@ -607,7 +607,7 @@ def build_sel4( board: BoardInfo, config: ConfigInfo, llvm: bool -): +) -> None: """Build seL4""" build_dir = build_dir / board.name / config.name / "sel4" build_dir.mkdir(exist_ok=True, parents=True) @@ -620,22 +620,24 @@ def build_sel4( print(f"Building sel4: {sel4_dir=} {sdk_dir=} {build_dir=} {board=} {config=}") - config_args = [ - *board.kernel_options.items(), - *config.kernel_options.items(), - board.arch.as_kernel_arch_config(), - ] + config_args = { + **config.kernel_options, + **board.arch.as_kernel_arch_config(), + } if config.kernel_options_arch is not None: if board.arch in config.kernel_options_arch: - config_args += config.kernel_options_arch[board.arch].items() + config_args |= config.kernel_options_arch[board.arch] + + config_args |= board.kernel_options + config_strs = [] - for arg, val in sorted(config_args): + for arg, val in config_args.items(): if isinstance(val, bool): str_val = "ON" if val else "OFF" elif isinstance(val, KernelPath): str_val = f"{sel4_dir.absolute()}/{val.path}" elif isinstance(val, Path): - str_val = Path(__file__).parent / val + str_val = (Path(__file__).parent / val).as_posix() else: str_val = str(val) s = f"-D{arg}={str_val}" From 04623758c71202f29d10548d103b72033b6888d9 Mon Sep 17 00:00:00 2001 From: Julia Vassiliki Date: Thu, 16 Jul 2026 11:58:58 +1000 Subject: [PATCH 2/2] build_sdk: cleanup config overriding order Instead of having defaults for each-board, the default is a global variabled merged into config_args when we build seL4 that takes priorities into account. Signed-off-by: Julia Vassiliki --- build_sdk.py | 94 +++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/build_sdk.py b/build_sdk.py index 92b6d341b..7ec4e3178 100644 --- a/build_sdk.py +++ b/build_sdk.py @@ -43,7 +43,7 @@ DEFAULT_X86_NUM_CPUS = 16 -DEFAULT_KERNEL_OPTIONS = { +DEFAULT_KERNEL_OPTIONS: KERNEL_OPTIONS = { "KernelIsMCS": True, "KernelRootCNodeSizeBits": "17", # Thread local storage is painful and annoying to configure. @@ -55,20 +55,18 @@ "LibSel4UseThreadLocals": False, } -DEFAULT_KERNEL_OPTIONS_AARCH64 = { +DEFAULT_KERNEL_OPTIONS_AARCH64: KERNEL_OPTIONS = { "KernelArmExportPCNTUser": True, "KernelArmHypervisorSupport": True, "KernelArmVtimerUpdateVOffset": False, "KernelAllowSMCCalls": True, -} | DEFAULT_KERNEL_OPTIONS - -DEFAULT_KERNEL_OPTIONS_RISCV64 = DEFAULT_KERNEL_OPTIONS +} -DEFAULT_KERNEL_OPTIONS_X86_64 = { +DEFAULT_KERNEL_OPTIONS_X86_64: KERNEL_OPTIONS = { "KernelPlatform": "pc99", "KernelX86MicroArch": "generic", "KernelIOMMU": True, -} | DEFAULT_KERNEL_OPTIONS +} class KernelArch(IntEnum): @@ -121,6 +119,12 @@ def as_kernel_arch_config(self) -> dict[str, str]: KERNEL_OPTIONS_ARCH = Dict[KernelArch, KERNEL_OPTIONS] +DEFAULT_KERNEL_OPTIONS_ARCH: KERNEL_OPTIONS_ARCH = { + KernelArch.AARCH64: DEFAULT_KERNEL_OPTIONS_AARCH64, + KernelArch.X86_64: DEFAULT_KERNEL_OPTIONS_X86_64, + KernelArch.RISCV64: {} +} + @dataclass class BoardInfo: @@ -160,7 +164,7 @@ class KernelPath: "KernelPlatform": "zynqmp", "KernelARMPlatform": "zcu102", "KernelCustomDTSOverlay": Path("custom_dts/overlay-zynqmp-kria-k26.dts"), - } | DEFAULT_KERNEL_OPTIONS_AARCH64, + }, ), BoardInfo( name="stm32mp2", @@ -171,7 +175,7 @@ class KernelPath: kernel_options={ "KernelPlatform": "stm32mp2", "KernelARMPlatform": "stm32mp257f-ev1", - } | DEFAULT_KERNEL_OPTIONS_AARCH64, + }, ), BoardInfo( name="tqma8xqp1gb", @@ -179,7 +183,7 @@ class KernelPath: gcc_cpu="cortex-a35", loader_link_address=0x90000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "tqma8xqp1gb", }, ), @@ -189,7 +193,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x40000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "zynqmp", "KernelARMPlatform": "zcu102", }, @@ -200,7 +204,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x50000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "maaxboard", }, ), @@ -210,7 +214,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x41000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "imx8mm-evk", }, ), @@ -220,7 +224,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x41000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "imx8mp-evk", }, ), @@ -230,7 +234,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x41000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "imx8mq-evk", }, ), @@ -240,7 +244,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x50000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "imx8mp-evk", "KernelCustomDTS": Path("custom_dts/iot-gate.dts"), "KernelCustomDTSOverlay": KernelPath(path="src/plat/imx8m-evk/overlay-imx8mp-evk.dts"), @@ -252,7 +256,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x20000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "odroidc2", }, ), @@ -262,7 +266,7 @@ class KernelPath: gcc_cpu="cortex-a55", loader_link_address=0x20000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "odroidc4", }, ), @@ -272,7 +276,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x40000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "zynqmp", "KernelARMPlatform": "ultra96v2", }, @@ -283,7 +287,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x70000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "qemu-arm-virt", "QEMU_MEMORY": "2048", # There is no peripheral timer, so we use the ARM @@ -297,7 +301,7 @@ class KernelPath: gcc_cpu="cortex-a53", loader_link_address=0x70000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "qemu-arm-virt", "KernelArmHypervisorSupport": False, "QEMU_MEMORY": "2048", @@ -312,7 +316,7 @@ class KernelPath: gcc_cpu=None, loader_link_address=0x90000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_RISCV64 | { + kernel_options={ "KernelPlatform": "qemu-riscv-virt", "QEMU_MEMORY": "2048", }, @@ -323,7 +327,7 @@ class KernelPath: gcc_cpu="cortex-a72", loader_link_address=0x10000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "bcm2711", "RPI4_MEMORY": 1024, }, @@ -334,7 +338,7 @@ class KernelPath: gcc_cpu="cortex-a72", loader_link_address=0x10000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "bcm2711", "RPI4_MEMORY": 2048, }, @@ -345,7 +349,7 @@ class KernelPath: gcc_cpu="cortex-a72", loader_link_address=0x10000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "bcm2711", "RPI4_MEMORY": 4096, }, @@ -356,7 +360,7 @@ class KernelPath: gcc_cpu="cortex-a72", loader_link_address=0x10000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "bcm2711", "RPI4_MEMORY": 8192, }, @@ -369,7 +373,7 @@ class KernelPath: # ROCKPRO64 has 4 Cortex-A53 cores and 2 Cortex-A72 cores, # we always run on the Cortex-A53s. smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "rockpro64", }, ), @@ -378,7 +382,7 @@ class KernelPath: arch=KernelArch.AARCH64, gcc_cpu="cortex-a55", loader_link_address=0x30000000, - kernel_options=DEFAULT_KERNEL_OPTIONS_AARCH64 | { + kernel_options={ "KernelPlatform": "rk3568", }, ), @@ -388,7 +392,7 @@ class KernelPath: gcc_cpu=None, loader_link_address=0x90000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_RISCV64 | { + kernel_options={ "KernelPlatform": "hifive-p550", }, ), @@ -398,7 +402,7 @@ class KernelPath: gcc_cpu=None, loader_link_address=0x60000000, smp_cores=4, - kernel_options=DEFAULT_KERNEL_OPTIONS_RISCV64 | { + kernel_options={ "KernelPlatform": "star64", }, ), @@ -407,7 +411,7 @@ class KernelPath: arch=KernelArch.RISCV64, gcc_cpu=None, loader_link_address=0x90000000, - kernel_options=DEFAULT_KERNEL_OPTIONS_RISCV64 | { + kernel_options={ "KernelPlatform": "ariane", }, ), @@ -416,7 +420,7 @@ class KernelPath: arch=KernelArch.RISCV64, gcc_cpu=None, loader_link_address=0x90000000, - kernel_options=DEFAULT_KERNEL_OPTIONS_RISCV64 | { + kernel_options={ "KernelPlatform": "cheshire", }, ), @@ -425,7 +429,7 @@ class KernelPath: arch=KernelArch.RISCV64, gcc_cpu=None, loader_link_address=0x90000000, - kernel_options=DEFAULT_KERNEL_OPTIONS_RISCV64 | { + kernel_options={ "KernelPlatform": "cheshire", }, ), @@ -435,7 +439,7 @@ class KernelPath: gcc_cpu="generic", loader_link_address=None, smp_cores=DEFAULT_X86_NUM_CPUS, - kernel_options=DEFAULT_KERNEL_OPTIONS_X86_64 | { + kernel_options={ "KernelSupportPCID": False, "KernelVTX": False, }, @@ -446,7 +450,7 @@ class KernelPath: gcc_cpu="generic", loader_link_address=None, smp_cores=DEFAULT_X86_NUM_CPUS, - kernel_options=DEFAULT_KERNEL_OPTIONS_X86_64 | { + kernel_options={ "KernelSupportPCID": False, "KernelVTX": True, "KernelX86_64VTX64BitGuests": True, @@ -620,15 +624,23 @@ def build_sel4( print(f"Building sel4: {sel4_dir=} {sdk_dir=} {build_dir=} {board=} {config=}") + # Config values are inserted in reverse-priority order, so that the most + # specific values take precedence. + # + # - Common kernel options for all arches + # - Config option to specify arch + # - Arch-specific kernel options + # - Any config (i.e. release/debug) specific kernel options + # - Any arch-specific config options (e.g. AArch64 debug) + # - Board-specific kernel options config_args = { - **config.kernel_options, + **DEFAULT_KERNEL_OPTIONS, **board.arch.as_kernel_arch_config(), + **DEFAULT_KERNEL_OPTIONS_ARCH[board.arch], + **config.kernel_options, + **config.kernel_options_arch.get(board.arch, {}), + **board.kernel_options, } - if config.kernel_options_arch is not None: - if board.arch in config.kernel_options_arch: - config_args |= config.kernel_options_arch[board.arch] - - config_args |= board.kernel_options config_strs = [] for arg, val in config_args.items():