pub struct ZbiContainer<B: SplitByteSlice> {
pub header: Ref<B, ZbiHeader>,
/* private fields */
}Expand description
Main structure to work with ZBI format.
It allows to create valid buffer as well as parse existing one.
Both cases would allow to iterate over elements in the container via ZbiContainer::iter or
ZbiContainer::iter_mut.
Fields§
§header: Ref<B, ZbiHeader>Container specific ZbiHeader, witch would be first element if ZBI buffer.
header.length would show how many bytes after this header is used for ZBI elements and
padding.
header.type_ is always ZbiType::Container
Implementations§
Source§impl<B: SplitByteSlice> ZbiContainer<B>
impl<B: SplitByteSlice> ZbiContainer<B>
Sourcepub fn get_payload_length_u32(&self) -> u32
pub fn get_payload_length_u32(&self) -> u32
Returns current container length as u32. Length doesn’t include container header, only
items and padding.
Sourcepub fn get_payload_length_usize(&self) -> usize
pub fn get_payload_length_usize(&self) -> usize
Returns current container length as usize. Length doesn’t include container header, only
items and padding.
Sourcepub fn container_size(&self) -> Result<usize, ZbiError>
pub fn container_size(&self) -> Result<usize, ZbiError>
Returns the total size including the ZBI container header, payload length after padding.
Sourcepub fn iter(
&self,
) -> ZbiContainerIterator<impl SplitByteSlice + IntoByteSlice<'_> + Default + Debug + PartialEq + '_> ⓘ
pub fn iter( &self, ) -> ZbiContainerIterator<impl SplitByteSlice + IntoByteSlice<'_> + Default + Debug + PartialEq + '_> ⓘ
Immutable iterator over ZBI elements. First element is first ZBI element after container header. Container header is not available via iterator.
Sourcepub fn get_bootable_kernel_item(
&self,
) -> Result<ZbiItem<impl SplitByteSlice + Default + Debug + PartialEq + '_>, ZbiError>
pub fn get_bootable_kernel_item( &self, ) -> Result<ZbiItem<impl SplitByteSlice + Default + Debug + PartialEq + '_>, ZbiError>
Validates if ZBI is bootable for the target platform. And returns ZBI item kernel on success.
§Returns
Ok(item)- if bootable, whereitemis the ZBI kernel item.- Err(
ZbiError::IncompleteKernel) - if first element in container has type not bootable on target platform. - Err(
ZbiError::Truncated) - if container is empty
Sourcepub fn get_kernel_entry_and_reserved_memory_size(
&self,
) -> Result<(u64, u64), ZbiError>
pub fn get_kernel_entry_and_reserved_memory_size( &self, ) -> Result<(u64, u64), ZbiError>
Returns the ZBI kernel entry and reserved_memory_size field value if the container is a
bootable ZBI kernel.
§Returns
- Returns
Ok((entry, reserved_memory_size))on success. - Returns
Errif container is not a bootable ZBI kernel or is truncated.
Sourcepub fn get_buffer_size_for_kernel_relocation(&self) -> Result<usize, ZbiError>
pub fn get_buffer_size_for_kernel_relocation(&self) -> Result<usize, ZbiError>
Computes the required buffer size needed for relocating this ZBI kernel.
§Returns
- Returns
Ok(size)on success. - Returns
Errif container is not a valid bootable ZBI kernel.
Sourcepub fn parse(buffer: B) -> Result<Self, ZbiError>
pub fn parse(buffer: B) -> Result<Self, ZbiError>
Creates ZbiContainer from provided buffer.
Buffer must be aligned to ZBI_ALIGNMENT_USIZE (align_buffer could be
used for that). If buffer is mutable than container can be mutable.
§Returns
Ok(ZbiContainer)- if buffer is aligned and contain valid buffer.- Err(
ZbiError) - if error occurred.
Source§impl<B: SplitByteSliceMut + PartialEq> ZbiContainer<B>
impl<B: SplitByteSliceMut + PartialEq> ZbiContainer<B>
Sourcepub fn get_next_payload(&mut self) -> Result<&mut [u8], ZbiError>
pub fn get_next_payload(&mut self) -> Result<&mut [u8], ZbiError>
Get payload slice for the next ZBI entry Next.
Next entry should be added using ZbiContainer::create_entry.
This is useful when it’s non-trivial to determine the length of a payload ahead of time - for example, loading a variable-length string from persistent storage.
Rather than loading the payload into a temporary buffer, determining the length, then copying it into the ZBI, this function allows loading data directly into the ZBI. Since this buffer is currently unused area, loading data here does not affect the ZBI until zbi_create_entry() is called.
§Example
let next_payload = container.get_next_payload().unwrap();
next_payload[..payload_to_use.len()].copy_from_slice(&payload_to_use[..]);
container
.create_entry(ZbiType::KernelX64, 0, ZbiFlags::default(), payload_to_use.len())
.unwrap();
assert_eq!(container.iter().count(), 1);
assert_eq!(&*container.iter().next().unwrap().payload, &payload_to_use[..]);§Returns:
Ok(&mut [u8]) - on success; slice of buffer where next entries payload would be located.
Err(ZbiError::TooBig) - if buffer is not big enough for new element without payload.
Sourcepub fn create_entry_with_payload(
&mut self,
type_: ZbiType,
extra: u32,
flags: ZbiFlags,
payload: &[u8],
) -> Result<(), ZbiError>
pub fn create_entry_with_payload( &mut self, type_: ZbiType, extra: u32, flags: ZbiFlags, payload: &[u8], ) -> Result<(), ZbiError>
Creates a new ZBI entry with the provided payload.
The new entry is aligned to ZBI_ALIGNMENT_USIZE. The capacity of the base ZBI must
be large enough to fit the new entry.
The ZbiFlags::VERSION is unconditionally set for the new entry.
The ZbiFlags::CRC32 flag yields an error because CRC computation is not yet
supported.
§Arguments
type_- The new entry’s typeextra- The new entry’s type-specific dataflags- The new entry’s flagspayload- The payload, copied into the new entry
§Returns:
- Ok(()) - on success
- Err(
ZbiError::TooBig) - if buffer is not big enough for new element with payload - Err(
ZbiError::Crc32NotSupported) - if unsupportedZbiFlags::CRC32is set - Err(
ZbiError) - if other errors occurred
§Example
container
.create_entry_with_payload(ZbiType::KernelX64, 0, ZbiFlags::default(), &[1, 2, 3, 4])
.unwrap();
assert_eq!(container.iter().count(), 1);
assert_eq!(&*container.iter().next().unwrap().payload, &[1, 2, 3, 4]);Sourcepub fn create_entry(
&mut self,
type_: ZbiType,
extra: u32,
flags: ZbiFlags,
payload_length: usize,
) -> Result<(), ZbiError>
pub fn create_entry( &mut self, type_: ZbiType, extra: u32, flags: ZbiFlags, payload_length: usize, ) -> Result<(), ZbiError>
Creates a new ZBI entry and returns a pointer to the payload.
The new entry is aligned to ZBI_ALIGNMENT_USIZE. The capacity of the base ZBI must
be large enough to fit the new entry.
The ZbiFlags::VERSION is unconditionally set for the new entry.
The ZbiFlags::CRC32 flag yields an error because CRC computation is not yet
supported.
§Arguments
type_- The new entry’s type.extra- The new entry’s type-specific data.flags- The new entry’s flags.payload_length- The length of the new entry’s payload.
§Returns
- Ok(()) - On success.
- Err(
ZbiError::TooBig) - if buffer is not big enough for new element with payload - Err(
ZbiError::Crc32NotSupported) - if unsupportedZbiFlags::CRC32is set - Err(
ZbiError) - if other errors occurred
§Example
let next_payload = container.get_next_payload().unwrap();
next_payload[..payload_to_use.len()].copy_from_slice(&payload_to_use[..]);
container
.create_entry(ZbiType::KernelX64, 0, ZbiFlags::default(), payload_to_use.len())
.unwrap();
assert_eq!(container.iter().count(), 1);
assert_eq!(&*container.iter().next().unwrap().payload, &payload_to_use[..]);Sourcepub fn extend(
&mut self,
other: &ZbiContainer<impl SplitByteSlice + PartialEq>,
) -> Result<(), ZbiError>
pub fn extend( &mut self, other: &ZbiContainer<impl SplitByteSlice + PartialEq>, ) -> Result<(), ZbiError>
Extends a ZBI container with another container’s payload.
§Arguments
other- The container to copy the payload from.
§Returns
Ok(())- On success.- Err(
ZbiError::TooBig) - If container is too small.
§Example
let mut container_0 = ZbiContainer::new(&mut buffer[..]).unwrap();
container_0
.create_entry_with_payload(ZbiType::DebugData, 0, ZbiFlags::default(), &[0, 1])
.unwrap();
let mut container_1 = ZbiContainer::new(&mut buffer[..]).unwrap();
container_1
.create_entry_with_payload(ZbiType::KernelX64, 0, ZbiFlags::default(), &[0, 1, 3, 4])
.unwrap();
container_0.extend(&container_1).unwrap();
assert_eq!(container_0.iter().count(), 2);Sourcepub fn extend_items<'a>(
&mut self,
iter: ZbiContainerIterator<impl SplitByteSlice + Default + Debug + PartialEq + 'a>,
) -> Result<(), ZbiError>
pub fn extend_items<'a>( &mut self, iter: ZbiContainerIterator<impl SplitByteSlice + Default + Debug + PartialEq + 'a>, ) -> Result<(), ZbiError>
Extends a ZBI container with another ZBI item.
§Arguments
iter- ZBI container iterator. Elements starting fromitertill the end are to be appended to the container.
§Returns
Ok(())- On success.- Err(
ZbiError::TooBig) - If container is too small.
Sourcepub fn extend_unaligned(&mut self, other: &[u8]) -> Result<(), ZbiError>
pub fn extend_unaligned(&mut self, other: &[u8]) -> Result<(), ZbiError>
Extends with another ZBI container stored on a potentially unaligned buffer.
The method copies other into the unused space first before checking validity and
extending. Thus if other.len() is greater than the remaining space in the container, it
it will be rejected, regardless of the actual container size.
Source§impl<B: SplitByteSlice + PartialEq + DerefMut> ZbiContainer<B>
impl<B: SplitByteSlice + PartialEq + DerefMut> ZbiContainer<B>
Sourcepub fn iter_mut(
&mut self,
) -> ZbiContainerIterator<impl SplitByteSliceMut + Debug + Default + PartialEq + '_> ⓘ
pub fn iter_mut( &mut self, ) -> ZbiContainerIterator<impl SplitByteSliceMut + Debug + Default + PartialEq + '_> ⓘ
Mutable iterator over ZBI elements. First element is first ZBI element after container header. Container header is not available via iterator.
Trait Implementations§
Source§impl<B: Debug + SplitByteSlice> Debug for ZbiContainer<B>
impl<B: Debug + SplitByteSlice> Debug for ZbiContainer<B>
Source§impl<B: PartialEq + SplitByteSlice> PartialEq for ZbiContainer<B>
impl<B: PartialEq + SplitByteSlice> PartialEq for ZbiContainer<B>
Source§fn eq(&self, other: &ZbiContainer<B>) -> bool
fn eq(&self, other: &ZbiContainer<B>) -> bool
self and other values to be equal, and is used by ==.