Skip to content

Commit cfc61eb

Browse files
committed
example: add bootinfo example
This adds an example showing how to map a bootinfo-prefilled MR to a PD. As the DTB is not passed through by Microkit loader, it isn't obvious to demonstrate the feature on ARM and RISC-V. For x86, this example reads the TSC frequency and prints it. Signed-off-by: Terry Bai <tianyi.bai@unsw.edu.au>
1 parent 1d0ac93 commit cfc61eb

4 files changed

Lines changed: 160 additions & 0 deletions

File tree

example/bootinfo/Makefile

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#
2+
# Copyright 2026, 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+
TARGET_TRIPLE := x86_64-linux-gnu
28+
CFLAGS_ARCH := -march=x86-64 -mtune=generic
29+
KERNEL := $(BOARD_DIR)//elf/sel4.elf
30+
KERNEL_32B := $(BOARD_DIR)//elf/sel4_32.elf
31+
else
32+
$(error Unsupported ARCH)
33+
endif
34+
35+
ifeq ($(strip $(LLVM)),True)
36+
CC := clang -target $(TARGET_TRIPLE)
37+
AS := clang -target $(TARGET_TRIPLE)
38+
LD := ld.lld
39+
else
40+
CC := $(TARGET_TRIPLE)-gcc
41+
LD := $(TARGET_TRIPLE)-ld
42+
AS := $(TARGET_TRIPLE)-as
43+
endif
44+
45+
MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
46+
47+
IMAGES := bootinfo.elf
48+
CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
49+
LDFLAGS := -L$(BOARD_DIR)/lib
50+
LIBS := -lmicrokit -Tmicrokit.ld
51+
52+
IMAGE_FILE = $(BUILD_DIR)/loader.img
53+
REPORT_FILE = $(BUILD_DIR)/report.txt
54+
55+
all: $(IMAGE_FILE)
56+
57+
$(BUILD_DIR):
58+
mkdir -p $@
59+
60+
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
61+
$(CC) -c $(CFLAGS) $< -o $@
62+
63+
$(BUILD_DIR)/%.elf: $(BUILD_DIR)/%.o
64+
$(LD) $(LDFLAGS) $^ $(LIBS) -o $@
65+
66+
$(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) bootinfo.system
67+
$(MICROKIT_TOOL) bootinfo.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)
68+
69+
qemu: $(IMAGE_FILE) $(KERNEL_32B)
70+
ifeq ($(ARCH),x86_64)
71+
qemu-system-x86_64 \
72+
-cpu qemu64,+fsgsbase,+pdpe1gb,+xsaveopt,+xsave \
73+
-m "1G" \
74+
-display none \
75+
-serial mon:stdio \
76+
-kernel $(KERNEL_32B) \
77+
-initrd $(IMAGE_FILE)
78+
else
79+
$(error Unsupported ARCH)
80+
endif

example/bootinfo/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!--
2+
Copyright 2026, UNSW
3+
SPDX-License-Identifier: CC-BY-SA-4.0
4+
-->
5+
# Example - Hello World
6+
7+
This is a basic example that demonstrates how one can define
8+
a MemoryRegion prefilled with BootInfo and map it to a PD, so
9+
the PD can read the BootInfo in userland.
10+
11+
Supported BootInfo includes:
12+
- x86_vbe
13+
- x86_mbmap
14+
- x86_acpi_rsdp
15+
- x86_framebuffer
16+
- x86_tsc_freq
17+
18+
As Microkit loader does not pass the DTB through on ARM and RISC-V,
19+
so only x86 is supported in this example for now.
20+
21+
## Building
22+
23+
```sh
24+
mkdir build
25+
make BUILD_DIR=build MICROKIT_BOARD=<board> MICROKIT_CONFIG=<debug/release/benchmark> MICROKIT_SDK=/path/to/sdk qemu
26+
```
27+
28+
## Running
29+
30+
See instructions for your board in the manual.

example/bootinfo/bootinfo.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2026, UNSW
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
#include <stdint.h>
7+
#include <microkit.h>
8+
9+
#if defined(CONFIG_ARCH_X86_64)
10+
typedef struct {
11+
seL4_BootInfoHeader header;
12+
uint32_t value;
13+
} bootinfo_tsc_freq_t;
14+
bootinfo_tsc_freq_t *bootinfo_tsc_freq;
15+
#else
16+
#error "No example cases for this architecture"
17+
#endif
18+
19+
void init(void)
20+
{
21+
microkit_dbg_puts("====BootInfo====\n");
22+
#if defined(CONFIG_ARCH_X86_64)
23+
if (bootinfo_tsc_freq->header.len) {
24+
microkit_dbg_puts("TSC Frequency: ");
25+
microkit_dbg_put32(bootinfo_tsc_freq->value);
26+
microkit_dbg_puts("MHz\n");
27+
} else {
28+
microkit_dbg_puts("TSC Frequency is not found or prefilled properly.\n");
29+
}
30+
#else
31+
#error "No example cases for this architecture"
32+
#endif
33+
}
34+
35+
void notified(microkit_channel ch)
36+
{
37+
}

example/bootinfo/bootinfo.system

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2026, UNSW
4+
5+
SPDX-License-Identifier: BSD-2-Clause
6+
-->
7+
<system>
8+
<memory_region name="bootinfo_x86_tsc_freq" prefill_bootinfo="x86_tsc_freq" />
9+
<protection_domain name="bootinfo">
10+
<program_image path="bootinfo.elf" />
11+
<map mr="bootinfo_x86_tsc_freq" vaddr="0x2_000_000" perms="r" cached="true" setvar_vaddr="bootinfo_tsc_freq" />
12+
</protection_domain>
13+
</system>

0 commit comments

Comments
 (0)