-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an image access abstraction to RoT update_server #1813
base: master
Are you sure you want to change the base?
Conversation
26ccf19
to
8eec9a6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments from the peanut gallery. Looks like a very nice abstraction layer in general.
let initial_pc_start = image_start.saturating_add(IMAGE_HEADER_OFFSET); | ||
let initial_pc_end = | ||
image_start.saturating_add(self.nxp_offset_to_specific_header); | ||
let pc = exec.start.saturating_add(self.normalized_initial_pc()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: Here and also on line 153 were using exec.start
while other lines use the image_start
alias. Could maybe unify to image_start
to avoid confusion on the offsetting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have stats on how much this changes flash size?
This change adds 768 bytes to the image flash size
New sizes for oxide-rot-1
|
There is work to do to clear fmt and panics out of the the update_server: On master:
On this PR:
|
I consider this reasonable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the image validation logic, would it be possible to pull this into a no_std crate so we can have unit tests?
}, | ||
Ram { | ||
buffer: &'a [u8], | ||
span: FlashRange, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, a number of places in the access code below appear to rely on buffer.len() being equal to the length of this span. How is this invariant maintained? Would it make more sense to have span be a base address instead, so that the len isn't duplicated (and thus doesn't have to be kept in sync)?
) -> ImageAccess<'_> { | ||
let span = flash_range(component, slot); | ||
ImageAccess { | ||
accessor: Accessor::Ram { buffer, span }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Here is a place where the length-matches invariant is definitely not maintained, fwiw.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless all of a slot is in use, it is expected that buffer.len() would always be less than the length of one of the spans.
Perhaps I should change span
to slot_range
(since Slot
is already in use).
Suggestions welcome.
Span is a FlashRange which describes both the stored and the at_runtime address ranges of the slot that the image can occupy.
buffer
here is a portion of the image that currently resides in RAM. The rest of the image may not be present.
In the case of a Accessor::Ram variant, the entire image resides in ram. It's destination slot is described by span.stored
and its runtime slot is described by span.at_runtime
(new names).
I would like to have a no_std library in the hubtools repo that can be used by any code concerned with Oxide LPC55 images. That would include Hubris lib/lpc55-rot-startup/src/images.rs if practical. Tests would be included there. I'd rather not refactor that now and the Created oxidecomputer/hubtools#34 |
Looks like all the saturating arithmetic is still in place. I need convincing that this handles bounds cases correctly. Tests would be the fastest way, short of that I'd like to see a laaaaarge rationale comment explaining why the arithmetic isn't checked instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I sort of accidentally came to read this PR anew and found some questions that I thought were interesting. Feel free to ignore these if need or want be; i ended up sitting on these questions for several days but figured eh, let's ask. They're just curiosity, basically.
/// does match FWIDs against the boot-time-info in some cases. But, because | ||
/// flash areas are mutated during update_server operations and stuff can | ||
/// happen, any data in the non-active Hubris image needs to be treated as | ||
/// untrusted (update_server does not alter its own image). |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The active image could be modified by the update_server task if there were a code path to do that.
There is a check testing to see if the slot to be updated is the currently executing Hubris slot. If so, the request is rejected.
pub const LENGTH_OFFSET: usize = 0x20; | ||
pub const HEADER_OFFSET: u32 = 0x130; | ||
const MAGIC_OFFSET: usize = HEADER_OFFSET as usize; | ||
// An image may have an ImageHeader located after the |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The early versions of the bootloader did not have the header and we have had discussions in the past about removing the need for the header. update_server
tolerates a missing ImageHeader.
…d rollback protection.
Remove last of the saturated math calls. Rename FlashRange::{store,exec} to {stored,at_runtime} for clarity. Remove unnecessary image validation logic in fn padded_image_len.
d7ff24a
to
f8cf87c
Compare
The upcoming rollback protection feature needs to access partial or complete
images in flash, ram, or a mix.
The ImageAccess abstraction makes these operations more readable.