diff --git a/examples/Kconfig b/examples/Kconfig
index 5738d555d22..7f099808908 100644
--- a/examples/Kconfig
+++ b/examples/Kconfig
@@ -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
diff --git a/examples/ulib/rust_demo.rs b/examples/ulib/rust_demo.rs
new file mode 100644
index 00000000000..7a85658520d
--- /dev/null
+++ b/examples/ulib/rust_demo.rs
@@ -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 {}
+}
diff --git a/scripts/Makefile.ulib-example b/scripts/Makefile.ulib-example
index 796b74b0c14..18d526f5b6b 100644
--- a/scripts/Makefile.ulib-example
+++ b/scripts/Makefile.ulib-example
@@ -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
