[Concept,04/13] ulib: Add Rust demo example
Commit Message
From: Simon Glass <simon.glass@canonical.com>
Add a #![no_std] Rust equivalent of the C ulib demo, compiled to an
object file with rustc and linked into U-Boot via the existing
u-boot-link mechanism. The Rust demo calls the same C helpers
(demo_show_banner, demo_show_footer, demo_add_numbers) via FFI and
produces identical output, so assert_demo_output() works unchanged.
Use core::ptr::addr_of!() rather than a reference cast to access the
extern static version_string, since the compiler cannot prove that an
extern static is non-null and would emit a call to an undefined panic
symbol.
Add CONFIG_RUST_EXAMPLES Kconfig option to gate the Rust examples.
When enabled, rustc must be available with the appropriate target for
the architecture.
Clear MAKEFLAGS when invoking rustc so that it does not inherit
make's --jobserver-auth file descriptors, which would produce a
spurious warning on every compilation.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
examples/Kconfig | 13 +++++++++
examples/ulib/rust_demo.rs | 55 +++++++++++++++++++++++++++++++++++
scripts/Makefile.ulib-example | 17 +++++++++++
3 files changed, 85 insertions(+)
create mode 100644 examples/ulib/rust_demo.rs
@@ -9,6 +9,19 @@ config EXAMPLES
U-Boot provides an legacy API for standalone applications. Examples
are provided in directory examples/.
+config RUST_EXAMPLES
+ bool "Build Rust example programs"
+ depends on EXAMPLES
+ help
+ Build example programs written in Rust alongside the C
+ examples. The Rust demo calls the same C helpers via FFI
+ and produces identical output.
+
+ Requires a Rust toolchain (rustc) with the appropriate
+ cross-compilation target for the architecture, e.g.
+ x86_64-unknown-none for x86_64 or aarch64-unknown-none
+ for ARM64.
+
config EXAMPLES_STANDALONE
bool "Compile standalone examples"
depends on !SANDBOX
new file mode 100644
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Rust demo program showing U-Boot library functionality
+//
+// Demonstrates calling C helper functions from Rust via FFI, producing
+// identical output to demo.c so assert_demo_output() works unchanged.
+//
+// Copyright 2026 Canonical Ltd.
+// Written by Simon Glass <simon.glass@canonical.com>
+
+#![no_std]
+#![no_main]
+
+use core::ffi::c_int;
+
+extern "C" {
+ fn printf(fmt: *const u8, ...) -> c_int;
+ fn demo_show_banner();
+ fn demo_show_footer();
+ fn demo_add_numbers(a: c_int, b: c_int) -> c_int;
+ static version_string: u8;
+}
+
+#[no_mangle]
+pub extern "C" fn ulib_has_main() -> bool {
+ true
+}
+
+fn demo_run() -> c_int {
+ unsafe {
+ demo_show_banner();
+ // Use addr_of!() rather than &version_string to avoid a
+ // null-pointer check: &T must be non-null, but the compiler
+ // cannot prove that for an extern static, so it emits a call
+ // to an undefined panic symbol that crashes ld.bfd on aarch64.
+ printf(
+ b"U-Boot version: %s\n\0".as_ptr(),
+ core::ptr::addr_of!(version_string),
+ );
+ printf(b"\n\0".as_ptr());
+ demo_add_numbers(42, 13);
+ demo_show_footer();
+ }
+ 0
+}
+
+#[no_mangle]
+pub extern "C" fn main() -> c_int {
+ demo_run()
+}
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+ loop {}
+}
@@ -19,11 +19,28 @@ PHONY += examples_$(EXAMPLE_ARCH)
ULIB_EXAMPLES := demo
+# --- Rust examples ---
+RUSTC := rustc
+RUST_TARGET := $(RUST_TARGET_$(EXAMPLE_ARCH))
+
+ifeq ($(CONFIG_RUST_EXAMPLES),y)
+ULIB_EXAMPLES += rust-demo
+endif
+
quiet_cmd_u-boot-example = LD $@
cmd_u-boot-example = $(call u-boot-link,$(example-objs),$@.map)
+quiet_cmd_rustc_obj = RUSTC $@
+ cmd_rustc_obj = \
+ mkdir -p $(dir $@) && \
+ MAKEFLAGS= $(RUSTC) --edition 2021 --emit=obj -o $@ --target=$(RUST_TARGET) $<
+
+examples/ulib/rust_demo.o: examples/ulib/rust_demo.rs FORCE
+ $(call if_changed,rustc_obj)
+
# Per-example object lists (matches examples/ulib/Kbuild)
example-demo-objs := examples/ulib/demo.o examples/ulib/demo_helper.o
+example-rust-demo-objs := examples/ulib/rust_demo.o examples/ulib/demo_helper.o
# Generate link rule for each example
define example_link_rule