Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/demo-stm32g0-nucleo/app-g070.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ stacksize = 944

[kernel]
name = "demo-stm32g0-nucleo"
requires = {flash = 19264, ram = 1632}
requires = {flash = 19264, ram = 1664}
features = ["g070"]
stacksize = 640

Expand Down
2 changes: 1 addition & 1 deletion app/oxide-rot-1/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ version = 0

[kernel]
name = "oxide-rot-1"
requires = {flash = 61252, ram = 2720}
requires = {flash = 61252, ram = 2736}
features = ["dice-mfg"]

[caboose]
Expand Down
8 changes: 8 additions & 0 deletions build/util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ use std::collections::BTreeMap;
use std::ffi::OsStr;
use std::io::Write;

/// Maximum length, in bytes, of an image name (an entry in `image-names` in a
/// manifest).
///
/// NOTE: If you modify this, the layout of `BOOTED_IMAGE` will change. Humility
/// won't be able to identify which image is running if the archive and target
/// have a different layout.
pub const MAX_IMAGE_NAME_LEN: usize = 8;

/// Reads the given environment variable and marks that it's used
///
/// This ensures a rebuild if the variable changes
Expand Down
1 change: 1 addition & 0 deletions build/xtask/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1880,6 +1880,7 @@ fn build_kernel(
let build_config = cfg.kernel_build_config(&[
("HUBRIS_KCONFIG", &kconfig),
("HUBRIS_IMAGE_ID", &format!("{image_id}")),
("HUBRIS_IMAGE_NAME", image_name),
("HUBRIS_FLASH_OUTPUTS", &flash_outputs),
]);
build(cfg, "kernel", build_config, false)?;
Expand Down
19 changes: 19 additions & 0 deletions sys/kern/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,22 @@ fn generate_statics(generated: &Generated) -> Result<()> {
.parse()
.context("parsing HUBRIS_IMAGE_ID")?;

let max_name_len = build_util::MAX_IMAGE_NAME_LEN;
let image_name =
build_util::env_var("HUBRIS_IMAGE_NAME").unwrap_or_default();
let image_name_bytes = image_name.as_bytes();
if image_name_bytes.len() > max_name_len {
bail!(
"HUBRIS_IMAGE_NAME '{}' is {} bytes, but the max length is {}",
image_name,
image_name_bytes.len(),
max_name_len,
);
}
let mut image_name_padded = vec![0u8; max_name_len];
image_name_padded[..image_name_bytes.len()]
.copy_from_slice(image_name_bytes);

let out = build_util::out_dir();
let kconfig_path = out.join("kconfig.rs");
let mut file =
Expand All @@ -425,6 +441,9 @@ fn generate_statics(generated: &Generated) -> Result<()> {
#[unsafe(no_mangle)]
pub static HUBRIS_IMAGE_ID: u64 = #image_id;

pub static HUBRIS_IMAGE_NAME: [u8; #max_name_len] =
[#(#image_name_padded),*];

static mut HUBRIS_TASK_TABLE_SPACE:
core::mem::MaybeUninit<[crate::task::Task; HUBRIS_TASK_COUNT]> =
core::mem::MaybeUninit::uninit();
Expand Down
41 changes: 40 additions & 1 deletion sys/kern/src/startup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::atomic::AtomicExt;
use crate::descs::{RegionAttributes, RegionDesc, TaskDesc, TaskFlags};
use crate::task::Task;
use core::mem::MaybeUninit;
use core::sync::atomic::{AtomicBool, Ordering};
use core::sync::atomic::{AtomicBool, AtomicU8, Ordering, compiler_fence};

/// Tracks when a mutable reference to the task table is floating around in
/// kernel code, to prevent production of a second one. This forms a sort of
Expand All @@ -19,6 +19,25 @@ use core::sync::atomic::{AtomicBool, Ordering};
/// `false` late in `start_kernel`.
static TASK_TABLE_IN_USE: AtomicBool = AtomicBool::new(true);

/// Magic marker written into the tail of `BOOTED_IMAGE`. This lets humility
/// confirm that it's reading from the right address and that the kernel has
/// finished populating `BOOTED_IMAGE`.
const BOOTED_IMAGE_MAGIC: [u8; 8] = *b"HUBRISID";

/// A record of which image is actually running. This is useful on systems with
/// multiple image slots, like the RoT's A/B images.
///
/// Layout:
/// - little-endian `HUBRIS_IMAGE_ID` (8 bytes),
/// - null-padded `HUBRIS_IMAGE_NAME` (`build_util::MAX_IMAGE_NAME_LEN`=8 bytes)
/// - `BOOTED_IMAGE_MAGIC` (8 bytes)
#[unsafe(no_mangle)]
static BOOTED_IMAGE: [AtomicU8; BOOTED_IMAGE_LEN] =
[const { AtomicU8::new(0) }; BOOTED_IMAGE_LEN];

const BOOTED_IMAGE_LEN: usize =
8 + HUBRIS_IMAGE_NAME.len() + BOOTED_IMAGE_MAGIC.len();

pub const HUBRIS_FAULT_NOTIFICATION: u32 = 1;

/// The main kernel entry point.
Expand Down Expand Up @@ -47,6 +66,26 @@ pub unsafe fn start_kernel(tick_divisor: u32) -> ! {
crate::arch::set_clock_freq(tick_divisor);
}

// Record the ID and name of the image so that humility can tell which image
// is actually running on a system with A/B image slots. Write the magic
// marker last, so that if humility sees the marker it can trust that the ID
// and name are complete (and that it's reading from the correct memory
// address).
let (id_and_name, magic) =
BOOTED_IMAGE.split_at(BOOTED_IMAGE.len() - BOOTED_IMAGE_MAGIC.len());
for (destination, byte) in id_and_name.iter().zip(
HUBRIS_IMAGE_ID
.to_le_bytes()
.into_iter()
.chain(HUBRIS_IMAGE_NAME.iter().copied()),
) {
destination.store(byte, Ordering::Relaxed);
}
compiler_fence(Ordering::Release);
for (destination, byte) in magic.iter().zip(BOOTED_IMAGE_MAGIC) {
destination.store(byte, Ordering::Relaxed);
}

// Grab references to all our statics.
let task_descs = &HUBRIS_TASK_DESCS;
// Safety: this reference will remain unique so long as the "only called
Expand Down
2 changes: 1 addition & 1 deletion test/tests-stm32g0/app-g070.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ memory = "memory-g070.toml"

[kernel]
name = "demo-stm32g0-nucleo"
requires = {flash = 19112, ram = 2832}
requires = {flash = 19112, ram = 2864}
features = ["g070"]
stacksize = 2048

Expand Down
Loading