mirror of
https://github.com/google/comprehensive-rust.git
synced 2026-06-21 00:12:59 +02:00
bazel: build and test bare-metal examples
This configures Bazel targets for the bare-metal examples. We now also
have test targets for them:
bazel test //:bare_metal_tests
will compile all the code and run a simple test in QEMU (boot the
binaries, send `"q"` to them on stdin).
The Cargo-based workflow has been kept: I expect that students will
keep using it in class, so we should keep testing it in CI.
This commit is contained in:
@@ -68,6 +68,24 @@ jobs:
|
|||||||
working-directory: ${{ matrix.directory }}
|
working-directory: ${{ matrix.directory }}
|
||||||
run: cargo build
|
run: cargo build
|
||||||
|
|
||||||
|
bare-metal-test:
|
||||||
|
name: Bare-metal tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Setup Bazel cache
|
||||||
|
uses: ./.github/workflows/setup-bazel-cache
|
||||||
|
|
||||||
|
- name: Install QEMU
|
||||||
|
uses: ./.github/workflows/apt-get-install
|
||||||
|
with:
|
||||||
|
packages: qemu-system-arm
|
||||||
|
|
||||||
|
- name: Run QEMU tests
|
||||||
|
run: bazel test //:bare_metal_tests
|
||||||
|
|
||||||
find-languages:
|
find-languages:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
"""Root BUILD file for Comprehensive Rust workspace.
|
||||||
|
|
||||||
|
This file defines a central test_suite for running manual QEMU tests.
|
||||||
|
"""
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
test_suite(
|
||||||
|
name = "bare_metal_tests",
|
||||||
|
tags = ["manual"],
|
||||||
|
tests = [
|
||||||
|
"//src/bare-metal/aps/examples:improved_test",
|
||||||
|
"//src/bare-metal/aps/examples:logger_test",
|
||||||
|
"//src/bare-metal/aps/examples:minimal_test",
|
||||||
|
"//src/bare-metal/aps/examples:psci_test",
|
||||||
|
"//src/bare-metal/aps/examples:rt_test",
|
||||||
|
"//src/bare-metal/aps/examples:safemmio_test",
|
||||||
|
"//src/exercises/bare-metal/rtc:rtc_test",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|||||||
@@ -282,3 +282,115 @@ Use `--mochaOpts.grep` to run a single test within a file:
|
|||||||
```bash
|
```bash
|
||||||
npm test -- --spec redbox --mochaOpts.grep "should be hidden by default"
|
npm test -- --spec redbox --mochaOpts.grep "should be hidden by default"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Bazel Bare-Metal and Microcontroller Integration
|
||||||
|
|
||||||
|
This project integrates Bazel rules for bare-metal AArch64 and microcontroller
|
||||||
|
target platforms. Key findings and conventions include:
|
||||||
|
|
||||||
|
### Checking Bazel Version
|
||||||
|
|
||||||
|
Always check the `.bazelversion` file at the workspace root (e.g., `9.1.1`)
|
||||||
|
before inspecting the host Bazel version.
|
||||||
|
|
||||||
|
### Target Platforms & Constraints
|
||||||
|
|
||||||
|
Bare-metal and microcontroller examples specify target CPU/OS constraint
|
||||||
|
configurations (e.g., `os:none`):
|
||||||
|
|
||||||
|
- `aarch64-unknown-none`: Mapped in `platforms/BUILD.bazel` to
|
||||||
|
`@platforms//os:none` and `@platforms//cpu:aarch64`.
|
||||||
|
- `thumbv7em-none-eabihf`: Mapped to `@platforms//os:none` and
|
||||||
|
`@platforms//cpu:armv7e-mf` (matching rules_rust's internal CPU naming
|
||||||
|
convention).
|
||||||
|
|
||||||
|
### Wildcard Host Builds & Compatibility
|
||||||
|
|
||||||
|
To prevent raw target compilation failures during wildcard host commands (like
|
||||||
|
`bazel build //...` or `bazel test //...`), all target-specific `rust_binary`
|
||||||
|
targets declare compatibility constraints:
|
||||||
|
|
||||||
|
```bazel
|
||||||
|
rust_binary(
|
||||||
|
name = "my_target",
|
||||||
|
...
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
This causes Bazel to automatically skip building these targets on host
|
||||||
|
configurations (where OS is Linux/macOS) instead of failing.
|
||||||
|
|
||||||
|
### Cargo Universe Imports & Host Splicing
|
||||||
|
|
||||||
|
When importing external crates via `rules_rust`'s Cargo Universe
|
||||||
|
(`crate.from_cargo`), the host platform triple (e.g.,
|
||||||
|
`x86_64-unknown-linux-gnu`) must be included in `supported_platform_triples`:
|
||||||
|
|
||||||
|
```bazel
|
||||||
|
crate.from_cargo(
|
||||||
|
...
|
||||||
|
supported_platform_triples = [
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
"aarch64-unknown-none",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Even if the imported dependencies are purely for bare-metal targets,
|
||||||
|
`cargo-bazel` runs on the host during the splicing phase and invokes
|
||||||
|
`cargo tree` to perform feature and dependency resolution. Excluding the host
|
||||||
|
execution platform triple prevents Bazel from resolving a host cargo toolchain,
|
||||||
|
resulting in feature generation failures during the analysis phase.
|
||||||
|
|
||||||
|
### Hermetic Binary Extraction (Objcopy)
|
||||||
|
|
||||||
|
Since host systems may lack target-specific `rust-objcopy` executables, the
|
||||||
|
extraction of `.bin` flat images is managed hermetically inside the Bazel
|
||||||
|
sandbox using a `genrule` target pointing to the nightly compiler's bundled
|
||||||
|
`rust-objcopy` tool:
|
||||||
|
|
||||||
|
```bazel
|
||||||
|
genrule(
|
||||||
|
name = "my_target_bin",
|
||||||
|
srcs = [":my_target"],
|
||||||
|
outs = ["my_target.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :my_target) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Host-Executed QEMU Tests, Runners & Platform Transitions
|
||||||
|
|
||||||
|
By default, Bazel test and binary runner targets run on the host system. Since
|
||||||
|
the target binaries require cross-compiling, we use Starlark configuration
|
||||||
|
transitions in `platforms/transition.bzl` (via rules like `aarch64_binary` or
|
||||||
|
`thumbv7em_binary`) to transition the target binary's compilation mode to the
|
||||||
|
target platform while letting the wrapper `sh_test` or `sh_binary` execute on
|
||||||
|
the host:
|
||||||
|
|
||||||
|
```bazel
|
||||||
|
# In platforms/transition.bzl:
|
||||||
|
def _aarch64_transition_impl(settings, attr):
|
||||||
|
return {"//command_line_option:platforms": ["//platforms:aarch64-unknown-none"]}
|
||||||
|
|
||||||
|
# In target BUILD.bazel:
|
||||||
|
aarch64_binary(
|
||||||
|
name = "my_target_bin_aarch64",
|
||||||
|
dep = ":my_target_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Automated host test (non-interactive, pipes 'q'):
|
||||||
|
sh_test(
|
||||||
|
name = "my_target_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
data = [":my_target_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Interactive host runner (run via `bazel run`):
|
||||||
|
sh_binary(
|
||||||
|
name = "my_target_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
data = [":my_target_bin_aarch64"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|||||||
@@ -3,12 +3,26 @@ module(
|
|||||||
version = "0.1.0",
|
version = "0.1.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bazel_dep(name = "platforms", version = "1.1.0")
|
||||||
bazel_dep(name = "rules_rust", version = "0.70.0")
|
bazel_dep(name = "rules_rust", version = "0.70.0")
|
||||||
|
bazel_dep(name = "rules_shell", version = "0.8.0")
|
||||||
bazel_dep(name = "toolchains_llvm", version = "1.7.0")
|
bazel_dep(name = "toolchains_llvm", version = "1.7.0")
|
||||||
|
|
||||||
|
# Remove when https://github.com/bazelbuild/rules_rust/pull/4019 is
|
||||||
|
# released and we update past version 0.70.0.
|
||||||
|
git_override(
|
||||||
|
module_name = "rules_rust",
|
||||||
|
commit = "d2d856d13f89f234298db1606ece7afd1c3eee1f",
|
||||||
|
remote = "https://github.com/bazelbuild/rules_rust.git",
|
||||||
|
)
|
||||||
|
|
||||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||||
rust.toolchain(
|
rust.toolchain(
|
||||||
edition = "2024",
|
edition = "2024",
|
||||||
|
extra_target_triples = [
|
||||||
|
"aarch64-unknown-none",
|
||||||
|
"thumbv7em-none-eabihf",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
use_repo(rust, "rust_toolchains")
|
use_repo(rust, "rust_toolchains")
|
||||||
|
|
||||||
@@ -87,3 +101,62 @@ crate.from_specs(
|
|||||||
host_tools = "@rust_host_tools_nightly",
|
host_tools = "@rust_host_tools_nightly",
|
||||||
)
|
)
|
||||||
use_repo(crate, "svgbob_plugin")
|
use_repo(crate, "svgbob_plugin")
|
||||||
|
|
||||||
|
# Bare-Metal and Microcontroller Examples
|
||||||
|
#
|
||||||
|
# Note: Host triple is required in supported_platform_triples below so
|
||||||
|
# cargo-bazel can invoke cargo tree on the host during splicing.
|
||||||
|
crate.from_cargo(
|
||||||
|
name = "bare_metal_alloc_example",
|
||||||
|
cargo_lockfile = "//src/bare-metal/alloc-example:Cargo.lock",
|
||||||
|
manifests = ["//src/bare-metal/alloc-example:Cargo.toml"],
|
||||||
|
supported_platform_triples = [
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
"aarch64-unknown-none",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
use_repo(crate, "bare_metal_alloc_example")
|
||||||
|
|
||||||
|
crate.from_cargo(
|
||||||
|
name = "bare_metal_aps",
|
||||||
|
cargo_lockfile = "//src/bare-metal/aps/examples:Cargo.lock",
|
||||||
|
manifests = ["//src/bare-metal/aps/examples:Cargo.toml"],
|
||||||
|
supported_platform_triples = [
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
"aarch64-unknown-none",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
use_repo(crate, "bare_metal_aps")
|
||||||
|
|
||||||
|
crate.from_cargo(
|
||||||
|
name = "bare_metal_microcontrollers",
|
||||||
|
cargo_lockfile = "//src/bare-metal/microcontrollers/examples:Cargo.lock",
|
||||||
|
manifests = ["//src/bare-metal/microcontrollers/examples:Cargo.toml"],
|
||||||
|
supported_platform_triples = [
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
"thumbv7em-none-eabihf",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
use_repo(crate, "bare_metal_microcontrollers")
|
||||||
|
|
||||||
|
crate.from_cargo(
|
||||||
|
name = "bare_metal_compass",
|
||||||
|
cargo_lockfile = "//src/exercises/bare-metal/compass:Cargo.lock",
|
||||||
|
manifests = ["//src/exercises/bare-metal/compass:Cargo.toml"],
|
||||||
|
supported_platform_triples = [
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
"thumbv7em-none-eabihf",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
use_repo(crate, "bare_metal_compass")
|
||||||
|
|
||||||
|
crate.from_cargo(
|
||||||
|
name = "bare_metal_rtc",
|
||||||
|
cargo_lockfile = "//src/exercises/bare-metal/rtc:Cargo.lock",
|
||||||
|
manifests = ["//src/exercises/bare-metal/rtc:Cargo.toml"],
|
||||||
|
supported_platform_triples = [
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
"aarch64-unknown-none",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
use_repo(crate, "bare_metal_rtc")
|
||||||
|
|||||||
Generated
+2262
-595
File diff suppressed because one or more lines are too long
@@ -0,0 +1,33 @@
|
|||||||
|
# platforms/BUILD.bazel
|
||||||
|
"""Target Platform Definitions for Embedded Cross-Compilation.
|
||||||
|
|
||||||
|
In Bazel, platforms represent execution and target build environments.
|
||||||
|
We define target platforms by declaring their constraint values (CPU
|
||||||
|
architecture and Operating System). The registered Rust toolchain
|
||||||
|
matches these constraint combinations to determine which
|
||||||
|
compiler/linker options to use:
|
||||||
|
|
||||||
|
- `aarch64-unknown-none` represents AArch64 bare-metal (no OS)
|
||||||
|
environments.
|
||||||
|
|
||||||
|
- `thumbv7em-none-eabihf` represents ARM Cortex-M4F microcontroller
|
||||||
|
environments.
|
||||||
|
"""
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
platform(
|
||||||
|
name = "aarch64-unknown-none",
|
||||||
|
constraint_values = [
|
||||||
|
"@platforms//os:none",
|
||||||
|
"@platforms//cpu:aarch64",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
platform(
|
||||||
|
name = "thumbv7em-none-eabihf",
|
||||||
|
constraint_values = [
|
||||||
|
"@platforms//os:none",
|
||||||
|
"@platforms//cpu:armv7e-mf",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
"""Starlark Configuration Transitions for Cross-Compilation.
|
||||||
|
|
||||||
|
In Bazel, test targets (like sh_test) are host-executed. If the global
|
||||||
|
invocation sets --platforms=//platforms:aarch64-unknown-none, Bazel
|
||||||
|
attempts to run the test runners themselves on the target bare-metal
|
||||||
|
platform. Because there are no test execution toolchains for
|
||||||
|
bare-metal targets, this results in analysis failures.
|
||||||
|
|
||||||
|
To resolve this, we keep the global invocation targeting the host
|
||||||
|
platform, and use these custom rules (aarch64_binary,
|
||||||
|
thumbv7em_binary) to apply a "transition". A transition modifies the
|
||||||
|
configuration (the --platforms flag) for the dependency edge to the
|
||||||
|
target binary. This ensures:
|
||||||
|
|
||||||
|
1. The binaries are always compiled for their specific bare-metal
|
||||||
|
target platform.
|
||||||
|
|
||||||
|
2. The parent test targets (sh_test) are built and run on the host
|
||||||
|
platform.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _aarch64_transition_impl(settings, attr):
|
||||||
|
return {"//command_line_option:platforms": ["//platforms:aarch64-unknown-none"]}
|
||||||
|
|
||||||
|
_aarch64_transition = transition(
|
||||||
|
implementation = _aarch64_transition_impl,
|
||||||
|
inputs = [],
|
||||||
|
outputs = ["//command_line_option:platforms"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _transition_rule_impl(ctx):
|
||||||
|
# Retrieve the files from the transitioned target
|
||||||
|
return [DefaultInfo(files = ctx.attr.dep[0][DefaultInfo].files)]
|
||||||
|
|
||||||
|
aarch64_binary = rule(
|
||||||
|
implementation = _transition_rule_impl,
|
||||||
|
attrs = {
|
||||||
|
"dep": attr.label(cfg = _aarch64_transition),
|
||||||
|
"_allowlist_function_transition": attr.label(
|
||||||
|
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def _thumbv7em_transition_impl(settings, attr):
|
||||||
|
return {"//command_line_option:platforms": ["//platforms:thumbv7em-none-eabihf"]}
|
||||||
|
|
||||||
|
_thumbv7em_transition = transition(
|
||||||
|
implementation = _thumbv7em_transition_impl,
|
||||||
|
inputs = [],
|
||||||
|
outputs = ["//command_line_option:platforms"],
|
||||||
|
)
|
||||||
|
|
||||||
|
thumbv7em_binary = rule(
|
||||||
|
implementation = _transition_rule_impl,
|
||||||
|
attrs = {
|
||||||
|
"dep": attr.label(cfg = _thumbv7em_transition),
|
||||||
|
"_allowlist_function_transition": attr.label(
|
||||||
|
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
"""Bazel BUILD file for AArch64 Bare-Metal Allocator Example.
|
||||||
|
|
||||||
|
This package defines the allocator example target. Because this code
|
||||||
|
targets AArch64 bare-metal platforms and not the host OS:
|
||||||
|
|
||||||
|
1. The raw `rust_binary` is constrained using `target_compatible_with`
|
||||||
|
to run only on `os:none` to prevent compilation errors during
|
||||||
|
wildcard host builds.
|
||||||
|
"""
|
||||||
|
|
||||||
|
load("@rules_rust//rust:defs.bzl", "rust_binary")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "alloc-example",
|
||||||
|
srcs = ["src/main.rs"],
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_alloc_example//:buddy_system_allocator",
|
||||||
|
"@bare_metal_alloc_example//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
"""Bazel BUILD file for AArch64 Bare-Metal APS Examples.
|
||||||
|
|
||||||
|
This package defines six distinct bare-metal demonstration binaries
|
||||||
|
along with their binary extraction genrules and host-executed QEMU
|
||||||
|
testing scripts. Because this code targets AArch64 bare-metal
|
||||||
|
platforms and not the host OS:
|
||||||
|
|
||||||
|
1. The raw `rust_binary` targets are constrained using
|
||||||
|
`target_compatible_with` to run only on `os:none` to prevent
|
||||||
|
compilation errors during wildcard host builds.
|
||||||
|
|
||||||
|
2. We extract flat binary images via `genrule` targets using the
|
||||||
|
hermetic host toolchain's `rust-objcopy`.
|
||||||
|
|
||||||
|
3. We wrap each binary target in a platform transition
|
||||||
|
(`aarch64_binary`) so they are built for the AArch64 bare-metal
|
||||||
|
target platform during host-executed tests.
|
||||||
|
"""
|
||||||
|
|
||||||
|
load("@rules_rust//rust:defs.bzl", "rust_binary")
|
||||||
|
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
|
||||||
|
load("@rules_shell//shell:sh_test.bzl", "sh_test")
|
||||||
|
load("//platforms:transition.bzl", "aarch64_binary")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "improved",
|
||||||
|
srcs = glob(["src/**/*.rs"]),
|
||||||
|
compile_data = glob(["src/**/*.S"]),
|
||||||
|
crate_root = "src/main_improved.rs",
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":image.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_aps//:aarch64-paging",
|
||||||
|
"@bare_metal_aps//:aarch64-rt",
|
||||||
|
"@bare_metal_aps//:arm-pl011-uart",
|
||||||
|
"@bare_metal_aps//:bitflags",
|
||||||
|
"@bare_metal_aps//:log",
|
||||||
|
"@bare_metal_aps//:safe-mmio",
|
||||||
|
"@bare_metal_aps//:smccc",
|
||||||
|
"@bare_metal_aps//:spin",
|
||||||
|
"@bare_metal_aps//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "logger",
|
||||||
|
srcs = glob(["src/**/*.rs"]),
|
||||||
|
compile_data = glob(["src/**/*.S"]),
|
||||||
|
crate_root = "src/main_logger.rs",
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":image.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_aps//:aarch64-paging",
|
||||||
|
"@bare_metal_aps//:aarch64-rt",
|
||||||
|
"@bare_metal_aps//:arm-pl011-uart",
|
||||||
|
"@bare_metal_aps//:bitflags",
|
||||||
|
"@bare_metal_aps//:log",
|
||||||
|
"@bare_metal_aps//:safe-mmio",
|
||||||
|
"@bare_metal_aps//:smccc",
|
||||||
|
"@bare_metal_aps//:spin",
|
||||||
|
"@bare_metal_aps//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "minimal",
|
||||||
|
srcs = glob(["src/**/*.rs"]),
|
||||||
|
compile_data = glob(["src/**/*.S"]),
|
||||||
|
crate_root = "src/main_minimal.rs",
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":image.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_aps//:aarch64-paging",
|
||||||
|
"@bare_metal_aps//:aarch64-rt",
|
||||||
|
"@bare_metal_aps//:arm-pl011-uart",
|
||||||
|
"@bare_metal_aps//:bitflags",
|
||||||
|
"@bare_metal_aps//:log",
|
||||||
|
"@bare_metal_aps//:safe-mmio",
|
||||||
|
"@bare_metal_aps//:smccc",
|
||||||
|
"@bare_metal_aps//:spin",
|
||||||
|
"@bare_metal_aps//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "psci",
|
||||||
|
srcs = glob(["src/**/*.rs"]),
|
||||||
|
compile_data = glob(["src/**/*.S"]),
|
||||||
|
crate_root = "src/main_psci.rs",
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":image.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_aps//:aarch64-paging",
|
||||||
|
"@bare_metal_aps//:aarch64-rt",
|
||||||
|
"@bare_metal_aps//:arm-pl011-uart",
|
||||||
|
"@bare_metal_aps//:bitflags",
|
||||||
|
"@bare_metal_aps//:log",
|
||||||
|
"@bare_metal_aps//:safe-mmio",
|
||||||
|
"@bare_metal_aps//:smccc",
|
||||||
|
"@bare_metal_aps//:spin",
|
||||||
|
"@bare_metal_aps//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "rt",
|
||||||
|
srcs = glob(["src/**/*.rs"]),
|
||||||
|
compile_data = glob(["src/**/*.S"]),
|
||||||
|
crate_root = "src/main_rt.rs",
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":image.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_aps//:aarch64-paging",
|
||||||
|
"@bare_metal_aps//:aarch64-rt",
|
||||||
|
"@bare_metal_aps//:arm-pl011-uart",
|
||||||
|
"@bare_metal_aps//:bitflags",
|
||||||
|
"@bare_metal_aps//:log",
|
||||||
|
"@bare_metal_aps//:safe-mmio",
|
||||||
|
"@bare_metal_aps//:smccc",
|
||||||
|
"@bare_metal_aps//:spin",
|
||||||
|
"@bare_metal_aps//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "safemmio",
|
||||||
|
srcs = glob(["src/**/*.rs"]),
|
||||||
|
compile_data = glob(["src/**/*.S"]),
|
||||||
|
crate_root = "src/main_safemmio.rs",
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":image.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_aps//:aarch64-paging",
|
||||||
|
"@bare_metal_aps//:aarch64-rt",
|
||||||
|
"@bare_metal_aps//:arm-pl011-uart",
|
||||||
|
"@bare_metal_aps//:bitflags",
|
||||||
|
"@bare_metal_aps//:log",
|
||||||
|
"@bare_metal_aps//:safe-mmio",
|
||||||
|
"@bare_metal_aps//:smccc",
|
||||||
|
"@bare_metal_aps//:spin",
|
||||||
|
"@bare_metal_aps//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "improved_bin",
|
||||||
|
srcs = [":improved"],
|
||||||
|
outs = ["improved.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :improved) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "logger_bin",
|
||||||
|
srcs = [":logger"],
|
||||||
|
outs = ["logger.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :logger) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "minimal_bin",
|
||||||
|
srcs = [":minimal"],
|
||||||
|
outs = ["minimal.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :minimal) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "psci_bin",
|
||||||
|
srcs = [":psci"],
|
||||||
|
outs = ["psci.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :psci) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "rt_bin",
|
||||||
|
srcs = [":rt"],
|
||||||
|
outs = ["rt.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :rt) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "safemmio_bin",
|
||||||
|
srcs = [":safemmio"],
|
||||||
|
outs = ["safemmio.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :safemmio) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "improved_bin_aarch64",
|
||||||
|
dep = ":improved_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "logger_bin_aarch64",
|
||||||
|
dep = ":logger_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "minimal_bin_aarch64",
|
||||||
|
dep = ":minimal_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "psci_bin_aarch64",
|
||||||
|
dep = ":psci_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "rt_bin_aarch64",
|
||||||
|
dep = ":rt_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "safemmio_bin_aarch64",
|
||||||
|
dep = ":safemmio_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "improved_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["improved"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":improved_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "logger_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["logger"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":logger_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "minimal_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["minimal"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":minimal_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "psci_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["psci"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":psci_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "rt_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["rt"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":rt_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "safemmio_test",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["safemmio"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":safemmio_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "bins",
|
||||||
|
srcs = [
|
||||||
|
":improved_bin",
|
||||||
|
":logger_bin",
|
||||||
|
":minimal_bin",
|
||||||
|
":psci_bin",
|
||||||
|
":rt_bin",
|
||||||
|
":safemmio_bin",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "improved_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["improved"],
|
||||||
|
data = [":improved_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "logger_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["logger"],
|
||||||
|
data = [":logger_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "minimal_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["minimal"],
|
||||||
|
data = [":minimal_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "psci_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["psci"],
|
||||||
|
data = [":psci_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "rt_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["rt"],
|
||||||
|
data = [":rt_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "safemmio_run",
|
||||||
|
srcs = ["run_test.sh"],
|
||||||
|
args = ["safemmio"],
|
||||||
|
data = [":safemmio_bin_aarch64"],
|
||||||
|
)
|
||||||
Executable
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2026 Google LLC
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BIN_NAME="$1"
|
||||||
|
BIN_PATH="src/bare-metal/aps/examples/${BIN_NAME}.bin"
|
||||||
|
# Detect if running as an automated test under 'bazel test'
|
||||||
|
NON_INTERACTIVE="${TEST_SRCDIR:-}"
|
||||||
|
|
||||||
|
if [ ! -f "$BIN_PATH" ]; then
|
||||||
|
echo "Error: Binary not found at $BIN_PATH" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running ${BIN_NAME}.bin under QEMU..."
|
||||||
|
if [ -n "$NON_INTERACTIVE" ]; then
|
||||||
|
echo "q" | qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel "$BIN_PATH"
|
||||||
|
else
|
||||||
|
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel "$BIN_PATH"
|
||||||
|
fi
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
"""Bazel BUILD file for ARM Cortex-M Microcontroller Examples.
|
||||||
|
|
||||||
|
This package defines board support and hardware abstraction layer
|
||||||
|
(HAL) binaries for microcontrollers. Because this code targets ARM
|
||||||
|
Cortex-M microcontrollers and not the host OS:
|
||||||
|
|
||||||
|
1. The raw `rust_binary` targets are constrained using
|
||||||
|
`target_compatible_with` to run only on `os:none` to prevent
|
||||||
|
compilation errors during wildcard host builds.
|
||||||
|
"""
|
||||||
|
|
||||||
|
load("@rules_rust//rust:defs.bzl", "rust_binary")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "board_support",
|
||||||
|
srcs = glob(["src/bin/**/*.rs"]),
|
||||||
|
crate_root = "src/bin/board_support.rs",
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_microcontrollers//:cortex-m-rt",
|
||||||
|
"@bare_metal_microcontrollers//:embedded-hal",
|
||||||
|
"@bare_metal_microcontrollers//:microbit-v2",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-hal",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-pac",
|
||||||
|
"@bare_metal_microcontrollers//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "hal",
|
||||||
|
srcs = glob(["src/bin/**/*.rs"]),
|
||||||
|
crate_root = "src/bin/hal.rs",
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_microcontrollers//:cortex-m-rt",
|
||||||
|
"@bare_metal_microcontrollers//:embedded-hal",
|
||||||
|
"@bare_metal_microcontrollers//:microbit-v2",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-hal",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-pac",
|
||||||
|
"@bare_metal_microcontrollers//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "minimal",
|
||||||
|
srcs = glob(["src/bin/**/*.rs"]),
|
||||||
|
crate_root = "src/bin/minimal.rs",
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_microcontrollers//:cortex-m-rt",
|
||||||
|
"@bare_metal_microcontrollers//:embedded-hal",
|
||||||
|
"@bare_metal_microcontrollers//:microbit-v2",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-hal",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-pac",
|
||||||
|
"@bare_metal_microcontrollers//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "mmio",
|
||||||
|
srcs = glob(["src/bin/**/*.rs"]),
|
||||||
|
crate_root = "src/bin/mmio.rs",
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_microcontrollers//:cortex-m-rt",
|
||||||
|
"@bare_metal_microcontrollers//:embedded-hal",
|
||||||
|
"@bare_metal_microcontrollers//:microbit-v2",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-hal",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-pac",
|
||||||
|
"@bare_metal_microcontrollers//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "pac",
|
||||||
|
srcs = glob(["src/bin/**/*.rs"]),
|
||||||
|
crate_root = "src/bin/pac.rs",
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_microcontrollers//:cortex-m-rt",
|
||||||
|
"@bare_metal_microcontrollers//:embedded-hal",
|
||||||
|
"@bare_metal_microcontrollers//:microbit-v2",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-hal",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-pac",
|
||||||
|
"@bare_metal_microcontrollers//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "typestate",
|
||||||
|
srcs = glob(["src/bin/**/*.rs"]),
|
||||||
|
crate_root = "src/bin/typestate.rs",
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_microcontrollers//:cortex-m-rt",
|
||||||
|
"@bare_metal_microcontrollers//:embedded-hal",
|
||||||
|
"@bare_metal_microcontrollers//:microbit-v2",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-hal",
|
||||||
|
"@bare_metal_microcontrollers//:nrf52833-pac",
|
||||||
|
"@bare_metal_microcontrollers//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
"""Bazel BUILD file for Microcontroller Compass Exercise.
|
||||||
|
|
||||||
|
This package defines the compass exercise target. Because this code
|
||||||
|
targets ARM Cortex-M microcontrollers and not the host OS:
|
||||||
|
|
||||||
|
1. The raw `rust_binary` target is constrained using
|
||||||
|
`target_compatible_with` to run only on `os:none` to prevent
|
||||||
|
compilation errors during wildcard host builds.
|
||||||
|
"""
|
||||||
|
|
||||||
|
load("@rules_rust//rust:defs.bzl", "rust_binary")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "compass",
|
||||||
|
srcs = ["src/main.rs"],
|
||||||
|
edition = "2024",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Tlink.x",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_compass//:cortex-m-rt",
|
||||||
|
"@bare_metal_compass//:embedded-hal",
|
||||||
|
"@bare_metal_compass//:lsm303agr",
|
||||||
|
"@bare_metal_compass//:microbit-v2",
|
||||||
|
"@bare_metal_compass//:panic-halt",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
"""Bazel BUILD file for PL031 RTC Bare-Metal Exercise.
|
||||||
|
|
||||||
|
This package defines the bare-metal binary and its binary
|
||||||
|
extraction/testing targets. Because this code runs directly on AArch64
|
||||||
|
hardware (under QEMU) and not the host OS:
|
||||||
|
|
||||||
|
1. The raw `rust_binary` is constrained using `target_compatible_with`
|
||||||
|
to run only on `os:none` to prevent compilation errors during
|
||||||
|
wildcard host builds.
|
||||||
|
|
||||||
|
2. We extract the binary flat image via a `genrule` using the hermetic
|
||||||
|
host toolchain's `rust-objcopy`.
|
||||||
|
|
||||||
|
3. We declare a custom platform transition target (`rtc_bin_aarch64`)
|
||||||
|
to build the binary for the AArch64 bare-metal target platform,
|
||||||
|
allowing host-executed tests to depend on it.
|
||||||
|
"""
|
||||||
|
|
||||||
|
load("@rules_rust//rust:defs.bzl", "rust_binary")
|
||||||
|
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
|
||||||
|
load("@rules_shell//shell:sh_test.bzl", "sh_test")
|
||||||
|
load("//platforms:transition.bzl", "aarch64_binary")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
rust_binary(
|
||||||
|
name = "rtc",
|
||||||
|
srcs = [
|
||||||
|
"src/exceptions.rs",
|
||||||
|
"src/logger.rs",
|
||||||
|
"src/main.rs",
|
||||||
|
"src/pl031.rs",
|
||||||
|
],
|
||||||
|
edition = "2024",
|
||||||
|
linker_script = ":memory.ld",
|
||||||
|
rustc_flags = [
|
||||||
|
"-C",
|
||||||
|
"linker=rust-lld",
|
||||||
|
"-C",
|
||||||
|
"link-arg=-Timage.ld",
|
||||||
|
],
|
||||||
|
target_compatible_with = ["@platforms//os:none"],
|
||||||
|
deps = [
|
||||||
|
"@bare_metal_rtc//:aarch64-paging",
|
||||||
|
"@bare_metal_rtc//:aarch64-rt",
|
||||||
|
"@bare_metal_rtc//:arm-gic",
|
||||||
|
"@bare_metal_rtc//:arm-pl011-uart",
|
||||||
|
"@bare_metal_rtc//:bitflags",
|
||||||
|
"@bare_metal_rtc//:chrono",
|
||||||
|
"@bare_metal_rtc//:log",
|
||||||
|
"@bare_metal_rtc//:safe-mmio",
|
||||||
|
"@bare_metal_rtc//:smccc",
|
||||||
|
"@bare_metal_rtc//:spin",
|
||||||
|
"@bare_metal_rtc//:zerocopy",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "rtc_bin",
|
||||||
|
srcs = [":rtc"],
|
||||||
|
outs = ["rtc.bin"],
|
||||||
|
cmd = "$(execpath @rust_host_tools_nightly//:rust-objcopy) -O binary $(location :rtc) $@",
|
||||||
|
tools = ["@rust_host_tools_nightly//:rust-objcopy"],
|
||||||
|
)
|
||||||
|
|
||||||
|
aarch64_binary(
|
||||||
|
name = "rtc_bin_aarch64",
|
||||||
|
dep = ":rtc_bin",
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "rtc_test",
|
||||||
|
srcs = ["rtc_test.sh"],
|
||||||
|
tags = [
|
||||||
|
"manual",
|
||||||
|
"qemu",
|
||||||
|
],
|
||||||
|
data = [":rtc_bin_aarch64"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "rtc_run",
|
||||||
|
srcs = ["rtc_test.sh"],
|
||||||
|
data = [":rtc_bin_aarch64"],
|
||||||
|
)
|
||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2026 Google LLC
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BIN_PATH="src/exercises/bare-metal/rtc/rtc.bin"
|
||||||
|
# Detect if running as an automated test under 'bazel test'
|
||||||
|
NON_INTERACTIVE="${TEST_SRCDIR:-}"
|
||||||
|
|
||||||
|
if [ ! -f "$BIN_PATH" ]; then
|
||||||
|
echo "Error: rtc.bin not found at $BIN_PATH" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running rtc.bin under QEMU..."
|
||||||
|
if [ -n "$NON_INTERACTIVE" ]; then
|
||||||
|
echo "q" | qemu-system-aarch64 -machine virt,gic-version=3 -cpu max -serial mon:stdio -display none -kernel "$BIN_PATH"
|
||||||
|
else
|
||||||
|
qemu-system-aarch64 -machine virt,gic-version=3 -cpu max -serial mon:stdio -display none -kernel "$BIN_PATH"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user