├── VERSION
├── docs
├── assets
│ └── microkit_flow.pdf
└── style
│ └── logos
│ ├── seL4-key.pdf
│ ├── blacktriangle.pdf
│ └── seL4-Foundation-logo.pdf
├── .flake8
├── initialiser
├── src
│ └── main.rs
├── Cargo.toml
└── support
│ └── targets
│ ├── riscv64imac-sel4-minimal.json
│ ├── aarch64-sel4-minimal.json
│ └── x86_64-sel4-minimal.json
├── monitor
├── src
│ ├── x86_64
│ │ └── crt0.s
│ ├── aarch64
│ │ └── crt0.s
│ ├── util.h
│ ├── riscv
│ │ └── crt0.s
│ └── util.c
└── Makefile
├── libmicrokit
├── src
│ ├── x86_64
│ │ └── crt0.s
│ ├── aarch64
│ │ └── crt0.s
│ ├── riscv
│ │ └── crt0.s
│ ├── dbg.c
│ └── main.c
├── microkit.ld
└── Makefile
├── tool
└── microkit
│ ├── tests
│ └── sdf
│ │ ├── sys_no_protection_domains.system
│ │ ├── pd_missing_program_image.system
│ │ ├── pd_parent_has_id.system
│ │ ├── mr_missing_name.system
│ │ ├── vm_not_child.system
│ │ ├── mr_missing_size.system
│ │ ├── mr_malformed_size.system
│ │ ├── pd_invalid_cpu.system
│ │ ├── mr_unsupported_page_size.system
│ │ ├── pd_missing_path.system
│ │ ├── mr_size_not_multiple_of_page_size.system
│ │ ├── pd_missing_name.system
│ │ ├── sys_text_elements.system
│ │ ├── vm_missing_vcpu.system
│ │ ├── irq_arm_on_x86.system
│ │ ├── pd_invalid_attrs.system
│ │ ├── irq_id_less_than_0.system
│ │ ├── mr_addr_not_aligned_to_page_size.system
│ │ ├── irq_id_greater_than_max.system
│ │ ├── pd_small_stack_size.system
│ │ ├── pd_missing_id.system
│ │ ├── pd_program_image_invalid_attrs.system
│ │ ├── pd_budget_gt_period.system
│ │ ├── pd_missing_irq.system
│ │ ├── pd_unaligned_stack_size.system
│ │ ├── irq_ioapic_on_arm.system
│ │ ├── vm_missing_vcpu_id.system
│ │ ├── irq_msi_on_arm.system
│ │ ├── irq_invalid_trigger.system
│ │ ├── irq_ioapic_less_than_0.system
│ │ ├── irq_ioapic_pin_less_than_0.system
│ │ ├── vm_invalid_vcpu_id.system
│ │ ├── irq_ioapic_vector_less_than_0.system
│ │ ├── irq_msi_handle_less_than_0.system
│ │ ├── irq_msi_vector_less_than_0.system
│ │ ├── vm_invalid_vcpu_cpu.system
│ │ ├── irq_msi_pci_bus_less_than_0.system
│ │ ├── irq_msi_pci_dev_less_than_0.system
│ │ ├── irq_msi_pci_func_less_than_0.system
│ │ ├── pd_invalid_x86_io_port_size.system
│ │ ├── irq_ioapic_invalid_polarity.system
│ │ ├── irq_ioapic_invalid_trigger.system
│ │ ├── sys_duplicate_irq_id.system
│ │ ├── mr_invalid_attrs.system
│ │ ├── pd_write_only_mr.system
│ │ ├── pd_missing_region_paddr.system
│ │ ├── pd_missing_symbol.system
│ │ ├── sys_map_not_aligned.system
│ │ ├── pd_duplicate_program_image.system
│ │ ├── pd_overlapping_x86_io_ports_1.system
│ │ ├── pd_child_missing_id.system
│ │ ├── pd_missing_mr.system
│ │ ├── pd_missing_vaddr.system
│ │ ├── sys_duplicate_pd_name.system
│ │ ├── mr_overlapping_phys_addr.system
│ │ ├── sys_map_too_high.system
│ │ ├── sys_duplicate_mr_name.system
│ │ ├── ch_not_enough_ends.system
│ │ ├── pd_duplicate_setvar.system
│ │ ├── vm_missing_mr.system
│ │ ├── sys_duplicate_irq_number.system
│ │ ├── ch_missing_id.system
│ │ ├── ch_missing_pd.system
│ │ ├── ch_end_invalid_pp.system
│ │ ├── ch_end_invalid_notify.system
│ │ ├── ch_id_less_than_0.system
│ │ ├── ch_invalid_element.system
│ │ ├── ch_invalid_pd.system
│ │ ├── ch_id_greater_than_max.system
│ │ ├── ch_invalid_attrs.system
│ │ ├── pd_duplicate_child_id_vcpu.system
│ │ ├── pd_overlapping_maps.system
│ │ ├── ch_ppcall_priority.system
│ │ ├── ch_bidirectional_ppc.system
│ │ ├── pd_overlapping_x86_io_ports_2.system
│ │ ├── sys_map_invalid_mr.system
│ │ ├── pd_duplicate_child_id.system
│ │ ├── sys_channel_duplicate_a_id.system
│ │ ├── sys_channel_duplicate_b_id.system
│ │ ├── ch_too_many_ends.system
│ │ ├── vm_duplicate_name.system
│ │ └── vm_overlapping_maps.system
│ ├── src
│ ├── capdl
│ │ ├── mod.rs
│ │ ├── packaging.rs
│ │ ├── spec.rs
│ │ └── initialiser.rs
│ ├── crc32.rs
│ └── uimage.rs
│ └── Cargo.toml
├── .cargo
└── config.toml
├── LICENSES
├── LicenseRef-Trademark.txt
└── BSD-2-Clause.txt
├── example
├── rust
│ ├── .cargo
│ │ └── config.toml
│ ├── rust-toolchain.toml
│ ├── rust.system
│ ├── Cargo.toml
│ ├── hello.rs
│ ├── README.md
│ ├── support
│ │ └── targets
│ │ │ ├── riscv64gc-sel4-microkit-minimal.json
│ │ │ └── aarch64-sel4-microkit-minimal.json
│ └── Makefile
├── hello
│ ├── hello.system
│ ├── hello.c
│ ├── README.md
│ └── Makefile
├── arm_smc
│ ├── arm_smc.system
│ ├── README.md
│ ├── arm_smc.c
│ └── Makefile
├── hierarchy
│ ├── hello.c
│ ├── crasher.c
│ ├── hierarchy.system
│ ├── README.md
│ ├── restarter.c
│ └── Makefile
├── x86_64_ioport
│ ├── x86_64_ioport.system
│ ├── README.md
│ ├── x86_64_ioport.c
│ └── Makefile
├── timer
│ ├── timer.system
│ ├── README.md
│ ├── Makefile
│ └── timer.c
├── passive_server
│ ├── client.c
│ ├── passive_server.system
│ ├── README.md
│ ├── server.c
│ └── Makefile
├── ethernet
│ ├── README.md
│ ├── foo.c
│ └── Makefile
└── setvar
│ ├── README.md
│ ├── setvar.system
│ ├── setvar.c
│ └── Makefile
├── requirements.txt
├── .gitignore
├── tests
├── overlapping_pages
│ ├── README.md
│ ├── overlapping_pages.c
│ ├── overlapping_pages.system
│ └── Makefile
├── simplemrs
│ ├── README.md
│ ├── simplemrs.c
│ ├── simplemrs.system
│ └── Makefile
└── capfault
│ ├── capfault.system
│ ├── README.md
│ ├── capfault.c
│ └── Makefile
├── ci
└── dev_version.sh
├── loader
├── src
│ ├── riscv
│ │ ├── exceptions.c
│ │ ├── init.c
│ │ ├── mmu.c
│ │ ├── sbi.h
│ │ ├── sbi.c
│ │ └── cpus.c
│ ├── cutil.h
│ ├── aarch64
│ │ ├── el.h
│ │ ├── mmu.c
│ │ ├── exceptions.c
│ │ ├── el.c
│ │ ├── crt0.S
│ │ ├── exceptions.h
│ │ ├── smc.h
│ │ └── init.c
│ ├── uart.h
│ ├── loader.h
│ ├── cutil.c
│ ├── cpus.h
│ └── arch.h
├── aarch64.ld
├── riscv64.ld
└── Makefile
├── .github
├── CODE_OF_CONDUCT.md
├── workflows
│ ├── push.yml
│ └── pr.yml
└── CONTRIBUTING.md
├── Cargo.toml
├── mypy.ini
├── .reuse
└── dep5
├── LICENSE.md
├── README.md
├── platforms.yml
├── dev_build.py
├── flake.lock
└── flake.nix
/VERSION:
--------------------------------------------------------------------------------
1 | 2.1.0-dev
2 |
--------------------------------------------------------------------------------
/docs/assets/microkit_flow.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seL4/microkit/HEAD/docs/assets/microkit_flow.pdf
--------------------------------------------------------------------------------
/docs/style/logos/seL4-key.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seL4/microkit/HEAD/docs/style/logos/seL4-key.pdf
--------------------------------------------------------------------------------
/docs/style/logos/blacktriangle.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seL4/microkit/HEAD/docs/style/logos/blacktriangle.pdf
--------------------------------------------------------------------------------
/docs/style/logos/seL4-Foundation-logo.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seL4/microkit/HEAD/docs/style/logos/seL4-Foundation-logo.pdf
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | [flake8]
7 | ignore = E501
8 |
--------------------------------------------------------------------------------
/initialiser/src/main.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, Colias Group, LLC
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | #![no_std]
8 | #![no_main]
9 |
10 | extern crate sel4_capdl_initializer;
11 |
--------------------------------------------------------------------------------
/monitor/src/x86_64/crt0.s:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | .section .text.start
8 | .globl _start
9 | _start:
10 | call main
11 |
--------------------------------------------------------------------------------
/libmicrokit/src/x86_64/crt0.s:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | .section .text.start
8 | .globl _start
9 | _start:
10 | call main
11 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_no_protection_domains.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | # Copyright 2024, UNSW
2 | # SPDX-License-Identifier: BSD-2-Clause
3 |
4 | [target.aarch64-unknown-linux-musl]
5 | rustflags = ["-Clinker=rust-lld"]
6 |
7 | [target.x86_64-unknown-linux-musl]
8 | rustflags = ["-Clinker=rust-lld"]
9 |
--------------------------------------------------------------------------------
/LICENSES/LicenseRef-Trademark.txt:
--------------------------------------------------------------------------------
1 | For license and usage guidelines on the seL4 trademark and logo, including
2 | the seL4 Foundation logo, see https://sel4.systems/Foundation/Trademark/
3 |
4 | No further license is granted from use in this repository.
5 |
--------------------------------------------------------------------------------
/example/rust/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2023, Colias Group, LLC
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 |
7 | [unstable]
8 | unstable-options = true
9 |
10 | [env]
11 | RUST_TARGET_PATH = { value = "support/targets", relative = true }
12 |
--------------------------------------------------------------------------------
/example/rust/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2023, Colias Group, LLC
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 |
7 | [toolchain]
8 | channel = "nightly-2025-02-26"
9 | components = [ "rustfmt", "rust-src", "rustc-dev", "llvm-tools-preview" ]
10 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | mypy==0.910
7 | black==21.7b0
8 | flake8==3.9.2
9 | ply==3.11
10 | Jinja2==3.0.3
11 | PyYAML==6.0.2
12 | pyfdt==0.3
13 | lxml==5.2.1
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 |
7 | __pycache__
8 | *-sdk-*/
9 | build/
10 | env/
11 | pyenv/
12 | release/
13 | tmp_build/
14 | target/
15 | *.orig
16 | .DS_Store
17 | *.pdf
18 |
--------------------------------------------------------------------------------
/monitor/src/aarch64/crt0.s:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | .extern main
7 |
8 | .section ".text.start"
9 |
10 | .global _start;
11 | .type _start, %function;
12 | _start:
13 | b main
14 |
--------------------------------------------------------------------------------
/libmicrokit/src/aarch64/crt0.s:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | .extern main
7 |
8 | .section ".text.start"
9 |
10 | .global _start;
11 | .type _start, %function;
12 | _start:
13 | b main
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_program_image.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_parent_has_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_missing_name.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_not_child.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_missing_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tests/overlapping_pages/README.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | # Overlapping Pages Test
7 |
8 | The purpose of this is to test that when a user attempts to create overlapping pages in the address space a build error occurs.
--------------------------------------------------------------------------------
/tests/simplemrs/README.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | # Simple Memory Region Tests
7 |
8 | The purpose of this is to test very simple system with two MRs and a single PD.
9 |
10 | It is a very simple smoke test.
11 |
--------------------------------------------------------------------------------
/initialiser/Cargo.toml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2025, Colias Group, LLC
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 |
7 | [package]
8 | name = "initialiser"
9 | version = "2.1.0-dev"
10 | edition = "2021"
11 | rust-version = "1.88.0"
12 |
13 | [dependencies]
14 | sel4-capdl-initializer = { workspace = true }
15 |
--------------------------------------------------------------------------------
/example/hello/hello.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/rust/rust.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tool/microkit/src/capdl/mod.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | pub mod allocation;
8 | pub mod builder;
9 | pub mod initialiser;
10 | mod irq;
11 | mod memory;
12 | pub mod packaging;
13 | pub mod spec;
14 | mod util;
15 |
16 | pub use self::builder::*;
17 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_malformed_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_invalid_cpu.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example/arm_smc/arm_smc.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_unsupported_page_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/hello/hello.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | void init(void)
10 | {
11 | microkit_dbg_puts("hello, world\n");
12 | }
13 |
14 | void notified(microkit_channel ch)
15 | {
16 | }
17 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_path.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example/hierarchy/hello.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | void init(void)
10 | {
11 | microkit_dbg_puts("hello, world\n");
12 | }
13 |
14 | void notified(microkit_channel ch)
15 | {
16 | }
17 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_size_not_multiple_of_page_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_name.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_text_elements.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | asdf
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ci/dev_version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2024, UNSW
4 | # SPDX-License-Identifier: BSD-2-Clause
5 |
6 | set -e
7 |
8 | VERSION=`cat VERSION`
9 | LATEST_TAG=`git describe --tags --abbrev=0`
10 | NUM_COMMITS=`git rev-list --count $LATEST_TAG..HEAD`
11 | HEAD=`git rev-parse --short HEAD`
12 |
13 | echo "$VERSION.$NUM_COMMITS+$HEAD"
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_missing_vcpu.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_arm_on_x86.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_invalid_attrs.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_id_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_addr_not_aligned_to_page_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tests/capfault/capfault.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_id_greater_than_max.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_small_stack_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_program_image_invalid_attrs.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_budget_gt_period.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_irq.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_unaligned_stack_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example/rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2025, UNSW
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | #
7 | [package]
8 | name = "hello"
9 | version = "0.1.0"
10 | edition = "2021"
11 | license = "BSD-2-Clause"
12 |
13 | [[bin]]
14 | name = "hello"
15 | path = "hello.rs"
16 |
17 | [dependencies]
18 | sel4-microkit = { git = "https://github.com/seL4/rust-sel4" }
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_ioapic_on_arm.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_missing_vcpu_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/rust/hello.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | #![no_std]
8 | #![no_main]
9 |
10 | use sel4_microkit::{NullHandler, protection_domain, debug_println};
11 |
12 | #[protection_domain()]
13 | fn init() -> NullHandler {
14 | debug_println!("hello, world from Rust!");
15 |
16 | NullHandler::new()
17 | }
18 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_msi_on_arm.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_invalid_trigger.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_ioapic_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_ioapic_pin_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_invalid_vcpu_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/loader/src/riscv/exceptions.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include "../arch.h"
9 |
10 | void arch_set_exception_handler(void)
11 | {
12 | /* Don't do anything on RISC-V since we always are in S-mode so M-mode
13 | * will catch our faults (e.g SBI). */
14 | }
15 |
--------------------------------------------------------------------------------
/tests/simplemrs/simplemrs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | volatile uint8_t *p;
10 | volatile uint8_t *q;
11 |
12 | void
13 | init(void)
14 | {
15 | *p = 'A';
16 | *q = 'Z';
17 | }
18 |
19 | void
20 | notified(microkit_channel ch)
21 | {
22 | }
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_ioapic_vector_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_msi_handle_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_msi_vector_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_invalid_vcpu_cpu.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/hierarchy/crasher.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | void init(void)
10 | {
11 | int *x = 0;
12 | microkit_dbg_puts("crasher, starting\n");
13 | /* Crash! */
14 | *x = 1;
15 | }
16 |
17 | void notified(microkit_channel ch)
18 | {
19 | }
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_msi_pci_bus_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_msi_pci_dev_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_msi_pci_func_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 |
6 |
7 | # Code of Conduct
8 |
9 | This repository and interactions with it fall under the [seL4 Code of Conduct][1] available from the [seL4 website][2].
10 |
11 | [1]: https://docs.sel4.systems/processes/conduct.html
12 | [2]: https://sel4.systems
13 |
--------------------------------------------------------------------------------
/monitor/src/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #pragma once
7 |
8 | #include
9 | #include
10 |
11 | void putc(uint8_t ch);
12 | void puts(const char *s);
13 | void puthex32(uint32_t val);
14 | void puthex64(uint64_t val);
15 | void fail(char *s);
16 | char* sel4_strerror(seL4_Word err);
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_invalid_x86_io_port_size.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/overlapping_pages/overlapping_pages.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | volatile uint8_t *p;
10 | volatile uint8_t *q;
11 |
12 | void
13 | init(void)
14 | {
15 | *p = 'A';
16 | *q = 'Z';
17 | }
18 |
19 | void
20 | notified(microkit_channel ch)
21 | {
22 | }
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_ioapic_invalid_polarity.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/irq_ioapic_invalid_trigger.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.github/workflows/push.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
2 | #
3 | # SPDX-License-Identifier: BSD-2-Clause
4 |
5 | # Actions to run on Push and Pull Request
6 | name: CI
7 |
8 | on:
9 | push:
10 | branches:
11 | - main
12 | pull_request:
13 | workflow_dispatch:
14 |
15 | jobs:
16 | checks:
17 | name: Checks
18 | uses: seL4/ci-actions/.github/workflows/push.yml@master
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_duplicate_irq_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/monitor/src/riscv/crt0.s:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | .extern main
8 | .extern __global_pointer$
9 |
10 | .section ".text.start"
11 |
12 | .global _start;
13 | .type _start, %function;
14 | _start:
15 | .option push
16 | .option norelax
17 | 1: auipc gp, %pcrel_hi(__global_pointer$)
18 | addi gp, gp, %pcrel_lo(1b)
19 | .option pop
20 | j main
21 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_invalid_attrs.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/libmicrokit/src/riscv/crt0.s:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | .extern main
8 | .extern __global_pointer$
9 |
10 | .section ".text.start"
11 |
12 | .global _start;
13 | .type _start, %function;
14 | _start:
15 | .option push
16 | .option norelax
17 | 1: auipc gp, %pcrel_hi(__global_pointer$)
18 | addi gp, gp, %pcrel_lo(1b)
19 | .option pop
20 | j main
21 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_write_only_mr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_region_paddr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_symbol.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_map_not_aligned.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_duplicate_program_image.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_overlapping_x86_io_ports_1.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/x86_64_ioport/x86_64_ioport.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_child_missing_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_mr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_missing_vaddr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_duplicate_pd_name.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tests/capfault/README.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | # Cap Fault Test
7 |
8 | The purpose of the capfault test is to verify that the monitor will
9 | correctly detect and output debug information in case a protection
10 | domain generates a cap fault.
11 |
12 | Note: This test is (currently) expected to be run manually, and
13 | the output inspected to ensure cap fault debugging is output.
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/mr_overlapping_phys_addr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_map_too_high.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_duplicate_mr_name.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_not_enough_ends.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_duplicate_setvar.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tests/capfault/capfault.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | #define ECHO_CH 2
10 |
11 | volatile uint64_t *shared_counter = (uint64_t *)(uintptr_t)0x1800000;
12 |
13 | void
14 | init(void)
15 | {
16 | microkit_dbg_puts("capfault: forcing a cap fault by notifying invalid channel 10,000\n");
17 | microkit_notify(10000);
18 | }
19 |
20 | void
21 | notified(microkit_channel ch)
22 | {
23 | }
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_missing_mr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/example/arm_smc/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - ARM SMC
6 |
7 | This is a basic example that performs a Secure Monitor Call.
8 |
9 | All supported ARM platforms are supported in this example.
10 |
11 | ## Building
12 |
13 | ```sh
14 | mkdir build
15 | make BUILD_DIR=build MICROKIT_BOARD= MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
16 | ```
17 |
18 | ## Running
19 |
20 | See instructions for your board in the manual.
21 |
--------------------------------------------------------------------------------
/example/timer/timer.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_duplicate_irq_number.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/example/passive_server/client.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #include
8 |
9 | #define SERVER_CH 0
10 |
11 | void init(void)
12 | {
13 | microkit_dbg_puts("CLIENT|INFO: init function running\n");
14 |
15 | /* message the server */
16 | (void) microkit_ppcall(SERVER_CH, microkit_msginfo_new(1, 1));
17 | }
18 |
19 | void notified(microkit_channel ch)
20 | {
21 | microkit_dbg_puts("CLIENT|INFO: received a notification on an unexpected channel\n");
22 | }
23 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_missing_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_missing_pd.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_end_invalid_pp.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_end_invalid_notify.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_id_less_than_0.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_invalid_element.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_invalid_pd.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/ethernet/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Ethernet
6 |
7 | This example shows an ethernet system for the TQMa8XQP platform.
8 | It also includes a driver for the general purpose timer on the platform.
9 |
10 | ## Building
11 |
12 | ```sh
13 | mkdir build
14 | make BUILD_DIR=build MICROKIT_BOARD=tqma8xqp1gb MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
15 | ```
16 |
17 | ## Running
18 |
19 | See instructions for your board in the manual.
20 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_id_greater_than_max.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_invalid_attrs.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_duplicate_child_id_vcpu.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_overlapping_maps.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_ppcall_priority.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_bidirectional_ppc.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_overlapping_x86_io_ports_2.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_map_invalid_mr.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/hello/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Hello World
6 |
7 | This is a basic hello world example that has a single protection domain
8 | that simply prints "hello, world!" upon initialisation.
9 |
10 | All supported platforms are supported in this example.
11 |
12 | ## Building
13 |
14 | ```sh
15 | mkdir build
16 | make BUILD_DIR=build MICROKIT_BOARD= MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
17 | ```
18 |
19 | ## Running
20 |
21 | See instructions for your board in the manual.
22 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/pd_duplicate_child_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2025, Colias Group, LLC
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 |
7 | [workspace]
8 | resolver = "3"
9 | members = [
10 | "tool/microkit",
11 | "initialiser",
12 | ]
13 |
14 | [workspace.dependencies.sel4-capdl-initializer]
15 | git = "https://github.com/seL4/rust-seL4"
16 | rev = "0ac1c27ee6cb9edac7a1a41a69b0d421e170d6a4"
17 |
18 | [workspace.dependencies.sel4-capdl-initializer-types]
19 | git = "https://github.com/seL4/rust-seL4"
20 | rev = "0ac1c27ee6cb9edac7a1a41a69b0d421e170d6a4"
21 |
22 | [profile.release.package.microkit-tool]
23 | strip = true
24 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_channel_duplicate_a_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/sys_channel_duplicate_b_id.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/example/timer/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Timer
6 |
7 | This example shows a basic timer driver for the Odroid-C4
8 | platform. The timer driver initialises the device and then
9 | sets a regular 1 second timeout and prints the current time
10 | whenever the timeout expires.
11 |
12 | ## Building
13 |
14 | ```sh
15 | mkdir build
16 | make BUILD_DIR=build MICROKIT_BOARD=odroidc4 MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
17 | ```
18 |
19 | ## Running
20 |
21 | See instructions for your board in the manual.
22 |
--------------------------------------------------------------------------------
/example/x86_64_ioport/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Hello World
6 |
7 | This is a basic hello world example that has a single protection domain
8 | that simply prints "hello!" via the first serial I/O port (0x3F8) upon initialisation.
9 |
10 | Only x86_64 platforms are supported.
11 |
12 | ## Building
13 |
14 | ```sh
15 | mkdir build
16 | make BUILD_DIR=build MICROKIT_BOARD= MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
17 | ```
18 |
19 | ## Running
20 |
21 | See instructions for your board in the manual.
22 |
--------------------------------------------------------------------------------
/example/passive_server/passive_server.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/ch_too_many_ends.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tool/microkit/Cargo.toml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2024, UNSW
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 |
7 | [package]
8 | name = "microkit-tool"
9 | version = "2.1.0-dev"
10 | edition = "2021"
11 | rust-version = "1.88.0"
12 |
13 | [[bin]]
14 | name = "microkit"
15 | path = "src/main.rs"
16 |
17 | [dependencies]
18 | roxmltree = "0.19.0"
19 | serde = { version = "1.0.228", features = ["derive"] }
20 | serde_json = "1.0.117"
21 | rkyv = { version = "0.8.12", default-features = false, features = ["alloc", "bytecheck", "pointer_width_32"] }
22 | sel4-capdl-initializer-types = { workspace = true, features = ["serde", "deflate", "transform"] }
23 |
--------------------------------------------------------------------------------
/example/hierarchy/hierarchy.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tool/microkit/src/crc32.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | pub fn crc32(bytes: &[u8]) -> u32 {
8 | // Could be more optimised using the table approach.
9 | // Source: https://web.archive.org/web/20190108202303/http://www.hackersdelight.org/hdcodetxt/crc.c.txt
10 | let mut crc: u32 = 0xFFFF_FFFF;
11 |
12 | for &byte in bytes {
13 | crc ^= byte as u32;
14 | for _ in 0..8 {
15 | if crc & 1 != 0 {
16 | crc = (crc >> 1) ^ 0xEDB8_8320;
17 | } else {
18 | crc >>= 1;
19 | }
20 | }
21 | }
22 |
23 | !crc
24 | }
25 |
--------------------------------------------------------------------------------
/tool/microkit/tests/sdf/vm_duplicate_name.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/example/setvar/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - setvar
6 |
7 | This is a basic example that demonstrate how to use some `setvar` functionalities that the Microkit provides.
8 |
9 | Only QEMU virt (AArch64) is supported in this example. Although everything will work the same way on other
10 | platforms, but on x86-64 `
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/hierarchy/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Hierarchy
6 |
7 | This example shows off the parent/child PD concept in Microkit as
8 | well as fault handling. The parent 'restarter' PD receives faults
9 | from the 'crasher' PD that is intentionally crashing and then
10 | resets the crasher's program counter.
11 |
12 | All supported platforms are supported in this example.
13 |
14 | ## Building
15 |
16 | ```sh
17 | mkdir build
18 | make BUILD_DIR=build MICROKIT_BOARD= MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
19 | ```
20 |
21 | ## Running
22 |
23 | See instructions for your board in the manual.
24 |
--------------------------------------------------------------------------------
/loader/aarch64.ld:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | PHDRS
7 | {
8 | all PT_LOAD AT (LINK_ADDRESS);
9 | }
10 |
11 | SECTIONS
12 | {
13 | . = LINK_ADDRESS;
14 |
15 | .text :
16 | {
17 | _text = .;
18 | *(.text.start)
19 | *(.text*)
20 | *(.rodata)
21 | _text_end = .;
22 | } :all
23 |
24 | .data :
25 | {
26 | _data = .;
27 | *(.data)
28 | _data_end = .;
29 | } :all
30 |
31 | .bss :
32 | {
33 | _bss = .;
34 | *(.bss)
35 | *(COMMON)
36 | . = ALIGN(4);
37 | _bss_end = .;
38 | } :all
39 | }
40 |
--------------------------------------------------------------------------------
/loader/src/cutil.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #define ALIGN(n) __attribute__((__aligned__(n)))
12 |
13 | #define BIT(n) (1UL << (n))
14 | #define MASK(x) (BIT(x) - 1UL)
15 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
16 |
17 | #define is_set(macro) _is_set_(macro)
18 | #define _macrotest_1 ,
19 | #define _is_set_(value) _is_set__(_macrotest_##value)
20 | #define _is_set__(comma) _is_set___(comma 1, 0)
21 | #define _is_set___(_, v, ...) v
22 |
23 | void *memcpy(void *dst, const void *src, size_t sz);
24 |
25 | void *memmove(void *restrict dest, const void *restrict src, size_t n);
26 |
--------------------------------------------------------------------------------
/tests/simplemrs/simplemrs.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/loader/src/aarch64/el.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #pragma once
9 |
10 | #include
11 |
12 | enum el {
13 | EL0 = 0,
14 | EL1 = 1,
15 | EL2 = 2,
16 | EL3 = 3,
17 | };
18 |
19 | enum el current_el(void);
20 | int ensure_correct_el(int logical_cpu);
21 |
22 | static inline const char *el_to_string(enum el el)
23 | {
24 | switch (el) {
25 | case EL0:
26 | return "EL0";
27 | case EL1:
28 | return "EL1";
29 | case EL2:
30 | return "EL2";
31 | case EL3:
32 | return "EL3";
33 | }
34 |
35 | return "";
36 | }
37 |
--------------------------------------------------------------------------------
/tests/overlapping_pages/overlapping_pages.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/arm_smc/arm_smc.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | #define PSCI_VERSION_FID 0x84000000
10 |
11 | void init(void)
12 | {
13 | microkit_dbg_puts("Getting SMC version via microkit_arm_smc_call()\n");
14 |
15 | seL4_ARM_SMCContext args = {0};
16 | seL4_ARM_SMCContext resp = {0};
17 |
18 | args.x0 = PSCI_VERSION_FID;
19 | microkit_arm_smc_call(&args, &resp);
20 |
21 | microkit_dbg_puts("PSCI version: ");
22 | microkit_dbg_put32(((uint32_t) resp.x0 >> 16) & 0xFFFF);
23 | microkit_dbg_puts(".");
24 | microkit_dbg_put32((uint32_t) resp.x0 & 0xFFFF);
25 | microkit_dbg_puts("\n");
26 | }
27 |
28 | void notified(microkit_channel ch)
29 | {
30 | }
31 |
--------------------------------------------------------------------------------
/example/passive_server/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Passive Server
6 |
7 | This example shows a client and server PD communicating with each
8 | other where the server does not have an active scheduling context
9 | and is therefore a 'passive' server.
10 |
11 | When the client PPCs into the server, the server is executing on
12 | the client's budget. See the manual for more details on passive
13 | PDs.
14 |
15 | All supported platforms are supported in this example.
16 |
17 | ## Building
18 |
19 | ```sh
20 | mkdir build
21 | make BUILD_DIR=build MICROKIT_BOARD= MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
22 | ```
23 |
24 | ## Running
25 |
26 | See instructions for your board in the manual.
27 |
--------------------------------------------------------------------------------
/loader/riscv64.ld:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | PHDRS
7 | {
8 | all PT_LOAD AT (LINK_ADDRESS);
9 | }
10 |
11 | SECTIONS
12 | {
13 | . = LINK_ADDRESS;
14 |
15 | .text :
16 | {
17 | _text = .;
18 | *(.text.start)
19 | *(.text*)
20 | *(.rodata)
21 | _text_end = .;
22 | } :all
23 |
24 | .data :
25 | {
26 | _data = .;
27 | *(.data)
28 | __global_pointer$ = . + 0x800;
29 | *(.srodata)
30 | *(.sdata)
31 | _data_end = .;
32 | } :all
33 |
34 | .bss :
35 | {
36 | _bss = .;
37 | *(.sbss)
38 | *(.bss)
39 | *(COMMON)
40 | . = ALIGN(4);
41 | _bss_end = .;
42 | } :all
43 | }
44 |
--------------------------------------------------------------------------------
/.reuse/dep5:
--------------------------------------------------------------------------------
1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Upstream-Name: seL4
3 | Upstream-Contact: seL4 team
4 | Source: http://sel4.systems
5 |
6 | Files:
7 | Cargo.lock
8 | example/rust/Cargo.lock
9 | example/rust/support/*.json
10 | initialiser/support/*.json
11 | flake.lock
12 | CHANGES.md
13 | VERSION
14 | docs/assets/microkit_flow.svg
15 | docs/assets/microkit_flow.pdf
16 | Copyright: 2024, UNSW
17 | License: BSD-2-Clause
18 |
19 | Files:
20 | docs/style/logos/blacktriangle.pdf
21 | docs/style/logos/seL4-key.pdf
22 | Copyright: 2020, Data61, CSIRO (ABN 41 687 119 230)
23 | License: CC-BY-SA-4.0
24 |
25 | Files:
26 | docs/style/logos/seL4-Foundation-logo.pdf
27 | Copyright: seL4 Project a Series of LF Projects, LLC
28 | License: LicenseRef-Trademark
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | # License
7 |
8 | The files in the Microkit project are released under standard open source
9 | licenses, identified by [SPDX license tags][1]. See the individual file headers
10 | for details, or use one of the publicly available SPDX tools to generate a bill
11 | of materials. The directory [`LICENSES`][2] contains the text for all licenses
12 | that are mentioned by files in this project.
13 |
14 | Code contributions to this project should be licensed under the [BSD-2-Clause]
15 | license, and documentation under the [CC-BY-SA-4.0] license.
16 |
17 | [1]: https://spdx.org
18 | [2]: LICENSES/
19 | [BSD-2-CLAUSE]: LICENSES/BSD-2-Clause.txt
20 | [CC-BY-SA-4.0]: LICENSES/CC-BY-SA-4.0.txt
21 |
--------------------------------------------------------------------------------
/initialiser/support/targets/riscv64imac-sel4-minimal.json:
--------------------------------------------------------------------------------
1 | {
2 | "arch": "riscv64",
3 | "code-model": "medium",
4 | "cpu": "generic-rv64",
5 | "crt-objects-fallback": "false",
6 | "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
7 | "emit-debug-gdb-scripts": false,
8 | "exe-suffix": ".elf",
9 | "features": "+m,+a,+c",
10 | "linker": "rust-lld",
11 | "linker-flavor": "gnu-lld",
12 | "llvm-abiname": "lp64",
13 | "llvm-target": "riscv64",
14 | "max-atomic-width": 64,
15 | "metadata": {
16 | "description": null,
17 | "host_tools": null,
18 | "std": null,
19 | "tier": null
20 | },
21 | "panic-strategy": "abort",
22 | "relocation-model": "static",
23 | "supported-sanitizers": [
24 | "shadow-call-stack",
25 | "kernel-address"
26 | ],
27 | "target-pointer-width": "64"
28 | }
29 |
--------------------------------------------------------------------------------
/example/passive_server/server.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #include
8 |
9 | microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo)
10 | {
11 | switch (microkit_msginfo_get_label(msginfo)) {
12 | case 1:
13 | microkit_dbg_puts("SERVER|INFO: running on clients scheduling context\n");
14 | break;
15 | default:
16 | microkit_dbg_puts("SERVER|ERROR: received an unexpected message\n");
17 | }
18 |
19 | return seL4_MessageInfo_new(0, 0, 0, 0);
20 | }
21 |
22 | void init(void)
23 | {
24 | microkit_dbg_puts("SERVER|INFO: init function running\n");
25 | /* Nothing to initialise */
26 | }
27 |
28 | void notified(microkit_channel ch)
29 | {
30 | microkit_dbg_puts("SERVER|ERROR: received a notification on an unexpected channel\n");
31 | }
32 |
--------------------------------------------------------------------------------
/example/rust/README.md:
--------------------------------------------------------------------------------
1 |
5 | # Example - Rust
6 |
7 | This example is the same as the 'hello' example expect that the
8 | protection domain is written in Rust instead of C. This makes
9 | use of the [rust-sel4](https://github.com/seL4/rust-sel4) Microkit
10 | support.
11 |
12 | You can find more complicated example systems written in Rust
13 | at the following links:
14 |
15 | * https://github.com/seL4/rust-microkit-demo
16 | * https://github.com/seL4/rust-microkit-http-server-demo
17 |
18 | All supported platforms are supported in this example.
19 |
20 | ## Building
21 |
22 | ```sh
23 | mkdir build
24 | make BUILD_DIR=build MICROKIT_BOARD= MICROKIT_CONFIG= MICROKIT_SDK=/path/to/sdk
25 | ```
26 |
27 | ## Running
28 |
29 | See instructions for your board in the manual.
30 |
--------------------------------------------------------------------------------
/tests/capfault/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | LIBMICROKIT := ../../libmicrokit
7 | TOOLCHAIN := aarch64-linux-gnu
8 | PYTHON := python3.8
9 |
10 | CPU := cortex-a35
11 |
12 | CC := $(TOOLCHAIN)-gcc
13 | LD := $(TOOLCHAIN)-ld
14 | AS := $(TOOLCHAIN)-as
15 |
16 | CAPFAULT_OBJS := capfault.o
17 |
18 | IMAGES := capfault.elf
19 | CFLAGS := -mcpu=$(CPU) -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(SEL4_SDK)/include -I$(LIBMICROKIT)/include
20 | LDFLAGS := -L$(LIBMICROKIT) -Tmicrokit.ld
21 | LIBS := -lmicrokit
22 |
23 |
24 | all: $(IMAGES)
25 |
26 | %.o: %.c Makefile
27 | $(CC) -c $(CFLAGS) $< -o $@
28 |
29 | %.o: %.s Makefile
30 | $(AS) -g -mcpu=$(CPU) $< -o $@
31 |
32 | capfault.elf: $(CAPFAULT_OBJS)
33 | $(LD) $(LDFLAGS) $(CAPFAULT_OBJS) $(LIBS) -o $@
34 |
--------------------------------------------------------------------------------
/tests/simplemrs/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | LIBMICROKIT := ../../libmicrokit
7 | TOOLCHAIN := aarch64-linux-gnu
8 | PYTHON := python3.8
9 |
10 | CPU := cortex-a35
11 |
12 | CC := $(TOOLCHAIN)-gcc
13 | LD := $(TOOLCHAIN)-ld
14 | AS := $(TOOLCHAIN)-as
15 |
16 | SIMPLEMRS_OBJS := simplemrs.o
17 |
18 | IMAGES := simplemrs.elf
19 | CFLAGS := -mcpu=$(CPU) -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(SEL4_SDK)/include -I$(LIBMICROKIT)/include
20 | LDFLAGS := -L$(LIBMICROKIT) -Tmicrokit.ld
21 | LIBS := -lmicrokit
22 |
23 |
24 | all: $(IMAGES)
25 |
26 | %.o: %.c Makefile
27 | $(CC) -c $(CFLAGS) $< -o $@
28 |
29 | %.o: %.s Makefile
30 | $(AS) -g -mcpu=$(CPU) $< -o $@
31 |
32 | simplemrs.elf: $(SIMPLEMRS_OBJS)
33 | $(LD) $(LDFLAGS) $(SIMPLEMRS_OBJS) $(LIBS) -o $@
34 |
--------------------------------------------------------------------------------
/example/rust/support/targets/riscv64gc-sel4-microkit-minimal.json:
--------------------------------------------------------------------------------
1 | {
2 | "arch": "riscv64",
3 | "code-model": "medium",
4 | "cpu": "generic-rv64",
5 | "crt-objects-fallback": "false",
6 | "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
7 | "emit-debug-gdb-scripts": false,
8 | "exe-suffix": ".elf",
9 | "features": "+m,+a,+f,+d,+c",
10 | "link-script": "__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;",
11 | "linker": "rust-lld",
12 | "linker-flavor": "gnu-lld",
13 | "llvm-abiname": "lp64d",
14 | "llvm-target": "riscv64",
15 | "max-atomic-width": 64,
16 | "metadata": {
17 | "description": null,
18 | "host_tools": null,
19 | "std": null,
20 | "tier": null
21 | },
22 | "panic-strategy": "abort",
23 | "relocation-model": "static",
24 | "supported-sanitizers": [
25 | "shadow-call-stack",
26 | "kernel-address"
27 | ],
28 | "target-pointer-width": "64"
29 | }
30 |
--------------------------------------------------------------------------------
/tests/overlapping_pages/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | LIBMICROKIT := ../../libmicrokit
7 | TOOLCHAIN := aarch64-linux-gnu
8 | PYTHON := python3.8
9 |
10 | CPU := cortex-a35
11 |
12 | CC := $(TOOLCHAIN)-gcc
13 | LD := $(TOOLCHAIN)-ld
14 | AS := $(TOOLCHAIN)-as
15 |
16 | OVERLAPPING_PAGES_OBJS := overlapping_pages.o
17 |
18 | IMAGES := overlapping_pages.elf
19 | CFLAGS := -mcpu=$(CPU) -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(SEL4_SDK)/include -I$(LIBMICROKIT)/include
20 | LDFLAGS := -L$(LIBMICROKIT) -Tmicrokit.ld
21 | LIBS := -lmicrokit
22 |
23 |
24 | all: $(IMAGES)
25 |
26 | %.o: %.c Makefile
27 | $(CC) -c $(CFLAGS) $< -o $@
28 |
29 | %.o: %.s Makefile
30 | $(AS) -g -mcpu=$(CPU) $< -o $@
31 |
32 | overlapping_pages.elf: $(OVERLAPPING_PAGES_OBJS)
33 | $(LD) $(LDFLAGS) $(OVERLAPPING_PAGES_OBJS) $(LIBS) -o $@
34 |
--------------------------------------------------------------------------------
/initialiser/support/targets/aarch64-sel4-minimal.json:
--------------------------------------------------------------------------------
1 | {
2 | "arch": "aarch64",
3 | "crt-objects-fallback": "false",
4 | "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
5 | "disable-redzone": true,
6 | "exe-suffix": ".elf",
7 | "features": "+v8a,+strict-align,+neon,+fp-armv8",
8 | "linker": "rust-lld",
9 | "linker-flavor": "gnu-lld",
10 | "llvm-target": "aarch64-unknown-none",
11 | "max-atomic-width": 128,
12 | "metadata": {
13 | "description": null,
14 | "host_tools": null,
15 | "std": null,
16 | "tier": null
17 | },
18 | "panic-strategy": "abort",
19 | "pre-link-args": {
20 | "gnu-lld": [
21 | "-z",
22 | "max-page-size=4096"
23 | ]
24 | },
25 | "relocation-model": "static",
26 | "stack-probes": {
27 | "kind": "inline"
28 | },
29 | "supported-sanitizers": [
30 | "kcfi",
31 | "kernel-address"
32 | ],
33 | "target-pointer-width": "64"
34 | }
35 |
--------------------------------------------------------------------------------
/initialiser/support/targets/x86_64-sel4-minimal.json:
--------------------------------------------------------------------------------
1 | {
2 | "arch": "x86_64",
3 | "code-model": "small",
4 | "cpu": "x86-64",
5 | "crt-objects-fallback": "false",
6 | "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
7 | "disable-redzone": true,
8 | "exe-suffix": ".elf",
9 | "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float",
10 | "linker": "rust-lld",
11 | "linker-flavor": "gnu-lld",
12 | "llvm-target": "x86_64-unknown-none-elf",
13 | "max-atomic-width": 64,
14 | "metadata": {
15 | "description": null,
16 | "host_tools": null,
17 | "std": null,
18 | "tier": null
19 | },
20 | "panic-strategy": "abort",
21 | "plt-by-default": false,
22 | "relro-level": "full",
23 | "rustc-abi": "x86-softfloat",
24 | "stack-probes": {
25 | "kind": "inline"
26 | },
27 | "supported-sanitizers": [
28 | "kcfi",
29 | "kernel-address"
30 | ],
31 | "target-pointer-width": "64"
32 | }
33 |
--------------------------------------------------------------------------------
/example/x86_64_ioport/x86_64_ioport.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | uint64_t com1_ioport_id;
10 | uint64_t com1_ioport_addr;
11 |
12 | static inline void serial_putc(char ch)
13 | {
14 | // Danger: may overflow hardware FIFO, but we are only writing a small message.
15 | microkit_x86_ioport_write_8(com1_ioport_id, com1_ioport_addr, ch);
16 | }
17 |
18 | static inline void serial_puts(const char *s)
19 | {
20 | while (*s) {
21 | if (*s == '\n') {
22 | serial_putc('\r');
23 | }
24 | serial_putc(*s++);
25 | }
26 | }
27 |
28 | void init(void)
29 | {
30 | microkit_dbg_puts("hello, world. my name is ");
31 | microkit_dbg_puts(microkit_name);
32 | microkit_dbg_puts("\n");
33 |
34 | microkit_dbg_puts("Now writing to serial I/O port: ");
35 | serial_puts("hello!\n");
36 | }
37 |
38 | void notified(microkit_channel ch)
39 | {
40 | }
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | # seL4 Microkit
7 |
8 | The purpose of the seL4 Microkit is to enable system designers to create static software systems based on the seL4 microkernel.
9 |
10 | The seL4 Microkit consists of five components:
11 |
12 | * Microkit bootloader
13 | * CapDL initialiser
14 | * Microkit library
15 | * Microkit monitor
16 | * Microkit tool
17 |
18 | The Microkit is distributed as a software development kit (SDK).
19 |
20 | This repository is the source for the Microkit SDK.
21 |
22 | If you are a system designer and want to *use* the Microkit SDK please download a pre-built SDK from
23 | [the latest release](https://github.com/seL4/microkit/releases).
24 |
25 | If you need help getting started see the [seL4 documentation website](https://docs.sel4.systems/projects/microkit/)
26 | as well as the manual in the SDK (`doc/manual.pdf`).
27 |
28 | If you are *developing* Microkit itself see [DEVELOPER.md](./DEVELOPER.md).
29 |
--------------------------------------------------------------------------------
/example/rust/support/targets/aarch64-sel4-microkit-minimal.json:
--------------------------------------------------------------------------------
1 | {
2 | "arch": "aarch64",
3 | "crt-objects-fallback": "false",
4 | "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
5 | "disable-redzone": true,
6 | "exe-suffix": ".elf",
7 | "features": "+v8a,+strict-align,+neon,+fp-armv8",
8 | "link-script": "__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;",
9 | "linker": "rust-lld",
10 | "linker-flavor": "gnu-lld",
11 | "llvm-target": "aarch64-unknown-none",
12 | "max-atomic-width": 128,
13 | "metadata": {
14 | "description": null,
15 | "host_tools": null,
16 | "std": null,
17 | "tier": null
18 | },
19 | "panic-strategy": "abort",
20 | "pre-link-args": {
21 | "gnu-lld": [
22 | "-z",
23 | "max-page-size=4096"
24 | ]
25 | },
26 | "relocation-model": "static",
27 | "stack-probes": {
28 | "kind": "inline"
29 | },
30 | "supported-sanitizers": [
31 | "kcfi",
32 | "kernel-address"
33 | ],
34 | "target-pointer-width": "64"
35 | }
36 |
--------------------------------------------------------------------------------
/loader/src/uart.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #if defined(CONFIG_PRINTING)
14 |
15 | void uart_init(void);
16 | void puts(const char *s);
17 | void puthex64(uint64_t val);
18 | void puthex32(uint32_t val);
19 | /* only 0-9 allowed */
20 | void putdecimal(uint8_t val);
21 |
22 | #define LDR_PRINT(lvl, cpu, msg) do { \
23 | puts("LDR|" lvl "|CPU"); \
24 | putdecimal(cpu); \
25 | puts(": " msg); \
26 | } while (0);
27 |
28 | #else
29 |
30 | static inline void uart_init(void) {}
31 | static inline void puts(const char *s) {}
32 | static inline void puthex64(uint64_t val) {}
33 | static inline void puthex32(uint32_t val) {}
34 | static inline void putdecimal(uint8_t val) {}
35 |
36 | #define LDR_PRINT(...) do { } while (0)
37 |
38 | #endif /* CONFIG_PRINTING */
39 |
--------------------------------------------------------------------------------
/example/setvar/setvar.system:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/loader/src/loader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #pragma once
9 |
10 | #define STACK_SIZE 4096
11 |
12 | #define REGION_TYPE_DATA 1
13 | #define REGION_TYPE_ZERO 2
14 |
15 | #ifndef __ASSEMBLER__
16 |
17 | #include
18 | #include
19 |
20 | #include "cpus.h"
21 |
22 |
23 | struct region {
24 | uintptr_t load_addr;
25 | uintptr_t size;
26 | uintptr_t offset;
27 | uintptr_t type;
28 | };
29 |
30 | struct loader_data {
31 | uintptr_t magic;
32 | uintptr_t size;
33 | uintptr_t kernel_entry;
34 | uintptr_t ui_p_reg_start;
35 | uintptr_t ui_p_reg_end;
36 | uintptr_t pv_offset;
37 | uintptr_t v_entry;
38 |
39 | uintptr_t num_regions;
40 | struct region regions[];
41 | };
42 |
43 | extern const struct loader_data *loader_data;
44 |
45 | /* Called from assembly */
46 | void relocation_failed(void);
47 | void relocation_log(uint64_t reloc_addr, uint64_t curr_addr);
48 |
49 | extern uint64_t _stack[NUM_ACTIVE_CPUS][STACK_SIZE / sizeof(uint64_t)];
50 |
51 | void start_kernel(int logical_cpu);
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/example/setvar/setvar.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | uint64_t mr_with_paddr_vaddr;
10 | uint64_t mr_with_paddr_paddr;
11 |
12 | uint64_t small_mr_no_paddr_paddr;
13 | uint64_t large_mr_no_paddr_paddr;
14 |
15 | uint64_t pl011_paddr;
16 |
17 | void init(void)
18 | {
19 | microkit_dbg_puts("Virtual address of 'mr_with_paddr': ");
20 | microkit_dbg_put32(mr_with_paddr_vaddr);
21 | microkit_dbg_puts("\n");
22 | microkit_dbg_puts("Physical address of 'mr_with_paddr': ");
23 | microkit_dbg_put32(mr_with_paddr_paddr);
24 | microkit_dbg_puts("\n");
25 |
26 | microkit_dbg_puts("Physical address of 'small_mr_no_paddr': ");
27 | microkit_dbg_put32(small_mr_no_paddr_paddr);
28 | microkit_dbg_puts("\n");
29 | microkit_dbg_puts("Physical address of 'large_mr_no_paddr': ");
30 | microkit_dbg_put32(large_mr_no_paddr_paddr);
31 | microkit_dbg_puts("\n");
32 |
33 | microkit_dbg_puts("Physical address of 'pl011_paddr': ");
34 | microkit_dbg_put32(pl011_paddr);
35 | microkit_dbg_puts("\n");
36 | }
37 |
38 | void notified(microkit_channel ch)
39 | {
40 | }
41 |
--------------------------------------------------------------------------------
/loader/src/cutil.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include "cutil.h"
9 |
10 | void *memcpy(void *dst, const void *src, size_t sz)
11 | {
12 | char *dst_ = dst;
13 | const char *src_ = src;
14 | while (sz-- > 0) {
15 | *dst_++ = *src_++;
16 | }
17 |
18 | return dst;
19 | }
20 |
21 | void *memmove(void *restrict dest, const void *restrict src, size_t n)
22 | {
23 | unsigned char *d = (unsigned char *)dest;
24 | const unsigned char *s = (const unsigned char *)src;
25 |
26 | /* no copying to do */
27 | if (d == s) {
28 | return dest;
29 | }
30 | /* for non-overlapping regions, just use memcpy */
31 | else if (s + n <= d || d + n <= s) {
32 | return memcpy(dest, src, n);
33 | }
34 | /* if copying from the start of s to the start of d, just use memcpy */
35 | else if (s > d) {
36 | return memcpy(dest, src, n);
37 | }
38 |
39 | /* copy from end of 's' to end of 'd' */
40 | size_t i;
41 | for (i = 1; i <= n; i++) {
42 | d[n - i] = s[n - i];
43 | }
44 |
45 | return dest;
46 | }
47 |
--------------------------------------------------------------------------------
/example/ethernet/foo.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | #define ECHO_CH 2
10 |
11 | volatile uint64_t *shared_counter = (uint64_t *)(uintptr_t)0x1800000;
12 |
13 | void
14 | init(void)
15 | {
16 | microkit_dbg_puts("foo: foo protection domain init function running\n");
17 | microkit_dbg_puts("foo: sending a notification\n");
18 | *shared_counter = 0x37;
19 | microkit_notify(ECHO_CH);
20 | microkit_dbg_puts("foo: sent a notification\n");
21 | }
22 |
23 | void
24 | notified(microkit_channel ch)
25 | {
26 | switch (ch) {
27 | case ECHO_CH:
28 | microkit_dbg_puts("foo: received notification on echo channel\n");
29 | if (*shared_counter == 0x38) {
30 | microkit_dbg_puts("foo: counter is expected value\n");
31 | } else {
32 | microkit_dbg_puts("foo: counter is unexpected value\n");
33 | }
34 |
35 | break;
36 |
37 | default:
38 | microkit_dbg_puts("foo: received notification on unexpected channel\n");
39 | break;
40 | /* ignore any other channels */
41 | }
42 | }
--------------------------------------------------------------------------------
/loader/src/aarch64/mmu.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include
9 |
10 | #include "el.h"
11 | #include "../arch.h"
12 | #include "../cutil.h"
13 | #include "../uart.h"
14 |
15 | void el1_mmu_enable(void);
16 | void el2_mmu_enable(void);
17 |
18 | /* Paging structures for kernel mapping */
19 | uint64_t boot_lvl0_upper[1 << 9] ALIGN(1 << 12);
20 | uint64_t boot_lvl1_upper[1 << 9] ALIGN(1 << 12);
21 | uint64_t boot_lvl2_upper[1 << 9] ALIGN(1 << 12);
22 |
23 | /* Paging structures for identity mapping */
24 | uint64_t boot_lvl0_lower[1 << 9] ALIGN(1 << 12);
25 | uint64_t boot_lvl1_lower[1 << 9] ALIGN(1 << 12);
26 |
27 | int arch_mmu_enable(int logical_cpu)
28 | {
29 | int r;
30 | enum el el;
31 | r = ensure_correct_el(logical_cpu);
32 | if (r != 0) {
33 | return r;
34 | }
35 |
36 | LDR_PRINT("INFO", logical_cpu, "enabling MMU\n");
37 | el = current_el();
38 | if (el == EL1) {
39 | el1_mmu_enable();
40 | } else if (el == EL2) {
41 | el2_mmu_enable();
42 | } else {
43 | LDR_PRINT("ERROR", logical_cpu, "unknown EL for MMU enable\n");
44 | }
45 |
46 | return 0;
47 | }
48 |
--------------------------------------------------------------------------------
/LICENSES/BSD-2-Clause.txt:
--------------------------------------------------------------------------------
1 | Copyright (c)
2 |
3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 |
5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 |
7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 |
9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10 |
--------------------------------------------------------------------------------
/loader/src/riscv/init.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include "../arch.h"
9 | #include "../cpus.h"
10 | #include "../loader.h"
11 | #include "../uart.h"
12 |
13 | #include
14 |
15 | void arch_init(void)
16 | {
17 | puts("LDR|INFO: configured with FIRST_HART_ID ");
18 | puthex32(CONFIG_FIRST_HART_ID);
19 | puts("\n");
20 | }
21 |
22 | typedef void (*sel4_entry)(
23 | uintptr_t ui_p_reg_start,
24 | uintptr_t ui_p_reg_end,
25 | intptr_t pv_offset,
26 | uintptr_t v_entry,
27 | uintptr_t dtb_addr_p,
28 | uintptr_t dtb_size
29 | #if defined(CONFIG_ENABLE_SMP_SUPPORT)
30 | ,
31 | uint64_t hart_id,
32 | uint64_t core_id
33 | #endif
34 | );
35 |
36 | void arch_jump_to_kernel(int logical_cpu)
37 | {
38 | #if defined(CONFIG_ENABLE_SMP_SUPPORT)
39 | uint64_t hart_id = plat_get_hw_id(logical_cpu);
40 | #endif
41 |
42 | ((sel4_entry)(loader_data->kernel_entry))(
43 | loader_data->ui_p_reg_start,
44 | loader_data->ui_p_reg_end,
45 | loader_data->pv_offset,
46 | loader_data->v_entry,
47 | 0,
48 | 0
49 | #if defined(CONFIG_ENABLE_SMP_SUPPORT)
50 | ,
51 | hart_id,
52 | logical_cpu
53 | #endif
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/loader/src/riscv/mmu.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include
9 |
10 | #include "../arch.h"
11 | #include "../cutil.h"
12 |
13 | /* Paging structures for kernel mapping */
14 | uint64_t boot_lvl1_pt[1 << 9] ALIGN(1 << 12);
15 | uint64_t boot_lvl2_pt[1 << 9] ALIGN(1 << 12);
16 | /* Paging structures for identity mapping */
17 | uint64_t boot_lvl2_pt_elf[1 << 9] ALIGN(1 << 12);
18 |
19 |
20 | /*
21 | * This is the encoding for the MODE field of the satp register when
22 | * implementing 39-bit virtual address spaces (known as Sv39).
23 | */
24 | #define VM_MODE (0x8llu << 60)
25 |
26 | #define RISCV_PGSHIFT 12
27 |
28 | int arch_mmu_enable(int logical_cpu)
29 | {
30 | // The RISC-V privileged spec (20211203), section 4.1.11 says that the
31 | // SFENCE.VMA instruction may need to be executed before or after writing
32 | // to satp. I don't understand why we do it before compared to after.
33 | // Need to understand 4.2.1 of the spec.
34 | asm volatile("sfence.vma" ::: "memory");
35 | asm volatile(
36 | "csrw satp, %0\n"
37 | :
38 | : "r"(VM_MODE | (uintptr_t)boot_lvl1_pt >> RISCV_PGSHIFT)
39 | :
40 | );
41 | asm volatile("fence.i" ::: "memory");
42 |
43 | return 0;
44 | }
45 |
--------------------------------------------------------------------------------
/loader/src/cpus.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | /* Define our own variant of the seL4 config */
15 | #define NUM_ACTIVE_CPUS CONFIG_MAX_NUM_NODES
16 |
17 | /**
18 | * This is the number of cores that we are going to boot seL4 with,
19 | * i.e. the active configuration.
20 | *
21 | * NUM_ACTIVE_CPUS is passed by the build system and can be used where
22 | * compile-time constants in C are needed.
23 | **/
24 | const inline int plat_get_active_cpus(void)
25 | {
26 | return NUM_ACTIVE_CPUS;
27 | }
28 |
29 | /**
30 | * This is the number of cores that the platform actually has.
31 | **/
32 | const int plat_get_available_cpus(void);
33 |
34 | /**
35 | * Tell the platform specific code about the hardware ID corresponding
36 | * to the logical ID.
37 | * This will often be MPIDR on ARM.
38 | **/
39 | void plat_save_hw_id(int logical_cpu, size_t hw_id);
40 |
41 | /**
42 | * Get the hardware ID from a logical ID from platform specific code
43 | **/
44 | size_t plat_get_hw_id(int logical_cpu);
45 |
46 | /**
47 | * Start the CPU with the given logical ID.
48 | * Returns a non-zero integer on failure.
49 | * Note this logical_cpu is the *target* CPU.
50 | **/
51 | int plat_start_cpu(int logical_cpu);
52 |
--------------------------------------------------------------------------------
/libmicrokit/src/dbg.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 |
8 | #define __thread
9 | #include
10 |
11 | void microkit_dbg_putc(int c)
12 | {
13 | #if defined(CONFIG_PRINTING)
14 | seL4_DebugPutChar(c);
15 | #endif
16 | }
17 |
18 |
19 |
20 | void microkit_dbg_puts(const char *s)
21 | {
22 | while (*s) {
23 | microkit_dbg_putc(*s);
24 | s++;
25 | }
26 | }
27 |
28 | void microkit_dbg_put8(seL4_Uint8 x)
29 | {
30 | char tmp[4];
31 | unsigned i = 3;
32 | tmp[3] = 0;
33 | do {
34 | seL4_Uint8 c = x % 10;
35 | tmp[--i] = '0' + c;
36 | x /= 10;
37 | } while (x);
38 | microkit_dbg_puts(&tmp[i]);
39 | }
40 |
41 | void microkit_dbg_put32(seL4_Uint32 x)
42 | {
43 | char tmp[11];
44 | unsigned i = 10;
45 | tmp[10] = 0;
46 | do {
47 | seL4_Uint8 c = x % 10;
48 | tmp[--i] = '0' + c;
49 | x /= 10;
50 | } while (x);
51 | microkit_dbg_puts(&tmp[i]);
52 | }
53 |
54 | void __assert_fail(const char *str, const char *file, int line, const char *function)
55 | {
56 | microkit_dbg_puts("assert failed: ");
57 | microkit_dbg_puts(str);
58 | microkit_dbg_puts(" ");
59 | microkit_dbg_puts(file);
60 | microkit_dbg_puts(" ");
61 | microkit_dbg_puts(function);
62 | microkit_dbg_puts("\n");
63 | }
64 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
6 |
7 | # Contributions Welcome
8 |
9 | Please see the [seL4 contributing guidelines][1] on the [seL4 website][2] for
10 | details.
11 |
12 | [1]: https://docs.sel4.systems/processes/contributing.html
13 | [2]: https://sel4.systems
14 |
15 |
16 | ## Contact
17 |
18 | If you have larger changes or additions, it is a good idea to get in contact
19 | with us as , so we can help you get started.
20 |
21 | The people responsible for the technical direction, procedures, and quality
22 | control are the [Technical Steering Committee][3] (TSC) of the seL4
23 | foundation. You can contact them either on the developer mailing list or on
24 | directly via email available from their profile pages.
25 |
26 | [3]: https://sel4.systems/Foundation/TSC
27 |
28 |
29 | ## Developer Certificate of Origin (DCO)
30 |
31 | This repository uses the same sign-off process as the Linux kernel. For every
32 | commit, use
33 |
34 | git commit -s
35 |
36 | to add a sign-off line to your commit message, which will come out as:
37 |
38 | Signed-off-by: name
39 |
40 | By adding this line, you make the declaration that you have the right to make
41 | this contribution under the open source license the files use that you changed
42 | or contributed.
43 |
44 | The full text of the declaration is at .
45 |
--------------------------------------------------------------------------------
/.github/workflows/pr.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
2 | #
3 | # SPDX-License-Identifier: BSD-2-Clause
4 |
5 | # Actions to run on pull requests
6 |
7 | name: PR
8 |
9 | on: [pull_request, workflow_dispatch]
10 |
11 | jobs:
12 | pr-checks:
13 | name: Checks
14 | uses: seL4/ci-actions/.github/workflows/pr.yml@master
15 |
16 | clippy_check:
17 | runs-on: ubuntu-latest
18 | # Make sure CI fails on all warnings, including Clippy lints
19 | env:
20 | RUSTFLAGS: "-Dwarnings"
21 | steps:
22 | - uses: actions/checkout@v4
23 | - uses: actions/cache@v3
24 | with:
25 | path: |
26 | ~/.cargo/bin/
27 | ~/.cargo/registry/index/
28 | ~/.cargo/registry/cache/
29 | ~/.cargo/git/db/
30 | target/
31 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
32 | - name: Run Clippy
33 | run: cd tool/microkit && cargo clippy --all-targets --all-features
34 |
35 | rustfmt_check:
36 | runs-on: ubuntu-latest
37 | steps:
38 | - uses: actions/checkout@v4
39 | - uses: actions/cache@v3
40 | with:
41 | path: |
42 | ~/.cargo/bin/
43 | ~/.cargo/registry/index/
44 | ~/.cargo/registry/cache/
45 | ~/.cargo/git/db/
46 | target/
47 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
48 | - name: Run rustfmt
49 | run: cd tool/microkit && cargo fmt --check
50 |
--------------------------------------------------------------------------------
/loader/src/riscv/sbi.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #pragma once
8 |
9 | #define SBI_BASE_EID 0x10
10 | #define SBI_HSM_EID 0x48534DULL
11 | #define SBI_DEBUG_CONSOLE_EID 0x4442434E
12 |
13 | /* SBI commands for the base extension */
14 | #define SBI_BASE_PROBE_EXT_FID 3
15 |
16 | /* SBI commands for the HSM extension */
17 | #define SBI_HSM_HART_START_FID 0
18 | #define SBI_HSM_HART_STOP_FID 1
19 |
20 | /* SBI commands for the DEBUG_CONSOLE extension */
21 | #define SBI_DEBUG_CONSOLE_WRITE_BYTE_FID 0x2
22 |
23 | #ifndef __ASSEMBLER__
24 |
25 | #include
26 | #include
27 |
28 | struct sbi_ret {
29 | uint64_t error;
30 | uint64_t value;
31 | };
32 |
33 | enum sbi_error {
34 | SBI_SUCCESS = 0,
35 | SBI_ERR_FAILED = -1,
36 | SBI_ERR_NOT_SUPPORTED = -2,
37 | SBI_ERR_INVALID_PARAM = -3,
38 | SBI_ERR_DENIED = -4,
39 | SBI_ERR_INVALID_ADDRESS = -5,
40 | SBI_ERR_ALREADY_AVAILABLE = -6,
41 | SBI_ERR_ALREADY_STARTED = -7,
42 | SBI_ERR_ALREADY_STOPPED = -8,
43 | SBI_ERR_NO_SHMEM = -9,
44 | SBI_ERR_INVALID_STATE = -10,
45 | SBI_ERR_BAD_RANGE = -11,
46 | SBI_ERR_TIMEOUT = -12,
47 | SBI_ERR_IO = -13,
48 | SBI_ERR_DENIED_LOCKED = -14,
49 | };
50 |
51 | struct sbi_ret sbi_call(uint64_t eid, uint64_t fid, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3,
52 | uint64_t arg4, uint64_t arg5);
53 | char *sbi_error_as_string(long error);
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/libmicrokit/microkit.ld:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | PHDRS
7 | {
8 | text PT_LOAD;
9 | data PT_LOAD;
10 | }
11 |
12 | ENTRY(_start);
13 |
14 | SECTIONS
15 | {
16 | . = 0x200000;
17 |
18 | .text :
19 | {
20 | _text = .;
21 | *(.text.start)
22 | *(.text*)
23 | *(.rodata)
24 | _text_end = .;
25 | } :text
26 |
27 | . = ALIGN(0x1000);
28 |
29 | /* For some reason the ABI puts init array
30 | * into writable memory, so we have to follow suit */
31 | .init_array :
32 | {
33 | PROVIDE(__init_array_start = .);
34 | KEEP (*(SORT(.init_array.*)))
35 | KEEP (*(.init_array*))
36 | PROVIDE(__init_array_end = .);
37 | } :data
38 |
39 | .data.rel.ro :
40 | {
41 | . = ALIGN(8);
42 | __data_rel_ro_start = .;
43 | *(.data.rel.ro.local*) *(.data.rel.ro*) *(.data.rel*)
44 | __data_rel_ro_end = .;
45 | . = ALIGN(8);
46 | } :data
47 |
48 | .data :
49 | {
50 | _data = .;
51 | *(.data)
52 | . = ALIGN(8);
53 | __global_pointer$ = . + 0x800;
54 | *(.srodata)
55 | *(.sdata)
56 | _data_end = .;
57 | } :data
58 |
59 | .bss :
60 | {
61 | _bss = .;
62 | *(.sbss)
63 | *(.bss)
64 | *(.bss*)
65 | *(COMMON)
66 | . = ALIGN(4);
67 | _bss_end = .;
68 | } :data
69 |
70 | . = ALIGN(0x1000);
71 | .ipc_buffer (NOLOAD): {
72 | __sel4_ipc_buffer_obj = .;
73 | } :NONE
74 | }
75 |
--------------------------------------------------------------------------------
/example/hierarchy/restarter.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 |
9 | static uint8_t restart_count = 0;
10 |
11 | static char decchar(unsigned int v)
12 | {
13 | return '0' + v;
14 | }
15 |
16 | static void put8(uint8_t x)
17 | {
18 | char tmp[4];
19 | unsigned i = 3;
20 | tmp[3] = 0;
21 | do {
22 | uint8_t c = x % 10;
23 | tmp[--i] = decchar(c);
24 | x /= 10;
25 | } while (x);
26 | microkit_dbg_puts(&tmp[i]);
27 | }
28 |
29 | void init(void)
30 | {
31 | microkit_dbg_puts("restarter: starting\n");
32 | }
33 |
34 | void notified(microkit_channel ch)
35 | {
36 | }
37 |
38 | seL4_MessageInfo_t protected(microkit_channel ch, microkit_msginfo msginfo)
39 | {
40 | microkit_dbg_puts("restarter: received protected message\n");
41 |
42 | return microkit_msginfo_new(0, 0);
43 | }
44 |
45 | seL4_Bool fault(microkit_child child, microkit_msginfo msginfo, microkit_msginfo *reply_msginfo)
46 | {
47 | microkit_dbg_puts("restarter: received fault message for child pd: ");
48 | put8(child);
49 | microkit_dbg_puts("\n");
50 | restart_count++;
51 | if (restart_count < 10) {
52 | microkit_pd_restart(child, 0x200000);
53 | microkit_dbg_puts("restarter: restarted\n");
54 | } else {
55 | microkit_pd_stop(child);
56 | microkit_dbg_puts("restarter: too many restarts - PD stopped\n");
57 | }
58 |
59 | /* We explicitly restart the thread so we do not need to 'reply' to the fault. */
60 | return seL4_False;
61 | }
62 |
--------------------------------------------------------------------------------
/loader/src/arch.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #pragma once
8 |
9 | /**
10 | * The layout and naming scheme of the functions in these files has meaning:
11 | *
12 | * - Functions that start with `arch_`, as specified within `arch.h`, e.g.
13 | * `arch_mmu_enable`, conform to a common interface across all architectures.
14 | * Code for these functions belongs in the architecture-specific subdirectory.
15 | *
16 | * - Functions that start with `plat_` are platform/board specific, conforming
17 | * to a common interface. This is useful for code such as CPU on/offlining.
18 | * This needs to be called from common code, but has details that are arch
19 | * and/or platform specific.
20 | *
21 | * - Functions starting with `arm_` or `riscv_` correspond to architecture-specific
22 | * code that is *not* expected to conform to a common interface. For instance
23 | * `arm_secondary_cpu_entry` is prefixed as such because it needs to do ARM
24 | * specific functions and is called by an ARM-specific convention.
25 | *
26 | * - Remaining functions are somewhat of a grab bag; some code in the non-arch-
27 | * specific files are for code common between all architectures, but these
28 | * also contain architecture specific code, depending.
29 | * Also, the UART code is not prefixed with `plat_` even though it conceptually
30 | * could be that way, simply because it makes function calls more verbose,
31 | * and UART is obviously platform specific.
32 | */
33 |
34 | void arch_init(void);
35 | void arch_set_exception_handler(void);
36 | int arch_mmu_enable(int logical_cpu);
37 | void arch_jump_to_kernel(int logical_cpu);
38 |
--------------------------------------------------------------------------------
/example/setvar/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2025, UNSW.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
23 |
24 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
25 |
26 | ifeq ($(ARCH),aarch64)
27 | TOOLCHAIN := aarch64-none-elf
28 | # No specific AArch64 flags
29 | CFLAGS_ARCH :=
30 | else
31 | $(error Unsupported ARCH)
32 | endif
33 |
34 | CC := $(TOOLCHAIN)-gcc
35 | LD := $(TOOLCHAIN)-ld
36 | AS := $(TOOLCHAIN)-as
37 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
38 |
39 | SETVAR_OBJS := setvar.o
40 |
41 | IMAGES := setvar.elf
42 | CFLAGS := -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
43 | LDFLAGS := -L$(BOARD_DIR)/lib
44 | LIBS := -lmicrokit -Tmicrokit.ld
45 |
46 | IMAGE_FILE = $(BUILD_DIR)/loader.img
47 | REPORT_FILE = $(BUILD_DIR)/report.txt
48 |
49 | all: $(IMAGE_FILE)
50 |
51 | $(BUILD_DIR)/%.o: %.c Makefile
52 | $(CC) -c $(CFLAGS) $< -o $@
53 |
54 | $(BUILD_DIR)/setvar.elf: $(addprefix $(BUILD_DIR)/, $(SETVAR_OBJS))
55 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
56 |
57 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) setvar.system
58 | $(MICROKIT_TOOL) setvar.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
59 |
--------------------------------------------------------------------------------
/example/arm_smc/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2025, UNSW.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
23 |
24 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
25 |
26 | ifeq ($(ARCH),aarch64)
27 | TOOLCHAIN := aarch64-none-elf
28 | # No specific AArch64 flags
29 | CFLAGS_ARCH :=
30 | else
31 | $(error Unsupported ARCH)
32 | endif
33 |
34 | CC := $(TOOLCHAIN)-gcc
35 | LD := $(TOOLCHAIN)-ld
36 | AS := $(TOOLCHAIN)-as
37 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
38 |
39 | ARM_SMC_OBJS := arm_smc.o
40 |
41 | IMAGES := arm_smc.elf
42 | CFLAGS := -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
43 | LDFLAGS := -L$(BOARD_DIR)/lib
44 | LIBS := -lmicrokit -Tmicrokit.ld
45 |
46 | IMAGE_FILE = $(BUILD_DIR)/loader.img
47 | REPORT_FILE = $(BUILD_DIR)/report.txt
48 |
49 | all: $(IMAGE_FILE)
50 |
51 | $(BUILD_DIR)/%.o: %.c Makefile
52 | $(CC) -c $(CFLAGS) $< -o $@
53 |
54 | $(BUILD_DIR)/arm_smc.elf: $(addprefix $(BUILD_DIR)/, $(ARM_SMC_OBJS))
55 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
56 |
57 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) arm_smc.system
58 | $(MICROKIT_TOOL) arm_smc.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
59 |
--------------------------------------------------------------------------------
/tool/microkit/src/capdl/packaging.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | use crate::{
8 | capdl::{initialiser::CapDLInitialiser, CapDLSpecContainer},
9 | elf::ElfFile,
10 | sel4::{Config, PageSize},
11 | };
12 |
13 | pub fn pack_spec_into_initial_task(
14 | sel4_config: &Config,
15 | build_config: &str,
16 | spec_container: &CapDLSpecContainer,
17 | system_elfs: &[ElfFile],
18 | capdl_initialiser: &mut CapDLInitialiser,
19 | ) {
20 | let compress_frames = true;
21 | let embed_frames = true;
22 |
23 | let (mut output_spec, embedded_frame_data_list) = spec_container.spec.embed_fill(
24 | PageSize::Small.fixed_size_bits(sel4_config) as u8,
25 | |_| embed_frames,
26 | |d, buf| {
27 | buf.copy_from_slice(
28 | &system_elfs[d.elf_id].segments[d.elf_seg_idx].data()[d.elf_seg_data_range.clone()],
29 | );
30 | compress_frames
31 | },
32 | );
33 |
34 | let embedded_frame_data = embedded_frame_data_list
35 | .into_iter()
36 | .flatten()
37 | .collect::>();
38 |
39 | for named_obj in output_spec.objects.iter_mut() {
40 | match build_config {
41 | "smp-debug" | "debug" => {}
42 | // We don't copy over the object names as there is no debug printing in these configuration to save memory.
43 | "release" | "benchmark" | "smp-release" | "smp-benchmark" => named_obj.name = None,
44 | _ => panic!("unknown configuration {build_config}"),
45 | };
46 | }
47 |
48 | output_spec.cache_orig_cap_slots();
49 |
50 | output_spec.set_log_level(capdl_initialiser.log_level as u8);
51 |
52 | let initialiser_payload = output_spec.to_bytes().unwrap();
53 |
54 | capdl_initialiser.add_spec(initialiser_payload, embedded_frame_data);
55 | }
56 |
--------------------------------------------------------------------------------
/example/timer/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | ifneq ($(MICROKIT_BOARD),odroidc4)
23 | $(error Unsupported MICROKIT_BOARD given, only odroidc4 supported)
24 | endif
25 |
26 | TARGET_TRIPLE := aarch64-none-elf
27 |
28 | CPU := cortex-a55
29 |
30 | ifeq ($(strip $(LLVM)),True)
31 | CC := clang -target $(TARGET_TRIPLE)
32 | AS := clang -target $(TARGET_TRIPLE)
33 | LD := ld.lld
34 | else
35 | CC := $(TARGET_TRIPLE)-gcc
36 | LD := $(TARGET_TRIPLE)-ld
37 | AS := $(TARGET_TRIPLE)-as
38 | endif
39 |
40 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
41 |
42 | TIMER_OBJS := timer.o
43 |
44 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
45 |
46 | IMAGES := timer.elf
47 | CFLAGS := -mcpu=$(CPU) -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include
48 | LDFLAGS := -L$(BOARD_DIR)/lib
49 | LIBS := -lmicrokit -Tmicrokit.ld
50 |
51 | IMAGE_FILE = $(BUILD_DIR)/loader.img
52 | REPORT_FILE = $(BUILD_DIR)/report.txt
53 |
54 | all: $(IMAGE_FILE)
55 |
56 | $(BUILD_DIR)/%.o: %.c Makefile
57 | $(CC) -c $(CFLAGS) $< -o $@
58 |
59 | $(BUILD_DIR)/%.o: %.s Makefile
60 | $(AS) -g -mcpu=$(CPU) $< -o $@
61 |
62 | $(BUILD_DIR)/timer.elf: $(addprefix $(BUILD_DIR)/, $(TIMER_OBJS))
63 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
64 |
65 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) timer.system
66 | $(MICROKIT_TOOL) timer.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
67 |
--------------------------------------------------------------------------------
/libmicrokit/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(ARCH)),)
11 | $(error ARCH must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(TARGET_TRIPLE)),)
15 | $(error TARGET_TRIPLE must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(LLVM)),True)
19 | CC := clang -target $(TARGET_TRIPLE)
20 | CPP := clang-cpp -target $(TARGET_TRIPLE)
21 | AS := clang -target $(TARGET_TRIPLE)
22 | LD := ld.lld
23 | AR := llvm-ar
24 | CFLAGS_TOOLCHAIN :=
25 | else
26 | CC = $(TARGET_TRIPLE)-gcc
27 | CPP = $(TARGET_TRIPLE)-cpp
28 | AS = $(TARGET_TRIPLE)-as
29 | LD = $(TARGET_TRIPLE)-ld
30 | AR = $(TARGET_TRIPLE)-ar
31 | CFLAGS_TOOLCHAIN := -Wno-maybe-uninitialized
32 | endif
33 |
34 | ifeq ($(ARCH),aarch64)
35 | ASM_FLAGS := -mcpu=$(GCC_CPU)
36 | CFLAGS_AARCH64 := -mcpu=$(GCC_CPU)
37 | CFLAGS_ARCH := $(CFLAGS_AARCH64)
38 | ARCH_DIR := aarch64
39 | else ifeq ($(ARCH),riscv64)
40 | ASM_FLAGS := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
41 | CFLAGS_RISCV64 := -mcmodel=medany -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
42 | CFLAGS_ARCH := $(CFLAGS_RISCV64)
43 | ARCH_DIR := riscv
44 | else ifeq ($(ARCH),x86_64)
45 | CFLAGS_ARCH := -march=x86-64 -mtune=$(GCC_CPU)
46 | ASM_FLAGS := -march=generic64
47 | ARCH_DIR := x86_64
48 | endif
49 |
50 | CFLAGS := -std=gnu11 \
51 | -g -O3 -nostdlib \
52 | -ffreestanding \
53 | -Wall $(CFLAGS_TOOLCHAIN) \
54 | -Wno-unused-function -Werror \
55 | -Iinclude -I$(SEL4_SDK)/include \
56 | $(CFLAGS_ARCH)
57 |
58 | LIBS := libmicrokit.a
59 | OBJS := main.o crt0.o dbg.o
60 |
61 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.S
62 | $(CC) -x assembler-with-cpp -c $(CFLAGS) $< -o $@
63 |
64 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.s
65 | $(AS) -c -g $(ASM_FLAGS) $< -o $@
66 |
67 | $(BUILD_DIR)/%.o : src/%.c
68 | $(CC) -c $(CFLAGS) $< -o $@
69 |
70 | LIB = $(addprefix $(BUILD_DIR)/, $(LIBS))
71 |
72 | all: $(LIB)
73 |
74 | $(LIB): $(addprefix $(BUILD_DIR)/, $(OBJS))
75 | $(AR) -crv $@ $^
76 |
--------------------------------------------------------------------------------
/example/rust/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2023, Colias Group, LLC
3 | # Copyright 2025, UNSW
4 | #
5 | # SPDX-License-Identifier: BSD-2-Clause
6 | #
7 |
8 | ifeq ($(strip $(BUILD_DIR)),)
9 | $(error BUILD_DIR must be specified)
10 | endif
11 |
12 | ifeq ($(strip $(MICROKIT_SDK)),)
13 | $(error MICROKIT_SDK must be specified)
14 | endif
15 |
16 | ifeq ($(strip $(MICROKIT_BOARD)),)
17 | $(error MICROKIT_BOARD must be specified)
18 | endif
19 |
20 | ifeq ($(strip $(MICROKIT_CONFIG)),)
21 | $(error MICROKIT_CONFIG must be specified)
22 | endif
23 |
24 | IMAGE_FILE = $(BUILD_DIR)/loader.img
25 | REPORT_FILE = $(BUILD_DIR)/report.txt
26 | SYSTEM_FILE := rust.system
27 |
28 | all: $(IMAGE_FILE)
29 |
30 | .PHONY: clean
31 | clean:
32 | rm -rf $(BUILD_DIR)
33 |
34 | $(BUILD_DIR):
35 | mkdir -p $@
36 |
37 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
38 | SEL4_INCLUDE_DIRS := $(BOARD_DIR)/include
39 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
40 |
41 | ifeq ($(ARCH),aarch64)
42 | RUST_TARGET := aarch64-sel4-microkit-minimal
43 | else ifeq ($(ARCH),riscv64)
44 | RUST_TARGET := riscv64gc-sel4-microkit-minimal
45 | else
46 | $(error Unsupported ARCH)
47 | endif
48 |
49 | crate = $(BUILD_DIR)/$(1).elf
50 |
51 | define build_crate
52 |
53 | $(crate): $(crate).intermediate
54 |
55 | .INTERMDIATE: $(crate).intermediate
56 | $(crate).intermediate:
57 | SEL4_INCLUDE_DIRS=$(abspath $(SEL4_INCLUDE_DIRS)) \
58 | cargo build \
59 | -Z build-std=core,alloc,compiler_builtins \
60 | -Z build-std-features=compiler-builtins-mem \
61 | --target-dir $(BUILD_DIR)/target \
62 | --out-dir $(BUILD_DIR) \
63 | --target $(RUST_TARGET) \
64 | --release \
65 | -p $(1)
66 |
67 | endef
68 |
69 | CRATE_NAMES := hello
70 |
71 | CRATES := $(foreach CRATE_NAME,$(CRATE_NAMES),$(call crate,$(CRATE_NAME)))
72 |
73 | $(eval $(foreach CRATE_NAME,$(CRATE_NAMES),$(call build_crate,$(CRATE_NAME))))
74 |
75 | $(IMAGE_FILE): $(SYSTEM_FILE) $(CRATES)
76 | $(MICROKIT_SDK)/bin/microkit \
77 | $< \
78 | --search-path $(BUILD_DIR) \
79 | --board $(MICROKIT_BOARD) \
80 | --config $(MICROKIT_CONFIG) \
81 | -r $(BUILD_DIR)/report.txt \
82 | -o $@
83 |
--------------------------------------------------------------------------------
/example/hello/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
23 |
24 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
25 |
26 | ifeq ($(ARCH),aarch64)
27 | TARGET_TRIPLE := aarch64-none-elf
28 | CFLAGS_ARCH := -mstrict-align
29 | else ifeq ($(ARCH),riscv64)
30 | TARGET_TRIPLE := riscv64-unknown-elf
31 | CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
32 | else ifeq ($(ARCH),x86_64)
33 | TARGET_TRIPLE := x86_64-linux-gnu
34 | CFLAGS_ARCH := -march=x86-64 -mtune=generic
35 | else
36 | $(error Unsupported ARCH)
37 | endif
38 |
39 | ifeq ($(strip $(LLVM)),True)
40 | CC := clang -target $(TARGET_TRIPLE)
41 | AS := clang -target $(TARGET_TRIPLE)
42 | LD := ld.lld
43 | else
44 | CC := $(TARGET_TRIPLE)-gcc
45 | LD := $(TARGET_TRIPLE)-ld
46 | AS := $(TARGET_TRIPLE)-as
47 | endif
48 |
49 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
50 |
51 | HELLO_OBJS := hello.o
52 |
53 | IMAGES := hello.elf
54 | CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
55 | LDFLAGS := -L$(BOARD_DIR)/lib
56 | LIBS := -lmicrokit -Tmicrokit.ld
57 |
58 | IMAGE_FILE = $(BUILD_DIR)/loader.img
59 | REPORT_FILE = $(BUILD_DIR)/report.txt
60 |
61 | all: $(IMAGE_FILE)
62 |
63 | $(BUILD_DIR)/%.o: %.c Makefile
64 | $(CC) -c $(CFLAGS) $< -o $@
65 |
66 | $(BUILD_DIR)/hello.elf: $(addprefix $(BUILD_DIR)/, $(HELLO_OBJS))
67 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
68 |
69 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) hello.system
70 | $(MICROKIT_TOOL) hello.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
71 |
--------------------------------------------------------------------------------
/example/ethernet/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | ifneq ($(MICROKIT_BOARD),tqma8xqp1gb)
23 | $(error Unsupported MICROKIT_BOARD given, only tqma8xqp1gb supported)
24 | endif
25 |
26 | TARGET_TRIPLE := aarch64-none-elf
27 |
28 | CPU := cortex-a35
29 |
30 | ifeq ($(strip $(LLVM)),True)
31 | CC := clang -target $(TARGET_TRIPLE)
32 | AS := clang -target $(TARGET_TRIPLE)
33 | LD := ld.lld
34 | else
35 | CC := $(TARGET_TRIPLE)-gcc
36 | LD := $(TARGET_TRIPLE)-ld
37 | AS := $(TARGET_TRIPLE)-as
38 | endif
39 |
40 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
41 |
42 | ETH_OBJS := eth.o
43 | PASS_OBJS := pass.o
44 | GPT_OBJS := gpt.o
45 |
46 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
47 |
48 | IMAGES := eth.elf pass.elf gpt.elf
49 | CFLAGS := -mcpu=$(CPU) -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include
50 | LDFLAGS := -L$(BOARD_DIR)/lib
51 | LIBS := -lmicrokit -Tmicrokit.ld
52 |
53 | IMAGE_FILE = $(BUILD_DIR)/loader.img
54 | REPORT_FILE = $(BUILD_DIR)/report.txt
55 |
56 | all: $(IMAGE_FILE)
57 |
58 | $(BUILD_DIR)/%.o: %.c Makefile
59 | $(CC) -c $(CFLAGS) $< -o $@
60 |
61 | $(BUILD_DIR)/%.o: %.s Makefile
62 | $(AS) -g -mcpu=$(CPU) $< -o $@
63 |
64 | $(BUILD_DIR)/eth.elf: $(addprefix $(BUILD_DIR)/, $(ETH_OBJS))
65 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
66 |
67 | $(BUILD_DIR)/pass.elf: $(addprefix $(BUILD_DIR)/, $(PASS_OBJS))
68 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
69 |
70 | $(BUILD_DIR)/gpt.elf: $(addprefix $(BUILD_DIR)/, $(GPT_OBJS))
71 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
72 |
73 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) ethernet.system
74 | $(MICROKIT_TOOL) ethernet.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
75 |
--------------------------------------------------------------------------------
/loader/src/aarch64/exceptions.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include "exceptions.h"
9 |
10 | #include
11 |
12 | #include "el.h"
13 | #include "../arch.h"
14 | #include "../cutil.h"
15 | #include "../loader.h"
16 | #include "../uart.h"
17 |
18 | extern char arm_vector_table[1];
19 |
20 |
21 | void arch_set_exception_handler(void)
22 | {
23 | enum el el = current_el();
24 | if (el == EL2) {
25 | asm volatile("msr vbar_el2, %0" :: "r"(arm_vector_table));
26 | }
27 | /* Since we call the exception handler before we check we're at
28 | * a valid EL we shouldn't assume we are at EL1 or higher. */
29 | if (el != EL0) {
30 | asm volatile("msr vbar_el1, %0" :: "r"(arm_vector_table));
31 | }
32 | }
33 |
34 | uintptr_t exception_register_state[32];
35 |
36 | void exception_handler(uintptr_t ex)
37 | {
38 | /* Read ESR/FSR based on the exception level we're at. */
39 | uint64_t esr;
40 | uintptr_t far;
41 |
42 | if (is_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
43 | asm volatile("mrs %0, ESR_EL2" : "=r"(esr) :: "cc");
44 | asm volatile("mrs %0, FAR_EL2" : "=r"(far) :: "cc");
45 | } else {
46 | asm volatile("mrs %0, ESR_EL1" : "=r"(esr) :: "cc");
47 | asm volatile("mrs %0, FAR_EL1" : "=r"(far) :: "cc");
48 | }
49 |
50 | uintptr_t ec = (esr >> 26) & 0x3f;
51 | puts("\nLDR|ERROR: loader trapped exception: ");
52 | puts(ex_to_string(ex));
53 | if (is_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
54 | puts("\n esr_el2: ");
55 | } else {
56 | puts("\n esr_el1: ");
57 | }
58 | puthex64(esr);
59 | puts("\n ec: ");
60 | puthex32(ec);
61 | puts(" (");
62 | puts(ec_to_string(ec));
63 | puts(")\n il: ");
64 | puthex64((esr >> 25) & 1);
65 | puts("\n iss: ");
66 | puthex64(esr & MASK(24));
67 | puts("\n far: ");
68 | puthex64(far);
69 | puts("\n");
70 |
71 | for (unsigned i = 0; i < 32; i++) {
72 | puts(" reg: ");
73 | puthex32(i);
74 | puts(": ");
75 | puthex64(exception_register_state[i]);
76 | puts("\n");
77 | }
78 |
79 | for (;;) {
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/monitor/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(ARCH)),)
11 | $(error ARCH must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(TARGET_TRIPLE)),)
15 | $(error TARGET_TRIPLE must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(LLVM)),True)
19 | CC = clang -target $(TARGET_TRIPLE)
20 | CPP = clang-cpp -target $(TARGET_TRIPLE)
21 | AS = clang -target $(TARGET_TRIPLE)
22 | LD = ld.lld
23 | AR = llvm-ar
24 | CFLAGS_TOOLCHAIN :=
25 | else
26 | CC = $(TARGET_TRIPLE)-gcc
27 | CPP = $(TARGET_TRIPLE)-cpp
28 | AS = $(TARGET_TRIPLE)-as
29 | LD = $(TARGET_TRIPLE)-ld
30 | AR = $(TARGET_TRIPLE)-ar
31 | CFLAGS_TOOLCHAIN := -Wno-maybe-uninitialized
32 | endif
33 |
34 | ifeq ($(ARCH),aarch64)
35 | CFLAGS_ARCH := -mcpu=$(GCC_CPU)
36 | ASM_CPP_FLAGS := -x assembler-with-cpp -c -g -mcpu=$(GCC_CPU)
37 | ASM_FLAGS := -mcpu=$(GCC_CPU)
38 |
39 | ARCH_DIR := aarch64
40 | else ifeq ($(ARCH),riscv64)
41 | ASM_CPP_FLAGS := -x assembler-with-cpp -c -g -march=rv64imac_zicsr_zifencei -mabi=lp64
42 | ASM_FLAGS := -march=rv64imac_zicsr_zifencei -mabi=lp64
43 | CFLAGS_ARCH := -mcmodel=medany -march=rv64imac_zicsr_zifencei -mabi=lp64
44 |
45 | ARCH_DIR := riscv
46 | else ifeq ($(ARCH),x86_64)
47 | CFLAGS_ARCH := -march=x86-64 -mtune=$(GCC_CPU)
48 | ASM_CPP_FLAGS := -x assembler-with-cpp -c -g
49 | ASM_FLAGS := -g -march=generic64
50 |
51 | ARCH_DIR := x86_64
52 | else
53 | $(error ARCH is unsupported)
54 | endif
55 |
56 | CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding -Wall $(CFLAGS_TOOLCHAIN) -Werror -I$(SEL4_SDK)/include $(CFLAGS_ARCH) -DARCH_$(ARCH)
57 |
58 | PROGS := monitor.elf
59 | OBJECTS := main.o crt0.o util.o
60 | LINKSCRIPT := ../libmicrokit/microkit.ld
61 |
62 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.S
63 | $(CC) $(ASM_CPP_FLAGS) $< -o $@
64 |
65 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.s
66 | $(AS) -c -g $(ASM_FLAGS) $< -o $@
67 |
68 | $(BUILD_DIR)/%.o : src/%.c
69 | $(CC) -c $(CFLAGS) $< -o $@
70 |
71 | OBJPROG = $(addprefix $(BUILD_DIR)/, $(PROGS))
72 |
73 | all: $(OBJPROG)
74 |
75 | $(OBJPROG): $(addprefix $(BUILD_DIR)/, $(OBJECTS)) $(LINKSCRIPT)
76 | $(LD) -z noexecstack -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@
77 |
--------------------------------------------------------------------------------
/example/x86_64_ioport/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2025, UNSW
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
23 |
24 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
25 |
26 | ifeq ($(ARCH),x86_64)
27 | TOOLCHAIN := x86_64-linux-gnu
28 | CFLAGS_ARCH := -march=x86-64 -mtune=generic
29 | else
30 | $(error Unsupported ARCH)
31 | endif
32 |
33 | CC := $(TOOLCHAIN)-gcc
34 | LD := $(TOOLCHAIN)-ld
35 | AS := $(TOOLCHAIN)-as
36 | OBJCOPY := $(TOOLCHAIN)-objcopy
37 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
38 |
39 | IMAGES := x86_64_ioport.elf
40 | CFLAGS := -nostdlib -ffreestanding -g3 -O3 -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
41 | LDFLAGS := -L$(BOARD_DIR)/lib -z noexecstack
42 | LIBS := -lmicrokit -Tmicrokit.ld
43 |
44 | INITIAL_TASK = $(BUILD_DIR)/initialiser.elf
45 | KERNEL = $(BUILD_DIR)/sel4.elf
46 | KERNEL_32B = $(BUILD_DIR)/sel4_32.elf
47 | REPORT = $(BUILD_DIR)/report.txt
48 | SPEC = $(BUILD_DIR)/capdl_spec.json
49 |
50 | all: $(KERNEL) $(INITIAL_TASK)
51 | qemu: $(KERNEL_32B) $(INITIAL_TASK)
52 |
53 | $(BUILD_DIR)/x86_64_ioport.o: x86_64_ioport.c Makefile
54 | $(CC) -c $(CFLAGS) -Wall -Wno-unused-function -Werror $< -o $@
55 |
56 | $(BUILD_DIR)/x86_64_ioport.elf: $(BUILD_DIR)/x86_64_ioport.o
57 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
58 |
59 | $(KERNEL) $(KERNEL_32B) $(INITIAL_TASK): $(addprefix $(BUILD_DIR)/, $(IMAGES)) x86_64_ioport.system
60 | $(MICROKIT_TOOL) x86_64_ioport.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(INITIAL_TASK) -r $(REPORT) --capdl-json $(SPEC)
61 |
62 | qemu:
63 | qemu-system-x86_64 \
64 | -cpu qemu64,+fsgsbase,+pdpe1gb,+xsaveopt,+xsave \
65 | -m "1G" \
66 | -display none \
67 | -serial mon:stdio \
68 | -kernel $(KERNEL_32B) \
69 | -initrd $(INITIAL_TASK)
70 |
--------------------------------------------------------------------------------
/loader/src/riscv/sbi.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #include "sbi.h"
8 |
9 | struct sbi_ret sbi_call(uint64_t eid, uint64_t fid, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3,
10 | uint64_t arg4, uint64_t arg5)
11 | {
12 | struct sbi_ret ret;
13 |
14 | register uint64_t a0 asm("a0") = arg0;
15 | register uint64_t a1 asm("a1") = arg1;
16 | register uint64_t a2 asm("a2") = arg2;
17 | register uint64_t a3 asm("a3") = arg3;
18 | register uint64_t a4 asm("a4") = arg4;
19 | register uint64_t a5 asm("a5") = arg5;
20 | register uint64_t a6 asm("a6") = fid;
21 | register uint64_t a7 asm("a7") = eid;
22 |
23 | asm volatile("ecall"
24 | : "+r"(a0), "+r"(a1)
25 | : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(a6), "r"(a7)
26 | : "memory");
27 |
28 | ret.error = a0;
29 | ret.value = a1;
30 |
31 | return ret;
32 | }
33 |
34 | /*
35 | * Chapter 3, Table 1 of SBI specification.
36 | */
37 | char *sbi_error_as_string(long error)
38 | {
39 | switch (error) {
40 | case SBI_SUCCESS:
41 | return "Completed successfully";
42 | case SBI_ERR_FAILED:
43 | return "Failed";
44 | case SBI_ERR_NOT_SUPPORTED:
45 | return "Not supported";
46 | case SBI_ERR_INVALID_PARAM:
47 | return "Invalid parameter(s)";
48 | case SBI_ERR_DENIED:
49 | return "Denied or not allowed";
50 | case SBI_ERR_INVALID_ADDRESS:
51 | return "Invalid address(s)";
52 | case SBI_ERR_ALREADY_AVAILABLE:
53 | return "Already available";
54 | case SBI_ERR_ALREADY_STARTED:
55 | return "Already started";
56 | case SBI_ERR_ALREADY_STOPPED:
57 | return "Already stopped";
58 | case SBI_ERR_NO_SHMEM:
59 | return "Shared memory not available";
60 | case SBI_ERR_INVALID_STATE:
61 | return "Invalid state";
62 | case SBI_ERR_BAD_RANGE:
63 | return "Bad (or invalid) range";
64 | case SBI_ERR_TIMEOUT:
65 | return "Failed due to timeout";
66 | case SBI_ERR_IO:
67 | return "Input/Output error";
68 | case SBI_ERR_DENIED_LOCKED:
69 | return "Denied or not allowed due to lock status";
70 | default:
71 | return "";
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example/passive_server/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
23 |
24 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
25 |
26 | ifeq ($(ARCH),aarch64)
27 | TARGET_TRIPLE := aarch64-none-elf
28 | CFLAGS_ARCH := -mstrict-align
29 | else ifeq ($(ARCH),riscv64)
30 | TARGET_TRIPLE := riscv64-unknown-elf
31 | CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
32 | else
33 | $(error Unsupported ARCH)
34 | endif
35 |
36 | ifeq ($(strip $(LLVM)),True)
37 | CC := clang -target $(TARGET_TRIPLE)
38 | AS := clang -target $(TARGET_TRIPLE)
39 | LD := ld.lld
40 | else
41 | CC := $(TARGET_TRIPLE)-gcc
42 | LD := $(TARGET_TRIPLE)-ld
43 | AS := $(TARGET_TRIPLE)-as
44 | endif
45 |
46 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
47 |
48 | SERVER_OBJS := server.o
49 | CLIENT_OBJS := client.o
50 |
51 | IMAGES := server.elf client.elf
52 | CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
53 | LDFLAGS := -L$(BOARD_DIR)/lib
54 | LIBS := -lmicrokit -Tmicrokit.ld
55 |
56 | IMAGE_FILE = $(BUILD_DIR)/loader.img
57 | REPORT_FILE = $(BUILD_DIR)/report.txt
58 |
59 | all: $(IMAGE_FILE)
60 |
61 | $(BUILD_DIR)/%.o: %.c Makefile
62 | $(CC) -c $(CFLAGS) $< -o $@
63 |
64 | $(BUILD_DIR)/%.o: %.s Makefile
65 | $(AS) -g -mcpu=$(CPU) $< -o $@
66 |
67 | $(BUILD_DIR)/server.elf: $(addprefix $(BUILD_DIR)/, $(SERVER_OBJS))
68 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
69 |
70 | $(BUILD_DIR)/client.elf: $(addprefix $(BUILD_DIR)/, $(CLIENT_OBJS))
71 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
72 |
73 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) passive_server.system
74 | $(MICROKIT_TOOL) passive_server.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
75 |
--------------------------------------------------------------------------------
/platforms.yml:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: BSD-2-Clause
2 | # Copyright 2025 Ivan Velickovic
3 |
4 | # This YAML file describes the supported platforms in Microkit.
5 | # It mainly exists so that the seL4 documentation website can list
6 | # the supported platforms in a data-oriented way.
7 | #
8 | # For each new platform, please at least supply the following:
9 | # name: the Microkit name in build_sdk.py
10 | # cmake_plat: the name of the platform in the seL4 kernel build-system
11 | # since: if this is a new platform, put 'dev' otherwise put what the
12 | # first released Microkit version the platform was available in.
13 | #
14 | # This list is ordered based on the order in what the platforms were added
15 | # in.
16 | platforms:
17 | - name: serengeti
18 | cmake_plat: cheshire
19 | since: 2.1.0
20 | - name: imx8mp_iotgate
21 | cmake_plat: imx8mp-evk
22 | since: 2.1.0
23 | - name: rpi4b_2gb
24 | cmake_plat: rpi4
25 | since: 2.1.0
26 | - name: rpi4b_4gb
27 | cmake_plat: rpi4
28 | since: 2.1.0
29 | - name: rpi4b_8gb
30 | cmake_plat: rpi4
31 | since: 2.1.0
32 | - name: hifive_p550
33 | cmake_plat: hifive-p550
34 | since: 2.1.0
35 | - name: ultra96v2
36 | cmake_plat: ultra96v2
37 | since: 2.1.0
38 | - name: ariane
39 | cmake_plat: ariane
40 | since: 2.0.0
41 | - name: cheshire
42 | cmake_plat: cheshire
43 | since: 2.0.0
44 | - name: rockpro64
45 | cmake_plat: rockpro64
46 | since: 2.0.0
47 | - name: rpi4b_1gb
48 | cmake_plat: rpi4
49 | since: 2.0.0
50 | - name: imx8mm_evk
51 | cmake_plat: imx8mm-evk
52 | since: 1.3.0
53 | - name: imx8mp_evk
54 | cmake_plat: imx8mp-evk
55 | since: 2.0.0
56 | - name: star64
57 | cmake_plat: star64
58 | since: 1.4.0
59 | - name: qemu_virt_riscv64
60 | cmake_plat: qemu-riscv-virt
61 | cpu: rv64
62 | since: 1.4.0
63 | - name: imx8mq_evk
64 | cmake_plat: imx8mq-evk
65 | since: 1.3.0
66 | - name: maaxboard
67 | cmake_plat: maaxboard
68 | since: 1.3.0
69 | - name: odroidc2
70 | cmake_plat: odroidc2
71 | since: 1.3.0
72 | - name: odroidc4
73 | cmake_plat: odroidc4
74 | since: 1.3.0
75 | - name: qemu_virt_aarch64
76 | cmake_plat: qemu-arm-virt
77 | cpu: Cortext-A53
78 | since: 1.3.0
79 | - name: tqma8xqp1gb
80 | cmake_plat: tqma8xqp1gb
81 | since: 1.3.0
82 | - name: zcu102
83 | cmake_plat: zcu102
84 | since: 1.3.0
85 |
--------------------------------------------------------------------------------
/loader/src/aarch64/el.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include "el.h"
9 |
10 | #include
11 |
12 | #include "../cutil.h"
13 | #include "../loader.h"
14 | #include "../uart.h"
15 |
16 | void switch_to_el1(void);
17 | void switch_to_el2(void);
18 |
19 | /* Returns the current exception level */
20 | enum el current_el(void)
21 | {
22 | /* See: C5.2.1 CurrentEL */
23 | uint32_t val;
24 | asm volatile("mrs %x0, CurrentEL" : "=r"(val) :: "cc");
25 | /* bottom two bits are res0 */
26 | return (enum el) val >> 2;
27 | }
28 |
29 |
30 | int ensure_correct_el(int logical_cpu)
31 | {
32 | enum el el = current_el();
33 |
34 | LDR_PRINT("INFO", logical_cpu, "CurrentEL=");
35 | puts(el_to_string(el));
36 | puts("\n");
37 |
38 | if (el == EL0) {
39 | LDR_PRINT("ERROR", logical_cpu, "Unsupported initial exception level\n");
40 | return 1;
41 | }
42 |
43 | if (el == EL3) {
44 | LDR_PRINT("INFO", logical_cpu, "Dropping from EL3 to EL2(NS)\n");
45 | switch_to_el2();
46 | LDR_PRINT("INFO", logical_cpu, "Dropped from EL3 to EL2(NS)\n");
47 | el = EL2;
48 | }
49 |
50 | if (is_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
51 | if (el != EL2) {
52 | LDR_PRINT("ERROR", logical_cpu, "seL4 configured as a hypervisor, but not in EL2\n");
53 | return 1;
54 | } else {
55 | LDR_PRINT("INFO", logical_cpu, "Resetting CNTVOFF\n");
56 | asm volatile("msr cntvoff_el2, xzr");
57 | }
58 | } else {
59 | if (el == EL2) {
60 | /* seL4 relies on the timer to be set to a useful value */
61 | LDR_PRINT("INFO", logical_cpu, "Resetting CNTVOFF\n");
62 | asm volatile("msr cntvoff_el2, xzr");
63 | LDR_PRINT("INFO", logical_cpu, "Dropping from EL2 to EL1\n");
64 | switch_to_el1();
65 | LDR_PRINT("INFO", logical_cpu, "CurrentEL=");
66 | el = current_el();
67 | puts(el_to_string(el));
68 | puts("\n");
69 | if (el == EL1) {
70 | LDR_PRINT("INFO", logical_cpu, "Dropped to EL1 successfully\n");
71 | } else {
72 | LDR_PRINT("ERROR", logical_cpu, "Failed to switch to EL1\n");
73 | return 1;
74 | }
75 | }
76 | }
77 |
78 | return 0;
79 | }
80 |
--------------------------------------------------------------------------------
/example/hierarchy/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(MICROKIT_SDK)),)
11 | $(error MICROKIT_SDK must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(MICROKIT_BOARD)),)
15 | $(error MICROKIT_BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(MICROKIT_CONFIG)),)
19 | $(error MICROKIT_CONFIG must be specified)
20 | endif
21 |
22 | BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
23 |
24 | ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
25 |
26 | ifeq ($(ARCH),aarch64)
27 | TARGET_TRIPLE := aarch64-none-elf
28 | CFLAGS_ARCH := -mstrict-align
29 | else ifeq ($(ARCH),riscv64)
30 | TARGET_TRIPLE := riscv64-unknown-elf
31 | CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
32 | else
33 | $(error Unsupported ARCH)
34 | endif
35 |
36 | ifeq ($(strip $(LLVM)),True)
37 | CC := clang -target $(TARGET_TRIPLE)
38 | AS := clang -target $(TARGET_TRIPLE)
39 | LD := ld.lld
40 | else
41 | CC := $(TARGET_TRIPLE)-gcc
42 | LD := $(TARGET_TRIPLE)-ld
43 | AS := $(TARGET_TRIPLE)-as
44 | endif
45 |
46 | MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
47 |
48 | RESTARTER_OBJS := restarter.o
49 | CRASHER_OBJS := crasher.o
50 | HELLO_OBJS := hello.o
51 |
52 | IMAGES := restarter.elf crasher.elf hello.elf
53 | CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
54 | LDFLAGS := -L$(BOARD_DIR)/lib
55 | LIBS := -lmicrokit -Tmicrokit.ld
56 |
57 | IMAGE_FILE = $(BUILD_DIR)/loader.img
58 | REPORT_FILE = $(BUILD_DIR)/report.txt
59 |
60 | all: $(IMAGE_FILE)
61 |
62 | $(BUILD_DIR)/%.o: %.c Makefile
63 | $(CC) -c $(CFLAGS) $< -o $@
64 |
65 | $(BUILD_DIR)/%.o: %.s Makefile
66 | $(AS) -g -mcpu=$(CPU) $< -o $@
67 |
68 | $(BUILD_DIR)/restarter.elf: $(addprefix $(BUILD_DIR)/, $(RESTARTER_OBJS))
69 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
70 |
71 | $(BUILD_DIR)/crasher.elf: $(addprefix $(BUILD_DIR)/, $(CRASHER_OBJS))
72 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
73 |
74 | $(BUILD_DIR)/hello.elf: $(addprefix $(BUILD_DIR)/, $(HELLO_OBJS))
75 | $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
76 |
77 | $(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) hierarchy.system
78 | $(MICROKIT_TOOL) hierarchy.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
79 |
--------------------------------------------------------------------------------
/monitor/src/util.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 |
8 | #include "util.h"
9 |
10 | void putc(uint8_t ch)
11 | {
12 | #if defined(CONFIG_PRINTING)
13 | seL4_DebugPutChar(ch);
14 | #endif
15 | }
16 |
17 | void puts(const char *s)
18 | {
19 | while (*s) {
20 | putc(*s);
21 | s++;
22 | }
23 | }
24 |
25 | static char hexchar(unsigned int v)
26 | {
27 | return v < 10 ? '0' + v : ('a' - 10) + v;
28 | }
29 |
30 | void puthex32(uint32_t val)
31 | {
32 | char buffer[8 + 3];
33 | buffer[0] = '0';
34 | buffer[1] = 'x';
35 | buffer[8 + 3 - 1] = 0;
36 | for (unsigned i = 8 + 1; i > 1; i--) {
37 | buffer[i] = hexchar(val & 0xf);
38 | val >>= 4;
39 | }
40 | puts(buffer);
41 | }
42 |
43 | void puthex64(uint64_t val)
44 | {
45 | char buffer[16 + 3];
46 | buffer[0] = '0';
47 | buffer[1] = 'x';
48 | buffer[16 + 3 - 1] = 0;
49 | for (unsigned i = 16 + 1; i > 1; i--) {
50 | buffer[i] = hexchar(val & 0xf);
51 | val >>= 4;
52 | }
53 | puts(buffer);
54 | }
55 |
56 | void fail(char *s)
57 | {
58 | puts("FAIL: ");
59 | puts(s);
60 | puts("\n");
61 | for (;;) {}
62 | }
63 |
64 | char *sel4_strerror(seL4_Word err)
65 | {
66 | switch (err) {
67 | case seL4_NoError:
68 | return "seL4_NoError";
69 | case seL4_InvalidArgument:
70 | return "seL4_InvalidArgument";
71 | case seL4_InvalidCapability:
72 | return "seL4_InvalidCapability";
73 | case seL4_IllegalOperation:
74 | return "seL4_IllegalOperation";
75 | case seL4_RangeError:
76 | return "seL4_RangeError";
77 | case seL4_AlignmentError:
78 | return "seL4_AlignmentError";
79 | case seL4_FailedLookup:
80 | return "seL4_FailedLookup";
81 | case seL4_TruncatedMessage:
82 | return "seL4_TruncatedMessage";
83 | case seL4_DeleteFirst:
84 | return "seL4_DeleteFirst";
85 | case seL4_RevokeFirst:
86 | return "seL4_RevokeFirst";
87 | case seL4_NotEnoughMemory:
88 | return "seL4_NotEnoughMemory";
89 | }
90 |
91 | return "";
92 | }
93 |
94 | char *strcpy(char *restrict dst, const char *restrict src)
95 | {
96 | int i = 0;
97 | while (src[i]) {
98 | dst[i] = src[i];
99 | i++;
100 | }
101 | dst[i] = '\0';
102 |
103 | return dst;
104 | }
105 |
--------------------------------------------------------------------------------
/loader/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | #
4 | # SPDX-License-Identifier: BSD-2-Clause
5 | #
6 | ifeq ($(strip $(BUILD_DIR)),)
7 | $(error BUILD_DIR must be specified)
8 | endif
9 |
10 | ifeq ($(strip $(ARCH)),)
11 | $(error ARCH must be specified)
12 | endif
13 |
14 | ifeq ($(strip $(BOARD)),)
15 | $(error BOARD must be specified)
16 | endif
17 |
18 | ifeq ($(strip $(LINK_ADDRESS)),)
19 | $(error LINK_ADDRESS must be specified)
20 | endif
21 |
22 | ifeq ($(strip $(TARGET_TRIPLE)),)
23 | $(error TARGET_TRIPLE must be specified)
24 | endif
25 |
26 | ifeq ($(strip $(LLVM)),True)
27 | CC = clang -target $(TARGET_TRIPLE)
28 | CPP = clang-cpp -target $(TARGET_TRIPLE)
29 | AS = clang -target $(TARGET_TRIPLE)
30 | LD = ld.lld
31 | else
32 | CC = $(TARGET_TRIPLE)-gcc
33 | CPP = $(TARGET_TRIPLE)-cpp
34 | AS = $(TARGET_TRIPLE)-as
35 | LD = $(TARGET_TRIPLE)-ld
36 | endif
37 |
38 | ifeq ($(ARCH),aarch64)
39 | CFLAGS_AARCH64 := -mcpu=$(GCC_CPU) -mgeneral-regs-only -mstrict-align -mno-outline-atomics
40 | CFLAGS_ARCH := $(CFLAGS_AARCH64) -DARCH_aarch64
41 | ASM_FLAGS_ARCH := -mcpu=$(GCC_CPU)
42 | ARCH_DIR := aarch64
43 | else ifeq ($(ARCH),riscv64)
44 | CFLAGS_RISCV64 := -mcmodel=medany -march=rv64imac_zicsr_zifencei -mabi=lp64
45 | CFLAGS_ARCH := $(CFLAGS_RISCV64) -DARCH_riscv64
46 | ASM_FLAGS_ARCH := -march=rv64imac_zicsr_zifencei -mabi=lp64
47 | ARCH_DIR := riscv
48 | endif
49 |
50 | CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding \
51 | -MP -MD $(CFLAGS_ARCH) -I$(SEL4_SDK)/include \
52 | -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \
53 | -Wundef -Wno-nonnull -Wnested-externs
54 |
55 | ASM_FLAGS := $(ASM_FLAGS_ARCH) -g -MP -MD -I$(SEL4_SDK)/include
56 |
57 | PROGS := loader.elf
58 | OBJECTS := loader.o crt0.o uart.o cutil.o
59 |
60 | ifeq ($(ARCH),aarch64)
61 | OBJECTS += util64.o el.o exceptions.o init.o mmu.o cpus.o
62 | else ifeq ($(ARCH),riscv64)
63 | OBJECTS += exceptions.o init.o mmu.o cpus.o sbi.o
64 | endif
65 |
66 | LINKSCRIPT_INPUT := $(ARCH).ld
67 | LINKSCRIPT := $(BUILD_DIR)/link.ld
68 |
69 | .SECONDARY:
70 |
71 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.S
72 | $(CC) -DLINK_ADDRESS=$(LINK_ADDRESS) -x assembler-with-cpp -c $(ASM_FLAGS) $< -o $@
73 |
74 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.s
75 | $(AS) -c $< -o $@
76 |
77 | $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.c
78 | $(CC) -c $(CFLAGS) $< -o $@
79 |
80 | $(BUILD_DIR)/%.o : src/%.c
81 | $(CC) -c $(CFLAGS) $< -o $@
82 |
83 | -include $(BUILD_DIR)/*.d
84 |
85 | OBJPROG = $(addprefix $(BUILD_DIR)/, $(PROGS))
86 |
87 | all: $(OBJPROG)
88 |
89 | $(LINKSCRIPT): $(LINKSCRIPT_INPUT)
90 | $(CPP) -DLINK_ADDRESS=$(LINK_ADDRESS) $< | grep -v "^#" > $@
91 |
92 | $(OBJPROG): $(addprefix $(BUILD_DIR)/, $(OBJECTS)) $(LINKSCRIPT)
93 | $(LD) -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@
94 |
--------------------------------------------------------------------------------
/loader/src/aarch64/crt0.S:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | .extern main
7 |
8 | #include "../loader.h"
9 |
10 | .section ".text.start"
11 |
12 | .global _start;
13 | .type _start, %function;
14 | _start:
15 | /* This assumes that the entry CPU is logical CPU0, the base of the stack*/
16 | adrp x1, _stack
17 | add x1, x1, STACK_SIZE
18 | mov sp, x1
19 | /* May not have been loaded in the right location.
20 | * Try and move ourselves so we're in the right place
21 | */
22 | bl relocate
23 | cmp x0, #1
24 | beq 1f
25 | /* Otherwise, jump to the start of the new loader */
26 | br x0
27 | 1:
28 | b main
29 |
30 | relocate:
31 | stp x29, x30, [sp, #-16]!
32 | mov x29, sp
33 | /* Check if the image is already at the correct location */
34 | ldr x0, =LINK_ADDRESS
35 | adr x1, _start
36 | cmp x0, x1
37 | beq image_ok
38 |
39 | /* Log that we are being relocated */
40 | bl relocation_log
41 |
42 | /* Restore x0 and x1 */
43 | ldr x0, =LINK_ADDRESS
44 | adr x1, _start
45 |
46 | /* Sanity check: We don't want to overwrite ourselves! We assume that
47 | * everything between _start (src_start) and _bss_end (src_end) is important (i.e.
48 | * something that might be run while relocating) but allow overlap for
49 | * things after _bss_end i.e. the loader_data.
50 | */
51 | adrp x2, _bss_end
52 | add x2, x2, #:lo12:_bss_end
53 |
54 | /* The loader_data is directly after _bss_end, with the first
55 | * value being the loader_data struct. The second field of
56 | * this struct is the size of the loader_data region, so we
57 | * add this to _bss_end to get the real end of the image
58 | */
59 | ldr x3, [x2, #+8]
60 | add x2, x2, x3
61 | sub x2, x2, x1
62 |
63 | adrp x3, _bss_end
64 | add x3, x3, #:lo12:_bss_end
65 |
66 | sub x5, x3, x1
67 | add x4, x0, x5 /* dst_end */
68 |
69 | /* At this point:
70 | * x0: dst_code_start (LINK_ADDRESS)
71 | * x1: src_code_start (_start)
72 | * x2: image_size
73 | * x3: src_code_end (_bss_end)
74 | * x4: dst_code_end (LINK_ADDRESS + (_bss_end - _start))
75 | */
76 |
77 | /* check: if (dst_end >= src_start && dst_end < src_end) { abort } */
78 | cmp x4, x1
79 | blt 1f
80 |
81 | cmp x4, x3
82 | bge 1f
83 |
84 | b cant_reloc
85 | 1:
86 |
87 | /* check: if (dst_start >= src_start && dest_start < src_end) { abort } */
88 | cmp x0, x1
89 | blt 2f
90 |
91 | cmp x0, x3
92 | bge 2f
93 | cant_reloc:
94 | b relocation_failed
95 |
96 | 2:
97 | /* x0 = desired image base */
98 | /* x1 = current image base */
99 | /* x2 = image size */
100 | bl memmove
101 |
102 | /* x0 = dest, save it to a callee-saved register while we invalidate icache */
103 | mov x19, x0
104 | bl flush_dcache
105 | bl invalidate_icache
106 | mov x0, x19
107 | b 1f
108 |
109 | image_ok:
110 | /* Already in the right place, keep booting */
111 | mov x0, #1
112 |
113 | 1:
114 | ldp x29, x30, [sp], #16
115 | ret
116 |
--------------------------------------------------------------------------------
/dev_build.py:
--------------------------------------------------------------------------------
1 | # Copyright 2021, Breakaway Consulting Pty. Ltd.
2 | # SPDX-License-Identifier: BSD-2-Clause
3 |
4 | """Build a specific example during development.
5 |
6 | This is designed to make it easy to build and run examples during development.
7 | """
8 | from argparse import ArgumentParser
9 | from os import environ, system
10 | from pathlib import Path
11 | from shutil import rmtree
12 | from subprocess import run
13 |
14 | CWD = Path(__file__).parent
15 | BUILD_DIR = CWD / "tmp_build"
16 |
17 |
18 | def find_releases():
19 | releases = []
20 | for f in (CWD / "release").iterdir():
21 | if not f.is_dir():
22 | continue
23 | if not f.name.startswith("microkit-sdk-"):
24 | # All directories in here should match this, but
25 | # skip just iun case someone added junk
26 | continue
27 | releases.append(f)
28 |
29 | def release_sort_key(rel):
30 | ver_str = rel.name.split("-")[2]
31 | ver = tuple(int(x) for x in ver_str.split("."))
32 | return ver
33 |
34 | releases.sort(key=release_sort_key, reverse=True)
35 | return releases
36 |
37 |
38 | def main():
39 | parser = ArgumentParser()
40 | parser.add_argument(
41 | "--rebuild",
42 | action="store_true",
43 | default=False,
44 | help="Force a rebuild of the example",
45 | )
46 | parser.add_argument(
47 | "--example-from-sdk",
48 | action="store_true",
49 | default=False,
50 | help="Build the example from the SDK build rather than directly from source directory",
51 | )
52 | parser.add_argument(
53 | "--board",
54 | help="Target board",
55 | required=True
56 | )
57 | parser.add_argument(
58 | "--example",
59 | help="Example to build",
60 | required=True
61 | )
62 | parser.add_argument(
63 | "--config",
64 | default="debug",
65 | help="Config option to be passed to the tool"
66 | )
67 | parser.add_argument(
68 | "--llvm",
69 | action="store_true",
70 | help="Build with LLVM/Clang toolchain"
71 | )
72 | args = parser.parse_args()
73 |
74 | # TODO: Support choosing a release by specifying on command line
75 | releases = find_releases()
76 | release = releases[0]
77 |
78 | if args.rebuild and BUILD_DIR.exists():
79 | rmtree(BUILD_DIR)
80 |
81 | if not BUILD_DIR.exists():
82 | BUILD_DIR.mkdir()
83 |
84 | tool_rebuild = f"cd {CWD / 'tool/microkit'} && cargo build --release"
85 | r = system(tool_rebuild)
86 | assert r == 0
87 |
88 | make_env = environ.copy()
89 | make_env["BUILD_DIR"] = str(BUILD_DIR.absolute())
90 | make_env["MICROKIT_BOARD"] = args.board
91 | make_env["MICROKIT_CONFIG"] = args.config
92 | make_env["MICROKIT_SDK"] = str(release)
93 | make_env["MICROKIT_TOOL"] = (CWD / "target/release/microkit").absolute()
94 | make_env["LLVM"] = str(args.llvm)
95 |
96 | # Choose the makefile based on the `--example-from-sdk` command line flag
97 | makefile_directory = (
98 | f"{release}/example/{args.example}"
99 | if args.example_from_sdk
100 | else f"{CWD.absolute()}/example/{args.example}"
101 | )
102 |
103 | cmd = ["make", "-C", makefile_directory]
104 |
105 | run(cmd, env=make_env, check=True)
106 |
107 |
108 | if __name__ == "__main__":
109 | main()
110 |
--------------------------------------------------------------------------------
/flake.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "nixpkgs": {
4 | "locked": {
5 | "lastModified": 1748026580,
6 | "narHash": "sha256-rWtXrcIzU5wm/C8F9LWvUfBGu5U5E7cFzPYT1pHIJaQ=",
7 | "owner": "NixOS",
8 | "repo": "nixpkgs",
9 | "rev": "11cb3517b3af6af300dd6c055aeda73c9bf52c48",
10 | "type": "github"
11 | },
12 | "original": {
13 | "owner": "NixOS",
14 | "ref": "25.05",
15 | "repo": "nixpkgs",
16 | "type": "github"
17 | }
18 | },
19 | "nixpkgs_2": {
20 | "locked": {
21 | "lastModified": 1744536153,
22 | "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
23 | "owner": "NixOS",
24 | "repo": "nixpkgs",
25 | "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
26 | "type": "github"
27 | },
28 | "original": {
29 | "owner": "NixOS",
30 | "ref": "nixpkgs-unstable",
31 | "repo": "nixpkgs",
32 | "type": "github"
33 | }
34 | },
35 | "root": {
36 | "inputs": {
37 | "nixpkgs": "nixpkgs",
38 | "rust-overlay": "rust-overlay",
39 | "treefmt-nix": "treefmt-nix",
40 | "utils": "utils"
41 | }
42 | },
43 | "rust-overlay": {
44 | "inputs": {
45 | "nixpkgs": "nixpkgs_2"
46 | },
47 | "locked": {
48 | "lastModified": 1753671061,
49 | "narHash": "sha256-IU4eBWfe9h2QejJYST+EAlhg8a1H6mh9gbcmWgZ2/mQ=",
50 | "owner": "oxalica",
51 | "repo": "rust-overlay",
52 | "rev": "40065d17ee4dbec3ded8ca61236132aede843fab",
53 | "type": "github"
54 | },
55 | "original": {
56 | "owner": "oxalica",
57 | "repo": "rust-overlay",
58 | "type": "github"
59 | }
60 | },
61 | "systems": {
62 | "locked": {
63 | "lastModified": 1681028828,
64 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
65 | "owner": "nix-systems",
66 | "repo": "default",
67 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
68 | "type": "github"
69 | },
70 | "original": {
71 | "owner": "nix-systems",
72 | "repo": "default",
73 | "type": "github"
74 | }
75 | },
76 | "treefmt-nix": {
77 | "inputs": {
78 | "nixpkgs": [
79 | "nixpkgs"
80 | ]
81 | },
82 | "locked": {
83 | "lastModified": 1729613947,
84 | "narHash": "sha256-XGOvuIPW1XRfPgHtGYXd5MAmJzZtOuwlfKDgxX5KT3s=",
85 | "owner": "numtide",
86 | "repo": "treefmt-nix",
87 | "rev": "aac86347fb5063960eccb19493e0cadcdb4205ca",
88 | "type": "github"
89 | },
90 | "original": {
91 | "owner": "numtide",
92 | "repo": "treefmt-nix",
93 | "type": "github"
94 | }
95 | },
96 | "utils": {
97 | "inputs": {
98 | "systems": "systems"
99 | },
100 | "locked": {
101 | "lastModified": 1726560853,
102 | "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
103 | "owner": "numtide",
104 | "repo": "flake-utils",
105 | "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
106 | "type": "github"
107 | },
108 | "original": {
109 | "owner": "numtide",
110 | "repo": "flake-utils",
111 | "type": "github"
112 | }
113 | }
114 | },
115 | "root": "root",
116 | "version": 7
117 | }
118 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2024, UNSW
3 | # SPDX-License-Identifier: BSD-2-Clause
4 | #
5 | {
6 | description = "A flake for building microkit";
7 |
8 | inputs = {
9 | nixpkgs.url = "github:NixOS/nixpkgs/25.05";
10 | utils.url = "github:numtide/flake-utils";
11 | rust-overlay.url = "github:oxalica/rust-overlay";
12 | treefmt-nix = {
13 | url = "github:numtide/treefmt-nix";
14 | inputs.nixpkgs.follows = "nixpkgs";
15 | };
16 | };
17 |
18 | outputs = { self, nixpkgs, rust-overlay, treefmt-nix, ... }@inputs: inputs.utils.lib.eachSystem [
19 | "x86_64-linux"
20 | "aarch64-linux"
21 | "x86_64-darwin"
22 | "aarch64-darwin"
23 | ]
24 | (system:
25 | let
26 | pkgs = import nixpkgs {
27 | inherit system;
28 |
29 | overlays = [ (import rust-overlay) ];
30 | };
31 |
32 | treefmtEval = treefmt-nix.lib.evalModule pkgs (
33 | { ... }:
34 | {
35 | projectRootFile = "flake.nix";
36 | programs.nixpkgs-fmt.enable = true;
37 | }
38 | );
39 |
40 | pythonTool = pkgs.python312.withPackages (ps: [
41 | ps.mypy
42 | ps.black
43 | ps.flake8
44 | ps.ply
45 | ps.jinja2
46 | ps.pyaml
47 | ps.lxml
48 | ps.pyfdt
49 | ps.setuptools
50 | ]);
51 |
52 | microkitToolToml = nixpkgs.lib.trivial.importTOML ./tool/microkit/Cargo.toml;
53 | microkitToolVersion = microkitToolToml.package.rust-version;
54 |
55 | # Unfortunately Cargo does not support all targets by default so for cross-compiling
56 | # we must explicitly add certain targets.
57 | rustAdditionalTargets = {
58 | aarch64-darwin = [ "x86_64-apple-darwin" "x86_64-unknown-linux-musl" "aarch64-unknown-linux-musl" ];
59 | x86_64-darwin = [ "aarch64-apple-darwin" "x86_64-unknown-linux-musl" "aarch64-unknown-linux-musl" ];
60 | x86_64-linux = [];
61 | aarch64-linux = [];
62 | }.${system} or (throw "Unsupported system: ${system}");
63 |
64 | rustTool = pkgs.rust-bin.stable.${microkitToolVersion}.default.override {
65 | extensions = [ "rust-src" ];
66 | targets = [ pkgs.pkgsStatic.hostPlatform.rust.rustcTarget ] ++ rustAdditionalTargets;
67 | };
68 | in
69 | {
70 | # for `nix fmt`
71 | formatter = treefmtEval.config.build.wrapper;
72 | # for `nix flake check`
73 | checks.formatting = treefmtEval.config.build.check self;
74 |
75 | devShells.default = pkgs.mkShell rec {
76 | name = "microkit-shell";
77 |
78 | nativeBuildInputs = with pkgs; [
79 | pkgsCross.x86_64-embedded.stdenv.cc.bintools.bintools
80 | pkgsCross.x86_64-embedded.stdenv.cc.cc
81 | pkgsCross.aarch64-embedded.stdenv.cc.bintools.bintools
82 | pkgsCross.aarch64-embedded.stdenv.cc.cc
83 | pkgsCross.riscv64-embedded.stdenv.cc.bintools.bintools
84 | pkgsCross.riscv64-embedded.stdenv.cc.cc
85 | gnumake
86 | dtc
87 | expect
88 | pythonTool
89 | git
90 | rustTool
91 | pandoc
92 | (texlive.combine {
93 | inherit (texlive) scheme-medium titlesec enumitem sfmath roboto fontaxes isodate substr tcolorbox environ pdfcol;
94 | })
95 | cmake
96 | ninja
97 | libxml2
98 | qemu
99 | gnutar
100 | ];
101 |
102 | # Necessary for Rust bindgen
103 | LIBCLANG_PATH = "${pkgs.llvmPackages_18.libclang.lib}/lib";
104 | };
105 | });
106 | }
107 |
--------------------------------------------------------------------------------
/example/timer/timer.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024, UNSW
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | /*
12 | * This is a very simple timer driver with the intention of showing
13 | * how to do MMIO and handle interrupts in Microkit.
14 | */
15 |
16 | uintptr_t timer_regs;
17 |
18 | #define TIMER_IRQ_CH 0
19 |
20 | #define TIMER_REG_START 0x140
21 |
22 | #define TIMER_A_INPUT_CLK 0
23 | #define TIMER_E_INPUT_CLK 8
24 | #define TIMER_A_EN (1 << 16)
25 | #define TIMER_A_MODE (1 << 12)
26 |
27 | #define TIMESTAMP_TIMEBASE_SYSTEM 0b000
28 | #define TIMESTAMP_TIMEBASE_1_US 0b001
29 | #define TIMESTAMP_TIMEBASE_10_US 0b010
30 | #define TIMESTAMP_TIMEBASE_100_US 0b011
31 | #define TIMESTAMP_TIMEBASE_1_MS 0b100
32 |
33 | #define TIMEOUT_TIMEBASE_1_US 0b00
34 | #define TIMEOUT_TIMEBASE_10_US 0b01
35 | #define TIMEOUT_TIMEBASE_100_US 0b10
36 | #define TIMEOUT_TIMEBASE_1_MS 0b11
37 |
38 | #define NS_IN_US 1000ULL
39 | #define NS_IN_MS 1000000ULL
40 |
41 | typedef struct {
42 | uint32_t mux;
43 | uint32_t timer_a;
44 | uint32_t timer_b;
45 | uint32_t timer_c;
46 | uint32_t timer_d;
47 | uint32_t unused[13];
48 | uint32_t timer_e;
49 | uint32_t timer_e_hi;
50 | uint32_t mux1;
51 | uint32_t timer_f;
52 | uint32_t timer_g;
53 | uint32_t timer_h;
54 | uint32_t timer_i;
55 | } meson_timer_reg_t;
56 |
57 | typedef struct {
58 | volatile meson_timer_reg_t *regs;
59 | bool disable;
60 | } meson_timer_t;
61 |
62 | meson_timer_t timer;
63 |
64 | static char hexchar(unsigned int v)
65 | {
66 | return v < 10 ? '0' + v : ('a' - 10) + v;
67 | }
68 |
69 | static void puthex64(uint64_t val)
70 | {
71 | char buffer[16 + 3];
72 | buffer[0] = '0';
73 | buffer[1] = 'x';
74 | buffer[16 + 3 - 1] = 0;
75 | for (unsigned i = 16 + 1; i > 1; i--) {
76 | buffer[i] = hexchar(val & 0xf);
77 | val >>= 4;
78 | }
79 | microkit_dbg_puts(buffer);
80 | }
81 |
82 | uint64_t meson_get_time()
83 | {
84 | uint64_t initial_high = timer.regs->timer_e_hi;
85 | uint64_t low = timer.regs->timer_e;
86 | uint64_t high = timer.regs->timer_e_hi;
87 | if (high != initial_high) {
88 | low = timer.regs->timer_e;
89 | }
90 |
91 | uint64_t ticks = (high << 32) | low;
92 | uint64_t time = ticks * NS_IN_US;
93 | return time;
94 | }
95 |
96 | void meson_set_timeout(uint16_t timeout, bool periodic)
97 | {
98 | if (periodic) {
99 | timer.regs->mux |= TIMER_A_MODE;
100 | } else {
101 | timer.regs->mux &= ~TIMER_A_MODE;
102 | }
103 |
104 | timer.regs->timer_a = timeout;
105 |
106 | if (timer.disable) {
107 | timer.regs->mux |= TIMER_A_EN;
108 | timer.disable = false;
109 | }
110 | }
111 |
112 | void meson_stop_timer()
113 | {
114 | timer.regs->mux &= ~TIMER_A_EN;
115 | timer.disable = true;
116 | }
117 |
118 | void init()
119 | {
120 | timer.regs = (void *)(timer_regs + TIMER_REG_START);
121 |
122 | timer.regs->mux = TIMER_A_EN | (TIMESTAMP_TIMEBASE_1_US << TIMER_E_INPUT_CLK) |
123 | (TIMEOUT_TIMEBASE_1_MS << TIMER_A_INPUT_CLK);
124 |
125 | timer.regs->timer_e = 0;
126 |
127 | // Have a timeout of 1 second, and have it be periodic so that it will keep recurring.
128 | microkit_dbg_puts("Setting a timeout of 1 second.\n");
129 | meson_set_timeout(1000, true);
130 | }
131 |
132 | void notified(microkit_channel ch)
133 | {
134 | switch (ch) {
135 | case TIMER_IRQ_CH:
136 | microkit_dbg_puts("Got timer interrupt!\n");
137 | microkit_irq_ack(ch);
138 | microkit_dbg_puts("Current time is: ");
139 | puthex64(meson_get_time());
140 | microkit_dbg_puts("\n");
141 | break;
142 | default:
143 | microkit_dbg_puts("TIMER|ERROR: unexpected channel!\n");
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/tool/microkit/src/capdl/spec.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | use std::ops::Range;
8 |
9 | use sel4_capdl_initializer_types::{Cap, Object, Rights, Word};
10 | use serde::Serialize;
11 |
12 | use crate::{
13 | capdl::{FrameFill, SLOT_BITS},
14 | sel4::{Config, ObjectType, PageSize},
15 | };
16 |
17 | #[derive(Clone, Serialize)]
18 | pub struct ElfContent {
19 | pub elf_id: usize,
20 | pub elf_seg_idx: usize,
21 | pub elf_seg_data_range: Range,
22 | }
23 |
24 | /// CNode and SchedContext are quirky as they have variable size.
25 | pub fn capdl_obj_physical_size_bits(obj: &Object, sel4_config: &Config) -> u64 {
26 | match obj {
27 | Object::Endpoint => ObjectType::Endpoint.fixed_size_bits(sel4_config).unwrap(),
28 | Object::Notification => ObjectType::Notification
29 | .fixed_size_bits(sel4_config)
30 | .unwrap(),
31 | Object::CNode(cnode) => cnode.size_bits as u64 + SLOT_BITS,
32 | Object::Tcb(_) => ObjectType::Tcb.fixed_size_bits(sel4_config).unwrap(),
33 | Object::VCpu => ObjectType::Vcpu.fixed_size_bits(sel4_config).unwrap(),
34 | Object::Frame(frame) => frame.size_bits as u64,
35 | Object::PageTable(pt) => {
36 | if pt.is_root {
37 | ObjectType::VSpace.fixed_size_bits(sel4_config).unwrap()
38 | } else {
39 | ObjectType::PageTable.fixed_size_bits(sel4_config).unwrap()
40 | }
41 | }
42 | Object::AsidPool(_) => ObjectType::AsidPool.fixed_size_bits(sel4_config).unwrap(),
43 | Object::SchedContext(sched_context) => sched_context.size_bits as u64,
44 | Object::Reply => ObjectType::Reply.fixed_size_bits(sel4_config).unwrap(),
45 | _ => 0,
46 | }
47 | }
48 |
49 | pub fn capdl_obj_human_name(obj: &Object, sel4_config: &Config) -> &'static str {
50 | match obj {
51 | Object::Endpoint => "Endpoint",
52 | Object::Notification => "Notification",
53 | Object::CNode(_) => "CNode",
54 | Object::Tcb(_) => "TCB",
55 | Object::VCpu => "VCPU",
56 | Object::Frame(frame) => {
57 | if frame.size_bits == PageSize::Small.fixed_size_bits(sel4_config) as u8 {
58 | "Page(4 KiB)"
59 | } else if frame.size_bits == PageSize::Large.fixed_size_bits(sel4_config) as u8 {
60 | "Page(2 MiB)"
61 | } else {
62 | unreachable!("unknown frame size bits {}", frame.size_bits);
63 | }
64 | }
65 | Object::PageTable(_) => "PageTable",
66 | Object::AsidPool(_) => "AsidPool",
67 | Object::ArmIrq(_) => "ARM IRQ",
68 | Object::IrqMsi(_) => "x86 MSI IRQ",
69 | Object::IrqIOApic(_) => "x86 IOAPIC IRQ",
70 | Object::RiscvIrq(_) => "RISC-V IRQ",
71 | Object::IOPorts(_) => "x86 I/O Ports",
72 | Object::SchedContext(_) => "SchedContext",
73 | Object::Reply => "Reply",
74 | Object::ArmSmc => "ARM SMC",
75 | Object::Untyped(_) => "Untyped",
76 | Object::Irq(_) => "IRQ",
77 | }
78 | }
79 |
80 | pub fn capdl_cap_badge(cap: &Cap) -> Option {
81 | match cap {
82 | Cap::Endpoint(endpoint) => Some(endpoint.badge),
83 | Cap::Notification(notification) => Some(notification.badge),
84 | _ => None,
85 | }
86 | }
87 |
88 | pub fn capdl_cap_rights(cap: &Cap) -> Option {
89 | match cap {
90 | Cap::Endpoint(endpoint) => Some(endpoint.rights),
91 | Cap::Notification(notification) => Some(notification.rights),
92 | Cap::Frame(frame) => Some(frame.rights),
93 | _ => None,
94 | }
95 | }
96 |
97 | pub fn capdl_rights_to_human_repr(rights: &Rights) -> String {
98 | let mut repr: String = "".into();
99 |
100 | if rights.read {
101 | repr += "Read, ";
102 | }
103 | if rights.write {
104 | repr += "Write, ";
105 | }
106 | if rights.grant {
107 | repr += "Grant, ";
108 | }
109 | if rights.grant_reply {
110 | repr += "Grant Reply, ";
111 | }
112 |
113 | repr.pop();
114 | repr.pop();
115 |
116 | repr
117 | }
118 |
--------------------------------------------------------------------------------
/loader/src/aarch64/exceptions.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #pragma once
9 |
10 | #include
11 |
12 | /** Called from assembly **/
13 | void exception_handler(uintptr_t ex);
14 |
15 | static inline const char *ex_to_string(uintptr_t ex)
16 | {
17 | switch (ex) {
18 | case 0:
19 | return "Synchronous (Current Exception level with SP_EL0)";
20 | case 1:
21 | return "IRQ (Current Exception level with SP_EL0)";
22 | case 2:
23 | return "FIQ (Current Exception level with SP_EL0)";
24 | case 3:
25 | return "SError (Current Exception level with SP_EL0)";
26 | case 4:
27 | return "Synchronous (Current Exception level with SP_ELx)";
28 | case 5:
29 | return "IRQ (Current Exception level with SP_ELx)";
30 | case 6:
31 | return "FIQ (Current Exception level with SP_ELx)";
32 | case 7:
33 | return "SError (Current Exception level with SP_ELx)";
34 | case 8:
35 | return "Synchronous 64-bit EL0";
36 | case 9:
37 | return "IRQ 64-bit EL0";
38 | case 10:
39 | return "FIQ 64-bit EL0";
40 | case 11:
41 | return "SError 64-bit EL0";
42 | case 12:
43 | return "Synchronous 32-bit EL0";
44 | case 13:
45 | return "IRQ 32-bit EL0";
46 | case 14:
47 | return "FIQ 32-bit EL0";
48 | case 15:
49 | return "SError 32-bit EL0";
50 | }
51 | return "";
52 | }
53 |
54 | static inline const char *ec_to_string(uintptr_t ec)
55 | {
56 | switch (ec) {
57 | case 0:
58 | return "Unknown reason";
59 | case 1:
60 | return "Trapped WFI or WFE instruction execution";
61 | case 3:
62 | return "Trapped MCR or MRC access with (coproc==0b1111) this is not reported using EC 0b000000";
63 | case 4:
64 | return "Trapped MCRR or MRRC access with (coproc==0b1111) this is not reported using EC 0b000000";
65 | case 5:
66 | return "Trapped MCR or MRC access with (coproc==0b1110)";
67 | case 6:
68 | return "Trapped LDC or STC access";
69 | case 7:
70 | return "Access to SVC, Advanced SIMD or floating-point functionality trapped";
71 | case 12:
72 | return "Trapped MRRC access with (coproc==0b1110)";
73 | case 13:
74 | return "Branch Target Exception";
75 | case 17:
76 | return "SVC instruction execution in AArch32 state";
77 | case 21:
78 | return "SVC instruction execution in AArch64 state";
79 | case 24:
80 | return "Trapped MSR, MRS or System instruction exuection in AArch64 state, this is not reported using EC 0xb000000, 0b000001 or 0b000111";
81 | case 25:
82 | return "Access to SVE functionality trapped";
83 | case 28:
84 | return "Exception from a Pointer Authentication instruction authentication failure";
85 | case 32:
86 | return "Instruction Abort from a lower Exception level";
87 | case 33:
88 | return "Instruction Abort taken without a change in Exception level";
89 | case 34:
90 | return "PC alignment fault exception";
91 | case 36:
92 | return "Data Abort from a lower Exception level";
93 | case 37:
94 | return "Data Abort taken without a change in Exception level";
95 | case 38:
96 | return "SP alignment faultr exception";
97 | case 40:
98 | return "Trapped floating-point exception taken from AArch32 state";
99 | case 44:
100 | return "Trapped floating-point exception taken from AArch64 state";
101 | case 47:
102 | return "SError interrupt";
103 | case 48:
104 | return "Breakpoint exception from a lower Exception level";
105 | case 49:
106 | return "Breakpoint exception taken without a change in Exception level";
107 | case 50:
108 | return "Software Step exception from a lower Exception level";
109 | case 51:
110 | return "Software Step exception taken without a change in Exception level";
111 | case 52:
112 | return "Watchpoint exception from a lower Exception level";
113 | case 53:
114 | return "Watchpoint exception taken without a change in Exception level";
115 | case 56:
116 | return "BKPT instruction execution in AArch32 state";
117 | case 60:
118 | return "BRK instruction execution in AArch64 state";
119 | }
120 | return "";
121 | }
122 |
--------------------------------------------------------------------------------
/libmicrokit/src/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 | #include
7 | #include
8 | #include
9 |
10 | #define __thread
11 | #include
12 |
13 | #include
14 |
15 | #define INPUT_CAP 1
16 | #define REPLY_CAP 4
17 |
18 | #define PD_MASK 0xff
19 | #define CHANNEL_MASK 0x3f
20 |
21 | /* All globals are prefixed with microkit_* to avoid clashes with user defined globals. */
22 |
23 | bool microkit_passive;
24 | char microkit_name[MICROKIT_PD_NAME_LENGTH];
25 | /* We use seL4 typedefs as this variable is exposed to the libmicrokit header
26 | * and we do not want to rely on compiler built-in defines. */
27 | seL4_Bool microkit_have_signal = seL4_False;
28 | seL4_CPtr microkit_signal_cap;
29 | seL4_MessageInfo_t microkit_signal_msg;
30 |
31 | seL4_Word microkit_irqs;
32 | seL4_Word microkit_notifications;
33 | seL4_Word microkit_pps;
34 | seL4_Word microkit_ioports;
35 |
36 | extern seL4_IPCBuffer __sel4_ipc_buffer_obj;
37 |
38 | seL4_IPCBuffer *__sel4_ipc_buffer = &__sel4_ipc_buffer_obj;
39 |
40 | extern const void (*const __init_array_start [])(void);
41 | extern const void (*const __init_array_end [])(void);
42 |
43 | __attribute__((weak)) microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo)
44 | {
45 | microkit_dbg_puts(microkit_name);
46 | microkit_dbg_puts(" is missing the 'protected' entry point\n");
47 | microkit_internal_crash(0);
48 | return seL4_MessageInfo_new(0, 0, 0, 0);
49 | }
50 |
51 | __attribute__((weak)) seL4_Bool fault(microkit_child child, microkit_msginfo msginfo, microkit_msginfo *reply_msginfo)
52 | {
53 | microkit_dbg_puts(microkit_name);
54 | microkit_dbg_puts(" is missing the 'fault' entry point\n");
55 | microkit_internal_crash(0);
56 | return seL4_False;
57 | }
58 |
59 | static void run_init_funcs(void)
60 | {
61 | size_t count = __init_array_end - __init_array_start;
62 | for (size_t i = 0; i < count; i++) {
63 | __init_array_start[i]();
64 | }
65 | }
66 |
67 | static void handler_loop(void)
68 | {
69 | bool have_reply = false;
70 | seL4_MessageInfo_t reply_tag;
71 |
72 | /**
73 | * Because of https://github.com/seL4/seL4/issues/1536
74 | * let's acknowledge all the IRQs after we've started.
75 | */
76 | {
77 | seL4_Word irqs_to_ack = microkit_irqs;
78 | unsigned int idx = 0;
79 | do {
80 | if (irqs_to_ack & 1) {
81 | microkit_irq_ack(idx);
82 | }
83 |
84 | irqs_to_ack >>= 1;
85 | idx++;
86 | } while (irqs_to_ack != 0);
87 | }
88 |
89 | for (;;) {
90 | seL4_Word badge;
91 | seL4_MessageInfo_t tag;
92 |
93 | if (have_reply) {
94 | tag = seL4_ReplyRecv(INPUT_CAP, reply_tag, &badge, REPLY_CAP);
95 | } else if (microkit_have_signal) {
96 | tag = seL4_NBSendRecv(microkit_signal_cap, microkit_signal_msg, INPUT_CAP, &badge, REPLY_CAP);
97 | microkit_have_signal = seL4_False;
98 | } else {
99 | tag = seL4_Recv(INPUT_CAP, &badge, REPLY_CAP);
100 | }
101 |
102 | uint64_t is_endpoint = badge >> 63;
103 | uint64_t is_fault = (badge >> 62) & 1;
104 |
105 | have_reply = false;
106 |
107 | if (is_fault) {
108 | seL4_Bool reply_to_fault = fault(badge & PD_MASK, tag, &reply_tag);
109 | if (reply_to_fault) {
110 | have_reply = true;
111 | }
112 | } else if (is_endpoint) {
113 | have_reply = true;
114 | reply_tag = protected(badge & CHANNEL_MASK, tag);
115 | } else {
116 | unsigned int idx = 0;
117 | do {
118 | if (badge & 1) {
119 | notified(idx);
120 | }
121 | badge >>= 1;
122 | idx++;
123 | } while (badge != 0);
124 | }
125 | }
126 | }
127 |
128 | void main(void)
129 | {
130 | run_init_funcs();
131 | init();
132 |
133 | /*
134 | * If we are passive, now our initialisation is complete we can
135 | * signal the monitor to unbind our scheduling context and bind
136 | * it to our notification object.
137 | * We delay this signal so we are ready waiting on a recv() syscall
138 | */
139 | if (microkit_passive) {
140 | microkit_have_signal = seL4_True;
141 | microkit_signal_msg = seL4_MessageInfo_new(0, 0, 0, 0);
142 | microkit_signal_cap = MONITOR_EP;
143 | }
144 |
145 | handler_loop();
146 | }
147 |
--------------------------------------------------------------------------------
/loader/src/riscv/cpus.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include "../cpus.h"
11 | #include "../cutil.h"
12 | #include "../loader.h"
13 | #include "../uart.h"
14 | #include "sbi.h"
15 |
16 | /*
17 | * On RISC-V the hart IDs represent any hardware thread in the system, including
18 | * ones that we do not intend to run on.
19 | * Typically the main CPU may have something like 4 cores that we intend to run
20 | * seL4 on but an additional S-mode only monitor core, this is the case on certain
21 | * CPUs such as the SiFive U74. The problematic part is that the monitor core has
22 | * a hart ID of zero and hart IDs are not guaranteed to be contiguous.
23 | * This is why we must explitly list all the hart IDs that we want to boot on.
24 | * To figure this out for your platform, the best way is to look at the Device Tree,
25 | * each CPU will have a 'reg' field where the value is the hart ID.
26 | */
27 | #if defined(CONFIG_PLAT_STAR64)
28 | static const uint64_t hart_ids[4] = {0x1, 0x2, 0x3, 0x4};
29 | #elif defined(CONFIG_PLAT_QEMU_RISCV_VIRT) || defined(CONFIG_PLAT_HIFIVE_P550)
30 | static const uint64_t hart_ids[4] = {0x0, 0x1, 0x2, 0x3};
31 | #else
32 |
33 | _Static_assert(!is_set(CONFIG_ENABLE_SMP_SUPPORT),
34 | "unknown board fallback not allowed for smp targets; " \
35 | "please define hart_ids");
36 |
37 | static const size_t hart_ids[1] = { CONFIG_FIRST_HART_ID };
38 | #endif
39 |
40 | _Static_assert(NUM_ACTIVE_CPUS <= ARRAY_SIZE(hart_ids),
41 | "active CPUs cannot be more than available CPUs");
42 |
43 | void plat_save_hw_id(int logical_cpu, uint64_t hart_id)
44 | {
45 | /** RISC-V appears to be nice and the hart_id given by the entrypoint
46 | * should always match that of the IDs we use to start it. Here we don't
47 | * need to do anything, but we can check that we are correct
48 | **/
49 |
50 | if (hart_ids[logical_cpu] != hart_id) {
51 | LDR_PRINT("ERROR", logical_cpu, "runtime hart id ");
52 | puthex64(hart_id);
53 | puts("does not match build-time value ");
54 | puthex64(hart_ids[logical_cpu]);
55 | puts("\n");
56 |
57 | for (;;) {}
58 | }
59 | }
60 |
61 | uint64_t plat_get_hw_id(int logical_cpu)
62 | {
63 | return hart_ids[logical_cpu];
64 | }
65 |
66 | /** defined in crt0.S */
67 | extern char riscv_secondary_cpu_entry_asm[1];
68 | /** called from crt0.S */
69 | void riscv_secondary_cpu_entry(uint64_t hart_id, int logical_cpu);
70 |
71 | void riscv_secondary_cpu_entry(uint64_t hart_id, int logical_cpu)
72 | {
73 | LDR_PRINT("INFO", logical_cpu, "secondary CPU entry with hart id ");
74 | puthex64(hart_id);
75 | puts("\n");
76 |
77 | if (logical_cpu == 0) {
78 | LDR_PRINT("ERROR", logical_cpu, "secondary CPU should not have logical id 0!!!\n");
79 | goto fail;
80 | } else if (logical_cpu >= NUM_ACTIVE_CPUS) {
81 | LDR_PRINT("ERROR", logical_cpu, "secondary CPU should not be >NUM_ACTIVE_CPUS\n");
82 | goto fail;
83 | }
84 |
85 | start_kernel(logical_cpu);
86 |
87 | fail:
88 | for (;;) {}
89 | }
90 |
91 | int plat_start_cpu(int logical_cpu)
92 | {
93 | LDR_PRINT("INFO", 0, "starting CPU ");
94 | putdecimal(logical_cpu);
95 | puts("\n");
96 |
97 | if (logical_cpu >= NUM_ACTIVE_CPUS) {
98 | LDR_PRINT("ERROR", 0, "starting a CPU with number above the active CPU count\n");
99 | return 1;
100 | }
101 |
102 | uint64_t *stack_base = _stack[logical_cpu];
103 | /* riscv expects stack to be 128-bit (16 byte) aligned, and we push to the stack
104 | to have space for the arguments to the entrypoint */
105 | uint64_t *sp = (uint64_t *)((uintptr_t)stack_base + STACK_SIZE - 2 * sizeof(uint64_t));
106 | /* store the logical cpu on the stack */
107 | sp[0] = logical_cpu;
108 | /* zero out what was here before */
109 | sp[1] = 0;
110 |
111 | uint64_t hart_id = plat_get_hw_id(logical_cpu);
112 |
113 | struct sbi_ret ret = sbi_call(
114 | SBI_HSM_EID,
115 | SBI_HSM_HART_START_FID,
116 | /* hartid */ hart_id,
117 | /* start_addr */ (uint64_t)riscv_secondary_cpu_entry_asm,
118 | /* opaque */ (uint64_t)sp,
119 | /* unused for this call */ 0, 0, 0);
120 |
121 | if (ret.error != SBI_SUCCESS) {
122 | LDR_PRINT("ERROR", 0, "could not start CPU, SBI call returned: ");
123 | puts(sbi_error_as_string(ret.error));
124 | puts("\n");
125 | }
126 |
127 | return 0;
128 | }
129 |
--------------------------------------------------------------------------------
/loader/src/aarch64/smc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025, UNSW.
3 | *
4 | * SPDX-License-Identifier: BSD-2-Clause
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include "../cutil.h"
12 | #include "../uart.h"
13 |
14 | /**
15 | * The Power State Coordinate Interface (DEN0022F.b) document in §5.2.1
16 | * specifies that
17 | *
18 | * For PSCI functions that use only 32-bit parameters, the arguments are
19 | * passed in R0 to R3 (AArch32) or W0 to W3 (AArch64), with return values
20 | * in R0 or W0. For versions using 64-bit parameters, the arguments are
21 | * passed in X0 to X3, with return values in X0. In line with the SMC
22 | * Calling Conventions, the immediate value used with an SMC (or HVC)
23 | * instruction must be 0.
24 | *
25 | * Hence we need both the SMC64 and SMC32 conventions implemented, with support
26 | * for up to 3 arguments.
27 | *
28 | * Table 5 Return error codes gives the error codes.
29 | * Errors are 32-bit signed integers for SMC32 functions, and 64-bit signed integers for SMC64 functions
30 | **/
31 |
32 | #define PSCI_RETURN_SUCCESS 0
33 | #define PSCI_RETURN_NOT_SUPPORTED -1
34 | #define PSCI_RETURN_INVALID_PARAMETERS -2
35 | #define PSCI_RETURN_DENIED -3
36 | #define PSCI_RETURN_ALREADY_ON -4
37 | #define PSCI_RETURN_ON_PENDING -5
38 | #define PSCI_RETURN_INTERNAL_FAILURE -6
39 | #define PSCI_RETURN_NOT_PRESENT -7
40 | #define PSCI_RETURN_DISABLED -8
41 | #define PSCI_RETURN_INVALID_ADDRESS -9
42 |
43 | /* this is fine for both 64-bit and 32-bit return codes as a 0xFFFFFFFF'XXXXXXXX code
44 | will get truncated to the 0xXXXXXXXX which is still -1 as 32-bit */
45 | static inline const char *psci_return_as_string(uint32_t ret)
46 | {
47 | switch (ret) {
48 | case PSCI_RETURN_SUCCESS:
49 | return "SUCCESS";
50 | case PSCI_RETURN_NOT_SUPPORTED:
51 | return "NOT_SUPPORTED";
52 | case PSCI_RETURN_INVALID_PARAMETERS:
53 | return "INVALID_PARAMETERS";
54 | case PSCI_RETURN_DENIED:
55 | return "DENIED";
56 | case PSCI_RETURN_ALREADY_ON:
57 | return "ALREADY_ON";
58 | case PSCI_RETURN_ON_PENDING:
59 | return "ON_PENDING";
60 | case PSCI_RETURN_INTERNAL_FAILURE:
61 | return "INTERNAL_FAILURE";
62 | case PSCI_RETURN_NOT_PRESENT:
63 | return "NOT_PRESENT";
64 | case PSCI_RETURN_DISABLED:
65 | return "DISABLED";
66 | case PSCI_RETURN_INVALID_ADDRESS:
67 | return "INVALID_ADDRESS";
68 | default:
69 | return "";
70 | }
71 | }
72 |
73 | /* §5.1.4 of PSCI */
74 | #define PSCI_FUNCTION_VERSION 0x84000000
75 | #define PSCI_FUNCTION_CPU_ON 0xC4000003
76 |
77 | /**
78 | * See document DEN002E SMC Calling Convention (v1.4, May 2022),
79 | * specifically §2.7 "SMC64/HVC64 argument passing".
80 | *
81 | * We only support up to 4 arguments, but the actual convention supports up
82 | * to 17, and clobbers X4--X17. The convention also supports up to 17 returns,
83 | * but we again only support 1.
84 | *
85 | **/
86 | static inline uint64_t arm_smc64_call(uint32_t function_id, uint64_t arg0, uint64_t arg1, uint64_t arg2)
87 | {
88 | // Per Table 2-1, BIT(30)==1 defines the SMC64 calling convention
89 | if ((function_id & BIT(30)) == 0) {
90 | puts("LDR|ERROR: SMC32 function used in SMC64 call\n");
91 | return PSCI_RETURN_INVALID_PARAMETERS;
92 | }
93 |
94 | register uint64_t x0 asm("x0") = function_id;
95 | register uint64_t x1 asm("x1") = arg0;
96 | register uint64_t x2 asm("x2") = arg1;
97 | register uint64_t x3 asm("x3") = arg2;
98 | asm volatile(
99 | "smc #0\n"
100 | : "=r"(x0)
101 | : "r"(x0), "r"(x1), "r"(x2), "r"(x3)
102 | : "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",
103 | "memory"
104 | );
105 |
106 | return x0;
107 | }
108 |
109 | /**
110 | * Reference 2.6 "SMC32/HVC32 argument passing".
111 | **/
112 | static inline uint32_t arm_smc32_call(uint32_t function_id, uint32_t arg0, uint32_t arg1, uint32_t arg2)
113 | {
114 | // Per Table 2-1, BIT(30)==0 defines the SMC32 calling convention
115 | if ((function_id & BIT(30)) == BIT(30)) {
116 | puts("LDR|ERROR: SMC64 function used in SMC32 call\n");
117 | return PSCI_RETURN_INVALID_PARAMETERS;
118 | }
119 | // TODO: This only supports AArch64 mode for the moment, in AArch32 mode
120 | // we need to use the x... registers.
121 |
122 | register uint64_t w0 asm("w0") = function_id;
123 | register uint64_t w1 asm("w1") = arg0;
124 | register uint64_t w2 asm("w2") = arg1;
125 | register uint64_t w3 asm("w3") = arg2;
126 | asm volatile(
127 | "smc #0\n"
128 | : "=r"(w0)
129 | : "r"(w0), "r"(w1), "r"(w2), "r"(w3)
130 | : "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", "w16", "w17",
131 | "memory"
132 | );
133 |
134 | return w0;
135 | }
136 |
--------------------------------------------------------------------------------
/tool/microkit/src/capdl/initialiser.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | use std::ops::Range;
8 |
9 | use rkyv::util::AlignedVec;
10 |
11 | use crate::elf::ElfSegmentData;
12 | use crate::util::round_up;
13 | use crate::{elf::ElfFile, sel4::PageSize};
14 | use crate::{serialise_ut, UntypedObject};
15 |
16 | // Page size used for allocating the spec and embedded frames segments.
17 | pub const INITIALISER_GRANULE_SIZE: PageSize = PageSize::Small;
18 |
19 | pub struct CapDLInitialiserSpecMetadata {
20 | pub spec_size: u64,
21 | }
22 |
23 | #[repr(u8)]
24 | #[derive(Debug, Clone, Copy)]
25 | pub enum LogLevel {
26 | Error = 1,
27 | Warn = 2,
28 | Info = 3,
29 | Debug = 4,
30 | Trace = 5,
31 | }
32 |
33 | pub struct CapDLInitialiser {
34 | pub elf: ElfFile,
35 | pub phys_base: Option,
36 | pub spec_metadata: Option,
37 | /// Log level of initialiser printing in debug mode.
38 | pub log_level: LogLevel,
39 | }
40 |
41 | impl CapDLInitialiser {
42 | pub fn new(elf: ElfFile) -> CapDLInitialiser {
43 | CapDLInitialiser {
44 | elf,
45 | phys_base: None,
46 | spec_metadata: None,
47 | log_level: LogLevel::Info,
48 | }
49 | }
50 |
51 | pub fn image_bound(&self) -> Range {
52 | self.elf.lowest_vaddr()..round_up(self.elf.highest_vaddr(), INITIALISER_GRANULE_SIZE as u64)
53 | }
54 |
55 | pub fn add_spec(&mut self, spec_payload: AlignedVec, embedded_frame_data: Vec) {
56 | if self.spec_metadata.is_some() {
57 | self.elf.segments.pop();
58 | self.elf.segments.pop();
59 | self.spec_metadata = None;
60 | }
61 |
62 | let spec_vaddr = self.elf.next_vaddr(INITIALISER_GRANULE_SIZE);
63 | let spec_size = spec_payload.len() as u64;
64 | self.elf.add_segment(
65 | true,
66 | false,
67 | false,
68 | spec_vaddr,
69 | ElfSegmentData::RealData(spec_payload.into()),
70 | );
71 |
72 | let embedded_frame_data_vaddr = self.elf.next_vaddr(INITIALISER_GRANULE_SIZE);
73 | self.elf.add_segment(
74 | true,
75 | false,
76 | false,
77 | embedded_frame_data_vaddr,
78 | ElfSegmentData::RealData(embedded_frame_data),
79 | );
80 |
81 | // These symbol names must match rust-sel4/crates/sel4-capdl-initializer/src/main.rs
82 | self.elf
83 | .write_symbol(
84 | "sel4_capdl_initializer_embedded_frames_data_start",
85 | &embedded_frame_data_vaddr.to_le_bytes(),
86 | )
87 | .unwrap();
88 |
89 | self.elf
90 | .write_symbol(
91 | "sel4_capdl_initializer_serialized_spec_data_start",
92 | &spec_vaddr.to_le_bytes(),
93 | )
94 | .unwrap();
95 | self.elf
96 | .write_symbol(
97 | "sel4_capdl_initializer_serialized_spec_data_size",
98 | &spec_size.to_le_bytes(),
99 | )
100 | .unwrap();
101 |
102 | self.elf
103 | .write_symbol(
104 | "sel4_capdl_initializer_image_start",
105 | &self.elf.lowest_vaddr().to_le_bytes(),
106 | )
107 | .unwrap();
108 | self.elf
109 | .write_symbol(
110 | "sel4_capdl_initializer_image_end",
111 | &self.elf.highest_vaddr().to_le_bytes(),
112 | )
113 | .unwrap();
114 |
115 | self.spec_metadata = Some(CapDLInitialiserSpecMetadata { spec_size });
116 | }
117 |
118 | pub fn spec_metadata(&self) -> &Option {
119 | &self.spec_metadata
120 | }
121 |
122 | pub fn add_expected_untypeds(&mut self, untypeds: &[UntypedObject]) {
123 | let mut uts_desc: Vec = Vec::new();
124 | for ut in untypeds.iter() {
125 | uts_desc.extend(serialise_ut(ut));
126 | }
127 |
128 | // This feature is currently not in mainline rust-seL4, keep it around for potential
129 | // debugging purposes.
130 | if self
131 | .elf
132 | .find_symbol("sel4_capdl_initializer_expected_untypeds_list_num_entries")
133 | .is_ok()
134 | {
135 | self.elf
136 | .write_symbol(
137 | "sel4_capdl_initializer_expected_untypeds_list_num_entries",
138 | &(untypeds.len() as u64).to_le_bytes(),
139 | )
140 | .unwrap();
141 | self.elf
142 | .write_symbol("sel4_capdl_initializer_expected_untypeds_list", &uts_desc)
143 | .unwrap();
144 | }
145 | }
146 |
147 | pub fn set_phys_base(&mut self, phys_base: u64) {
148 | self.phys_base = Some(phys_base);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/loader/src/aarch64/init.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Breakaway Consulting Pty. Ltd.
3 | * Copyright 2025, UNSW
4 | *
5 | * SPDX-License-Identifier: BSD-2-Clause
6 | */
7 |
8 | #include "../arch.h"
9 | #include "../loader.h"
10 | #include "../uart.h"
11 | #include "el.h"
12 | #include "smc.h"
13 |
14 | #include
15 |
16 | #if defined(CONFIG_PLAT_ZYNQMP_ZCU102) || defined(CONFIG_PLAT_ZYNQMP_ULTRA96V2)
17 | #define GICD_BASE 0x00F9010000UL
18 | #define GICC_BASE 0x00F9020000UL
19 | #elif defined(CONFIG_PLAT_QEMU_ARM_VIRT)
20 | #define GICD_BASE 0x8000000UL
21 | #define GICC_BASE 0x8010000UL
22 | #endif
23 |
24 | #if defined(CONFIG_PLAT_ZYNQMP_ZCU102) || defined(CONFIG_PLAT_ZYNQMP_ULTRA96V2) || defined(CONFIG_PLAT_QEMU_ARM_VIRT)
25 | static void configure_gicv2(void)
26 | {
27 | /* The ZCU102 start in EL3, and then we drop to EL1(NS).
28 | *
29 | * The GICv2 supports security extensions (as does the CPU).
30 | *
31 | * The GIC sets any interrupt as either Group 0 or Group 1.
32 | * A Group 0 interrupt can only be configured in secure mode,
33 | * while Group 1 interrupts can be configured from non-secure mode.
34 | *
35 | * As seL4 runs in non-secure mode, and we want seL4 to have
36 | * the ability to configure interrupts, at this point we need
37 | * to put all interrupts into Group 1.
38 | *
39 | * GICD_IGROUPn starts at offset 0x80.
40 | *
41 | * 0xF901_0000.
42 | *
43 | * Future work: On multicore systems the distributor setup
44 | * only needs to be called once, while the GICC registers
45 | * should be set for each CPU.
46 | */
47 | puts("LDR|INFO: Setting all interrupts to Group 1\n");
48 | uint32_t gicd_typer = *((volatile uint32_t *)(GICD_BASE + 0x4));
49 | uint32_t it_lines_number = gicd_typer & 0x1f;
50 | puts("LDR|INFO: GICv2 ITLinesNumber: ");
51 | puthex32(it_lines_number);
52 | puts("\n");
53 |
54 | for (uint32_t i = 0; i <= it_lines_number; i++) {
55 | *((volatile uint32_t *)(GICD_BASE + 0x80 + (i * 4))) = 0xFFFFFFFF;
56 | }
57 |
58 | /* For any interrupts to go through the interrupt priority mask
59 | * must be set appropriately. Only interrupts with priorities less
60 | * than this mask will interrupt the CPU.
61 | *
62 | * seL4 (effectively) sets interrupts to priority 0x80, so it is
63 | * important to make sure this is greater than 0x80.
64 | */
65 | *((volatile uint32_t *)(GICC_BASE + 0x4)) = 0xf0;
66 | }
67 | #endif
68 |
69 | void el1_mmu_disable(void);
70 | void el2_mmu_disable(void);
71 |
72 | void arch_init(void)
73 | {
74 | #if defined(CONFIG_PLAT_ZYNQMP_ZCU102) || defined(CONFIG_PLAT_ZYNQMP_ULTRA96V2) || defined(CONFIG_PLAT_QEMU_ARM_VIRT)
75 | configure_gicv2();
76 | #endif
77 |
78 | /* Disable the MMU, as U-Boot will start in virtual memory on some platforms
79 | * (https://docs.u-boot.org/en/latest/arch/arm64.html), which means that
80 | * certain physical memory addresses contain page table information which
81 | * the loader doesn't know about and would need to be careful not to
82 | * overwrite.
83 | *
84 | * This also means that we would need to worry about caching.
85 | * TODO: should we do that instead?
86 | * note the issues where it forces us to flush any shared addresses all the
87 | * way to cache as we might have mixed non-cached/cached access.
88 | */
89 | puts("LDR|INFO: disabling MMU (if it was enabled)\n");
90 | enum el el = current_el();
91 |
92 | if (el == EL1) {
93 | el1_mmu_disable();
94 | } else if (el == EL2) {
95 | el2_mmu_disable();
96 | } else {
97 | puts("LDR|ERROR: unknown EL level for MMU disable\n");
98 | }
99 |
100 | // TODO: handle non-PSCI platforms better, see https://github.com/seL4/microkit/issues/401.
101 | #if !defined(CONFIG_PLAT_BCM2711)
102 | uint32_t ret = arm_smc32_call(PSCI_FUNCTION_VERSION, /* unused */ 0, 0, 0);
103 | /* the return value has no error codes, but if we get it wrong this is what we will get */
104 | if (ret == PSCI_RETURN_NOT_SUPPORTED) {
105 | puts("LDR|ERROR: could not determine PSCI version: ");
106 | puts(psci_return_as_string(ret));
107 | puts("\n");
108 | } else {
109 | uint16_t major = (ret >> 16) & 0xffff;
110 | uint16_t minor = (ret >> 0) & 0xffff;
111 | puts("LDR|INFO: PSCI version is ");
112 | putdecimal(major);
113 | puts(".");
114 | putdecimal(minor);
115 | puts("\n");
116 | }
117 | #endif
118 | }
119 |
120 | typedef void (*sel4_entry)(
121 | uintptr_t ui_p_reg_start,
122 | uintptr_t ui_p_reg_end,
123 | intptr_t pv_offset,
124 | uintptr_t v_entry,
125 | uintptr_t dtb_addr_p,
126 | uintptr_t dtb_size
127 | );
128 |
129 | void arch_jump_to_kernel(int logical_cpu)
130 | {
131 | /* seL4 always expects the current logical CPU number in TPIDR_EL1 */
132 | asm volatile("msr TPIDR_EL1, %0" :: "r"(logical_cpu));
133 |
134 | ((sel4_entry)(loader_data->kernel_entry))(
135 | loader_data->ui_p_reg_start,
136 | loader_data->ui_p_reg_end,
137 | loader_data->pv_offset,
138 | loader_data->v_entry,
139 | 0,
140 | 0
141 | );
142 | }
143 |
--------------------------------------------------------------------------------
/tool/microkit/src/uimage.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025, UNSW
3 | //
4 | // SPDX-License-Identifier: BSD-2-Clause
5 | //
6 |
7 | // Document referenced:
8 | // U-Boot: include/image.h
9 | // Linux: https://www.kernel.org/doc/html/latest/arch/riscv/boot-image-header.html
10 |
11 | use crate::struct_to_bytes;
12 | use crate::{crc32::crc32, sel4::Arch};
13 | use std::fs::File;
14 | use std::io::Write;
15 |
16 | const UIMAGE_NAME: &str = "seL4 Microkit";
17 |
18 | // OS-type code
19 | const IH_OS_LINUX: u8 = 5;
20 |
21 | // CPU-arch codes
22 | const IH_ARCH_RISCV: u8 = 26;
23 |
24 | // Image-type code
25 | const IH_TYPE_KERNEL: u8 = 2;
26 |
27 | // No compression
28 | const IH_COMP_NONE: u8 = 0;
29 |
30 | // Image name length max
31 | const IH_NMLEN: usize = 32;
32 |
33 | // Image magic
34 | const IH_MAGIC: u32 = 0x27051956;
35 |
36 | #[repr(C, packed)]
37 | struct UbootLegacyImgHeader {
38 | ih_magic: u32, // Image Header Magic Number
39 | ih_hcrc: u32, // Image Header CRC Checksum
40 | ih_time: u32, // Image Creation Timestamp
41 | ih_size: u32, // Image Data Size
42 | ih_load: u32, // Data Load Address
43 | ih_ep: u32, // Entry Point Address
44 | ih_dcrc: u32, // Image Data CRC Checksum
45 | ih_os: u8, // Operating System
46 | ih_arch: u8, // CPU architecture
47 | ih_type: u8, // Image Type
48 | ih_comp: u8, // Compression Type
49 | ih_name: [u8; IH_NMLEN], // Image Name
50 | }
51 |
52 | // Bits 0:15 minor, bits 16:31 major
53 | // Linux defines this to be 0.2 currently
54 | const LINUX_RISCV_HEADER_VERSION: u32 = 2;
55 |
56 | const LINUX_RISCV_HEADER_MAGIC: u64 = 0x5643534952;
57 | const LINUX_RISCV_HEADER_MAGIC2: u32 = 0x05435352;
58 |
59 | #[repr(C, packed)]
60 | struct LinuxRiscvImageHeader {
61 | code0: u32,
62 | code1: u32,
63 | text_offset: u64, // Image load offset, little endian
64 | image_size: u64, // Effective Image size, little endian
65 | flags: u64, // kernel flags, little endian
66 | version: u32, // Version of this header
67 | res1: u32,
68 | res2: u64,
69 | magic: u64,
70 | magic2: u32,
71 | res3: u32,
72 | }
73 |
74 | pub fn uimage_serialise(
75 | arch: &Arch,
76 | entry: u32,
77 | executable_payload: Vec,
78 | path: &std::path::Path,
79 | ) -> Result {
80 | let ih_arch_le = match arch {
81 | Arch::Aarch64 => unreachable!("internal bug: unimplemented uImage creation for ARM"),
82 | Arch::Riscv64 => IH_ARCH_RISCV,
83 | Arch::X86_64 => unreachable!("internal bug: unimplemented uImage creation for x86"),
84 | };
85 |
86 | // We masquerade the Microkit loader as a Linux kernel to U-Boot, so that U-Boot follows
87 | // the Linux boot protocol and give us the HART ID in a0. If we pack the uImage as a generic `IH_OS_ELF`,
88 | // we won't get the HART ID which will be problematic for booting seL4.
89 | let linux_riscv_hdr = LinuxRiscvImageHeader {
90 | code0: 0,
91 | code1: 0,
92 | text_offset: 0,
93 | image_size: executable_payload.len() as u64,
94 | flags: 0, // little endian executable
95 | version: LINUX_RISCV_HEADER_VERSION,
96 | res1: 0,
97 | res2: 0,
98 | magic: LINUX_RISCV_HEADER_MAGIC,
99 | magic2: LINUX_RISCV_HEADER_MAGIC2,
100 | res3: 0,
101 | };
102 |
103 | let mut linux_image_payload = Vec::new();
104 | linux_image_payload.extend_from_slice(unsafe { struct_to_bytes(&linux_riscv_hdr) });
105 | linux_image_payload.extend_from_slice(executable_payload.as_slice());
106 |
107 | // The actual loader executable is after the Linux header, so we tell U-Boot to load the
108 | // uImage in a way that the loader always start at the physical address it expects.
109 | let load_paddr = entry - ::core::mem::size_of::() as u32;
110 |
111 | let mut hdr = UbootLegacyImgHeader {
112 | ih_magic: IH_MAGIC.to_be(),
113 | ih_hcrc: 0, // U-Boot clears this field before it recalculate the checksum, so do the same here
114 | ih_time: 0,
115 | ih_size: (linux_image_payload.len() as u32).to_be(),
116 | ih_load: load_paddr.to_be(),
117 | ih_ep: entry.to_be(),
118 | ih_dcrc: crc32(&linux_image_payload).to_be(),
119 | ih_os: IH_OS_LINUX.to_be(),
120 | ih_arch: ih_arch_le.to_be(),
121 | ih_type: IH_TYPE_KERNEL.to_be(),
122 | ih_comp: IH_COMP_NONE.to_be(),
123 | ih_name: [0; IH_NMLEN],
124 | };
125 |
126 | let hdr_name_cpy_dest = &mut hdr.ih_name[0..UIMAGE_NAME.len()];
127 | hdr_name_cpy_dest.copy_from_slice(UIMAGE_NAME.as_bytes());
128 |
129 | let hdr_chksum = unsafe { crc32(struct_to_bytes(&hdr)) };
130 | hdr.ih_hcrc = hdr_chksum.to_be();
131 |
132 | let mut uimage_file = match File::create(path) {
133 | Ok(file) => file,
134 | Err(e) => return Err(format!("cannot create '{}': {}", path.display(), e)),
135 | };
136 |
137 | uimage_file
138 | .write_all(unsafe { struct_to_bytes(&hdr) })
139 | .unwrap_or_else(|_| panic!("Failed to write uImage header for '{}'", path.display()));
140 |
141 | uimage_file
142 | .write_all(&linux_image_payload)
143 | .unwrap_or_else(|_| panic!("Failed to write payload for '{}'", path.display()));
144 |
145 | uimage_file.flush().unwrap();
146 |
147 | Ok(0)
148 | }
149 |
--------------------------------------------------------------------------------