Merge "Port Android boot image structures and parsing to Rust" into main am: 58f7545123 am: b5262c8e92 am: c1048d5d77
Original change: https://android-review.googlesource.com/c/platform/system/tools/mkbootimg/+/2721974
Change-Id: Icf94328fdfa2565da951733d9b636b965e5471b8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/rust/Android.bp b/rust/Android.bp
new file mode 100644
index 0000000..353070e
--- /dev/null
+++ b/rust/Android.bp
@@ -0,0 +1,50 @@
+// Copyright 2023 The Android Open Source Project
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+ name: "libbootimg_private_defaults",
+ srcs: ["bootimg_priv.rs"],
+ rustlibs: ["libzerocopy"],
+ lints: "none",
+}
+
+rust_library {
+ name: "libbootimg_private",
+ crate_name: "bootimg_private",
+ vendor_available: true,
+ defaults: ["libbootimg_private_defaults"],
+ host_supported: true,
+ visibility: [":__subpackages__"],
+}
+
+rust_test_host {
+ name: "libbootimg_tests_priv",
+ auto_gen_config: true,
+ defaults: ["libbootimg_private_defaults"],
+}
+
+rust_defaults {
+ name: "libbootimg_defaults",
+ srcs: ["bootimg.rs"],
+ rustlibs: [
+ "libzerocopy",
+ "libbootimg_private",
+ ],
+}
+
+rust_library {
+ name: "libbootimg",
+ crate_name: "bootimg",
+ vendor_available: true,
+ host_supported: true,
+ defaults: ["libbootimg_defaults"],
+}
+
+rust_test_host {
+ name: "libbootimg_tests",
+ auto_gen_config: true,
+ defaults: ["libbootimg_defaults"],
+}
diff --git a/rust/bindgen.sh b/rust/bindgen.sh
new file mode 100755
index 0000000..b854d10
--- /dev/null
+++ b/rust/bindgen.sh
@@ -0,0 +1,76 @@
+#! /usr/bin/env bash
+# Copyright 2023, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+# Run this script to regenerate bootimg_priv.rs if
+# include/bootimg/bootimg.h ever changes.
+# The rust_bindgen rule is not cooperative, causing custom derive types
+# to not percolate to the generated structures.
+# It's just easier to do all the munging in a script.
+
+SCRATCH_DIR=$(mktemp -d)
+
+cleanup (){
+ rm -rf ${SCRATCH_DIR}
+}
+
+trap cleanup EXIT
+pushd ~/aosp > /dev/null
+
+BOOTIMG_DIR=$(realpath system/tools/mkbootimg/)
+# The stdint include generates a lot of unnecessary types that the
+# generated rust bindings really don't need.
+BLOCKED_TYPES_RE="__.+|.?int.+"
+# The stdint include generates a lot of unnecessary constants that the
+# generated rust bindings really don't need.
+BLOCKED_ITEMS_RE="_.+|.?INT.+|PTR.+|ATOMIC.+|.+SOURCE|.+_H|SIG_.+|SIZE_.+|.?CHAR.+"
+CUSTOM_STRUCT_RE="(vendor_)?(boot_img_hdr|ramdisk_table_entry)_v\d+"
+CUSTOM_STRUCT_DERIVES="AsBytes,FromBytes,PartialEq,Copy,Clone,Debug"
+BINDGEN_FLAGS="--use-core --with-derive-default"
+BOOTIMG_PRIV=${BOOTIMG_DIR}/rust/bootimg_priv.rs
+
+# We need C++ isms, and the only obvious way to convince bindgen
+# that the source is C++ is with a C++ extension.
+cp ${BOOTIMG_DIR}/include/bootimg/bootimg.h ${SCRATCH_DIR}/bootimg.hpp
+
+./out/host/linux-x86/bin/bindgen \
+ --blocklist-type="${BLOCKED_TYPES_RE}" \
+ --blocklist-item="${BLOCKED_ITEMS_RE}" \
+ --with-derive-custom-struct="${CUSTOM_STRUCT_RE}=${CUSTOM_STRUCT_DERIVES}" \
+ ${BINDGEN_FLAGS} \
+ ${SCRATCH_DIR}/bootimg.hpp \
+ -o ${SCRATCH_DIR}/bootimg_gen.rs
+
+cat << EOF | cat - ${SCRATCH_DIR}/bootimg_gen.rs > ${BOOTIMG_PRIV}
+// Copyright $(date +%Y), The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use zerocopy::{AsBytes, FromBytes};
+
+EOF
+
+rustfmt ${BOOTIMG_PRIV} --config-path system/tools/aidl/rustfmt.toml
diff --git a/rust/bootimg.rs b/rust/bootimg.rs
new file mode 100644
index 0000000..bc83eb1
--- /dev/null
+++ b/rust/bootimg.rs
@@ -0,0 +1,399 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! The public interface for bootimg structs
+use zerocopy::{ByteSlice, LayoutVerified};
+
+use bootimg_private::{
+ boot_img_hdr_v0, boot_img_hdr_v1, boot_img_hdr_v2, boot_img_hdr_v3, boot_img_hdr_v4,
+ vendor_boot_img_hdr_v3, vendor_boot_img_hdr_v4, BOOT_MAGIC, BOOT_MAGIC_SIZE, VENDOR_BOOT_MAGIC,
+ VENDOR_BOOT_MAGIC_SIZE,
+};
+
+/// Generalized boot image from a backing store of bytes.
+#[derive(PartialEq, Debug)]
+pub enum BootImage<B: ByteSlice + PartialEq> {
+ /// Version 0 header
+ V0(LayoutVerified<B, boot_img_hdr_v0>),
+ /// Version 1 header
+ V1(LayoutVerified<B, boot_img_hdr_v1>),
+ /// Version 2 header
+ V2(LayoutVerified<B, boot_img_hdr_v2>),
+ /// Version 3 header
+ V3(LayoutVerified<B, boot_img_hdr_v3>),
+ /// Version 4 header
+ V4(LayoutVerified<B, boot_img_hdr_v4>),
+}
+
+/// Generalized vendor boot header from a backing store of bytes.
+#[derive(PartialEq, Debug)]
+pub enum VendorImageHeader<B: ByteSlice + PartialEq> {
+ /// Version 3 header
+ V3(LayoutVerified<B, vendor_boot_img_hdr_v3>),
+ /// Version 4 header
+ V4(LayoutVerified<B, vendor_boot_img_hdr_v4>),
+}
+
+/// Boot related errors.
+#[derive(PartialEq, Debug)]
+pub enum ImageError {
+ /// The provided buffer was too small to hold a header.
+ BufferTooSmall,
+ /// The magic string was incorrect.
+ BadMagic,
+ /// The header version present is not supported.
+ UnexpectedVersion,
+ /// Catch-all for remaining errors.
+ Unknown,
+}
+
+impl core::fmt::Display for ImageError {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ let str = match self {
+ Self::BufferTooSmall => "The provided buffer is too small",
+ Self::BadMagic => "The magic string is incorrect",
+ Self::UnexpectedVersion => "Header version is not supported",
+ Self::Unknown => "Unknown error",
+ };
+ write!(f, "{str}")
+ }
+}
+
+/// Common result type for use with boot headers
+pub type BootResult<T> = Result<T, ImageError>;
+
+fn parse_header<B: ByteSlice + PartialEq, T>(buffer: B) -> BootResult<LayoutVerified<B, T>> {
+ Ok(LayoutVerified::<B, T>::new_from_prefix(buffer).ok_or(ImageError::BufferTooSmall)?.0)
+}
+
+impl<B: ByteSlice + PartialEq> BootImage<B> {
+ /// Given a byte buffer, attempt to parse the contents and return a zero-copy reference
+ /// to the associated boot image header.
+ ///
+ /// # Arguments
+ /// * `buffer` - buffer to parse
+ ///
+ /// # Returns
+ ///
+ /// * `Ok(BootImage)` - if parsing was successful.
+ /// * `Err(ImageError)` - if `buffer` does not contain a valid boot image header.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use bootimg::BootImage;
+ ///
+ /// let mut buffer = [0; 4096];
+ /// // Not shown: read first 4096 bytes of boot image into buffer
+ /// let header = BootImage::parse(&buffer[..]).unwrap();
+ /// ```
+ pub fn parse(buffer: B) -> BootResult<Self> {
+ let magic_size = BOOT_MAGIC_SIZE as usize;
+ // Note: even though the v3 header is not a prefix for the v0, v1, or v2 header,
+ // the version and the magic string exist at the same offset and have the same types.
+ // Make a v3 temporary because it is the smallest.
+ let (hdr, _) =
+ LayoutVerified::<&[u8], boot_img_hdr_v3>::new_from_prefix(buffer.get(..).unwrap())
+ .ok_or(ImageError::BufferTooSmall)?;
+
+ if hdr.magic.ne(&BOOT_MAGIC[..magic_size]) {
+ return Err(ImageError::BadMagic);
+ }
+
+ match hdr.header_version {
+ 0 => Ok(Self::V0(parse_header::<B, boot_img_hdr_v0>(buffer)?)),
+ 1 => Ok(Self::V1(parse_header::<B, boot_img_hdr_v1>(buffer)?)),
+ 2 => Ok(Self::V2(parse_header::<B, boot_img_hdr_v2>(buffer)?)),
+ 3 => Ok(Self::V3(parse_header::<B, boot_img_hdr_v3>(buffer)?)),
+ 4 => Ok(Self::V4(parse_header::<B, boot_img_hdr_v4>(buffer)?)),
+ _ => Err(ImageError::UnexpectedVersion),
+ }
+ }
+}
+
+impl<B: ByteSlice + PartialEq> VendorImageHeader<B> {
+ /// Given a byte buffer, attempt to parse the contents and return a zero-copy reference
+ /// to the associated vendor boot image header.
+ ///
+ /// # Arguments
+ /// * `buffer` - buffer to parse
+ ///
+ /// # Returns
+ ///
+ /// * `Ok(VendorImageHeader)` - if parsing was successful.
+ /// * `Err(ImageError)` - If `buffer` does not contain a valid boot image header.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use bootimg::VendorImageHeader;
+ ///
+ /// let mut buffer = [0; 4096];
+ /// // Not shown: read first 4096 bytes of vendor image into buffer
+ /// let header = VendorImageHeader::parse(&buffer[..]).unwrap();
+ /// ```
+ pub fn parse(buffer: B) -> BootResult<Self> {
+ let magic_size = VENDOR_BOOT_MAGIC_SIZE as usize;
+ let (hdr, _) = LayoutVerified::<&[u8], vendor_boot_img_hdr_v3>::new_from_prefix(
+ buffer.get(..).unwrap(),
+ )
+ .ok_or(ImageError::BufferTooSmall)?;
+
+ if hdr.magic.ne(&VENDOR_BOOT_MAGIC[..magic_size]) {
+ return Err(ImageError::BadMagic);
+ }
+
+ match hdr.header_version {
+ 3 => Ok(Self::V3(parse_header::<B, vendor_boot_img_hdr_v3>(buffer)?)),
+ 4 => Ok(Self::V4(parse_header::<B, vendor_boot_img_hdr_v4>(buffer)?)),
+ _ => Err(ImageError::UnexpectedVersion),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use zerocopy::AsBytes;
+
+ const MAGIC_SIZE: usize = BOOT_MAGIC_SIZE as usize;
+ const VENDOR_MAGIC_SIZE: usize = VENDOR_BOOT_MAGIC_SIZE as usize;
+
+ pub fn add<T: AsBytes>(buffer: &mut [u8], t: T) {
+ t.write_to_prefix(buffer).unwrap();
+ }
+
+ #[test]
+ fn buffer_too_small_for_version() {
+ let buffer = [0; 40];
+ assert_eq!(BootImage::parse(&buffer[..]), Err(ImageError::BufferTooSmall));
+ }
+
+ #[test]
+ fn buffer_too_small_valid_version() {
+ // Note: because the v1 header fully encapsulates the v0 header,
+ // we can trigger a buffer-too-small error by providing
+ // a perfectly valid v0 header and changing the version to 1.
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v0>()];
+ add::<boot_img_hdr_v0>(
+ &mut buffer,
+ boot_img_hdr_v0 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 1,
+ ..Default::default()
+ },
+ );
+ assert_eq!(BootImage::parse(&buffer[..]), Err(ImageError::BufferTooSmall));
+ }
+
+ #[test]
+ fn bad_magic() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v0>()];
+ add::<boot_img_hdr_v0>(
+ &mut buffer,
+ boot_img_hdr_v0 { magic: *b"ANDROGEN", ..Default::default() },
+ );
+ assert_eq!(BootImage::parse(&buffer[..]), Err(ImageError::BadMagic));
+ }
+
+ #[test]
+ fn bad_version() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v0>()];
+ add::<boot_img_hdr_v0>(
+ &mut buffer,
+ boot_img_hdr_v0 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 2112,
+ ..Default::default()
+ },
+ );
+ assert_eq!(BootImage::parse(&buffer[..]), Err(ImageError::UnexpectedVersion));
+ }
+
+ #[test]
+ fn parse_v0() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v0>()];
+ add::<boot_img_hdr_v0>(
+ &mut buffer,
+ boot_img_hdr_v0 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 0,
+ ..Default::default()
+ },
+ );
+ let expected =
+ Ok(BootImage::V0(LayoutVerified::<&[u8], boot_img_hdr_v0>::new(&buffer).unwrap()));
+ assert_eq!(BootImage::parse(&buffer[..]), expected);
+ }
+
+ #[test]
+ fn parse_v1() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v1>()];
+ add::<boot_img_hdr_v1>(
+ &mut buffer,
+ boot_img_hdr_v1 {
+ _base: boot_img_hdr_v0 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 1,
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ );
+ let expected =
+ Ok(BootImage::V1(LayoutVerified::<&[u8], boot_img_hdr_v1>::new(&buffer).unwrap()));
+ assert_eq!(BootImage::parse(&buffer[..]), expected);
+ }
+
+ #[test]
+ fn parse_v2() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v2>()];
+ add::<boot_img_hdr_v2>(
+ &mut buffer,
+ boot_img_hdr_v2 {
+ _base: boot_img_hdr_v1 {
+ _base: boot_img_hdr_v0 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 2,
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ );
+ let expected =
+ Ok(BootImage::V2(LayoutVerified::<&[u8], boot_img_hdr_v2>::new(&buffer).unwrap()));
+ assert_eq!(BootImage::parse(&buffer[..]), expected);
+ }
+
+ #[test]
+ fn parse_v3() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v3>()];
+ add::<boot_img_hdr_v3>(
+ &mut buffer,
+ boot_img_hdr_v3 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 3,
+ ..Default::default()
+ },
+ );
+ let expected =
+ Ok(BootImage::V3(LayoutVerified::<&[u8], boot_img_hdr_v3>::new(&buffer).unwrap()));
+ assert_eq!(BootImage::parse(&buffer[..]), expected);
+ }
+
+ #[test]
+ fn parse_v4() {
+ let mut buffer = [0; core::mem::size_of::<boot_img_hdr_v4>()];
+ add::<boot_img_hdr_v4>(
+ &mut buffer,
+ boot_img_hdr_v4 {
+ _base: boot_img_hdr_v3 {
+ magic: BOOT_MAGIC[0..MAGIC_SIZE].try_into().unwrap(),
+ header_version: 4,
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ );
+ let expected =
+ Ok(BootImage::V4(LayoutVerified::<&[u8], boot_img_hdr_v4>::new(&buffer).unwrap()));
+ assert_eq!(BootImage::parse(&buffer[..]), expected);
+ }
+
+ #[test]
+ fn vendor_buffer_too_small_for_version() {
+ let buffer = [0; VENDOR_MAGIC_SIZE + 3];
+ assert_eq!(VendorImageHeader::parse(&buffer[..]), Err(ImageError::BufferTooSmall));
+ }
+
+ #[test]
+ fn vendor_bad_magic() {
+ let mut buffer = [0; core::mem::size_of::<vendor_boot_img_hdr_v3>()];
+ add::<vendor_boot_img_hdr_v3>(
+ &mut buffer,
+ vendor_boot_img_hdr_v3 { magic: *b"VNDRBOOK", header_version: 3, ..Default::default() },
+ );
+ assert_eq!(VendorImageHeader::parse(&buffer[..]), Err(ImageError::BadMagic));
+ }
+
+ #[test]
+ fn vendor_bad_version() {
+ let mut buffer = [0; core::mem::size_of::<vendor_boot_img_hdr_v3>()];
+ add::<vendor_boot_img_hdr_v3>(
+ &mut buffer,
+ vendor_boot_img_hdr_v3 {
+ magic: VENDOR_BOOT_MAGIC[0..VENDOR_MAGIC_SIZE].try_into().unwrap(),
+ header_version: 2112,
+ ..Default::default()
+ },
+ );
+ assert_eq!(VendorImageHeader::parse(&buffer[..]), Err(ImageError::UnexpectedVersion));
+ }
+
+ #[test]
+ fn vendor_buffer_too_small_valid_version() {
+ let mut buffer = [0; core::mem::size_of::<vendor_boot_img_hdr_v3>()];
+ add::<vendor_boot_img_hdr_v3>(
+ &mut buffer,
+ vendor_boot_img_hdr_v3 {
+ magic: VENDOR_BOOT_MAGIC[0..VENDOR_MAGIC_SIZE].try_into().unwrap(),
+ // Note: because the v4 header fully encapsulates the v3 header,
+ // we can trigger a buffer-too-small error by providing
+ // a perfectly valid v3 header and changing the version to 4.
+ header_version: 4,
+ ..Default::default()
+ },
+ );
+ assert_eq!(VendorImageHeader::parse(&buffer[..]), Err(ImageError::BufferTooSmall));
+ }
+
+ #[test]
+ fn vendor_parse_v3() {
+ let mut buffer = [0; core::mem::size_of::<vendor_boot_img_hdr_v3>()];
+ add::<vendor_boot_img_hdr_v3>(
+ &mut buffer,
+ vendor_boot_img_hdr_v3 {
+ magic: VENDOR_BOOT_MAGIC[0..VENDOR_MAGIC_SIZE].try_into().unwrap(),
+ header_version: 3,
+ ..Default::default()
+ },
+ );
+ let expected = Ok(VendorImageHeader::V3(
+ LayoutVerified::<&[u8], vendor_boot_img_hdr_v3>::new(&buffer).unwrap(),
+ ));
+ assert_eq!(VendorImageHeader::parse(&buffer[..]), expected);
+ }
+
+ #[test]
+ fn vendor_parse_v4() {
+ let mut buffer = [0; core::mem::size_of::<vendor_boot_img_hdr_v4>()];
+ add::<vendor_boot_img_hdr_v4>(
+ &mut buffer,
+ vendor_boot_img_hdr_v4 {
+ _base: vendor_boot_img_hdr_v3 {
+ magic: VENDOR_BOOT_MAGIC[0..VENDOR_MAGIC_SIZE].try_into().unwrap(),
+ header_version: 4,
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ );
+ let expected = Ok(VendorImageHeader::V4(
+ LayoutVerified::<&[u8], vendor_boot_img_hdr_v4>::new(&buffer).unwrap(),
+ ));
+ assert_eq!(VendorImageHeader::parse(&buffer[..]), expected);
+ }
+}
diff --git a/rust/bootimg_priv.rs b/rust/bootimg_priv.rs
new file mode 100644
index 0000000..fbd883c
--- /dev/null
+++ b/rust/bootimg_priv.rs
@@ -0,0 +1,669 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use zerocopy::{AsBytes, FromBytes};
+
+/* automatically generated by rust-bindgen 0.65.1 */
+
+pub const BOOT_MAGIC: &[u8; 9usize] = b"ANDROID!\0";
+pub const BOOT_MAGIC_SIZE: u32 = 8;
+pub const BOOT_NAME_SIZE: u32 = 16;
+pub const BOOT_ARGS_SIZE: u32 = 512;
+pub const BOOT_EXTRA_ARGS_SIZE: u32 = 1024;
+pub const VENDOR_BOOT_MAGIC: &[u8; 9usize] = b"VNDRBOOT\0";
+pub const VENDOR_BOOT_MAGIC_SIZE: u32 = 8;
+pub const VENDOR_BOOT_ARGS_SIZE: u32 = 2048;
+pub const VENDOR_BOOT_NAME_SIZE: u32 = 16;
+pub const VENDOR_RAMDISK_TYPE_NONE: u32 = 0;
+pub const VENDOR_RAMDISK_TYPE_PLATFORM: u32 = 1;
+pub const VENDOR_RAMDISK_TYPE_RECOVERY: u32 = 2;
+pub const VENDOR_RAMDISK_TYPE_DLKM: u32 = 3;
+pub const VENDOR_RAMDISK_NAME_SIZE: u32 = 32;
+pub const VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE: u32 = 16;
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct boot_img_hdr_v0 {
+ pub magic: [u8; 8usize],
+ pub kernel_size: u32,
+ pub kernel_addr: u32,
+ pub ramdisk_size: u32,
+ pub ramdisk_addr: u32,
+ pub second_size: u32,
+ pub second_addr: u32,
+ pub tags_addr: u32,
+ pub page_size: u32,
+ pub header_version: u32,
+ pub os_version: u32,
+ pub name: [u8; 16usize],
+ pub cmdline: [u8; 512usize],
+ pub id: [u32; 8usize],
+ pub extra_cmdline: [u8; 1024usize],
+}
+#[test]
+fn bindgen_test_layout_boot_img_hdr_v0() {
+ const UNINIT: ::core::mem::MaybeUninit<boot_img_hdr_v0> = ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<boot_img_hdr_v0>(),
+ 1632usize,
+ concat!("Size of: ", stringify!(boot_img_hdr_v0))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<boot_img_hdr_v0>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(boot_img_hdr_v0))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).magic) as usize - ptr as usize },
+ 0usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(magic))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).kernel_size) as usize - ptr as usize },
+ 8usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(kernel_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).kernel_addr) as usize - ptr as usize },
+ 12usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(kernel_addr))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_size) as usize - ptr as usize },
+ 16usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(ramdisk_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_addr) as usize - ptr as usize },
+ 20usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(ramdisk_addr))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).second_size) as usize - ptr as usize },
+ 24usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(second_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).second_addr) as usize - ptr as usize },
+ 28usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(second_addr))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).tags_addr) as usize - ptr as usize },
+ 32usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(tags_addr))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).page_size) as usize - ptr as usize },
+ 36usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(page_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).header_version) as usize - ptr as usize },
+ 40usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(header_version))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).os_version) as usize - ptr as usize },
+ 44usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(os_version))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).name) as usize - ptr as usize },
+ 48usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(name))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).cmdline) as usize - ptr as usize },
+ 64usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(cmdline))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).id) as usize - ptr as usize },
+ 576usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(id))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).extra_cmdline) as usize - ptr as usize },
+ 608usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v0), "::", stringify!(extra_cmdline))
+ );
+}
+impl Default for boot_img_hdr_v0 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+pub type boot_img_hdr = boot_img_hdr_v0;
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct boot_img_hdr_v1 {
+ pub _base: boot_img_hdr_v0,
+ pub recovery_dtbo_size: u32,
+ pub recovery_dtbo_offset: u64,
+ pub header_size: u32,
+}
+#[test]
+fn bindgen_test_layout_boot_img_hdr_v1() {
+ const UNINIT: ::core::mem::MaybeUninit<boot_img_hdr_v1> = ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<boot_img_hdr_v1>(),
+ 1648usize,
+ concat!("Size of: ", stringify!(boot_img_hdr_v1))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<boot_img_hdr_v1>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(boot_img_hdr_v1))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).recovery_dtbo_size) as usize - ptr as usize },
+ 1632usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(boot_img_hdr_v1),
+ "::",
+ stringify!(recovery_dtbo_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).recovery_dtbo_offset) as usize - ptr as usize },
+ 1636usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(boot_img_hdr_v1),
+ "::",
+ stringify!(recovery_dtbo_offset)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).header_size) as usize - ptr as usize },
+ 1644usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v1), "::", stringify!(header_size))
+ );
+}
+impl Default for boot_img_hdr_v1 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct boot_img_hdr_v2 {
+ pub _base: boot_img_hdr_v1,
+ pub dtb_size: u32,
+ pub dtb_addr: u64,
+}
+#[test]
+fn bindgen_test_layout_boot_img_hdr_v2() {
+ const UNINIT: ::core::mem::MaybeUninit<boot_img_hdr_v2> = ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<boot_img_hdr_v2>(),
+ 1660usize,
+ concat!("Size of: ", stringify!(boot_img_hdr_v2))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<boot_img_hdr_v2>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(boot_img_hdr_v2))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).dtb_size) as usize - ptr as usize },
+ 1648usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v2), "::", stringify!(dtb_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).dtb_addr) as usize - ptr as usize },
+ 1652usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v2), "::", stringify!(dtb_addr))
+ );
+}
+impl Default for boot_img_hdr_v2 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct boot_img_hdr_v3 {
+ pub magic: [u8; 8usize],
+ pub kernel_size: u32,
+ pub ramdisk_size: u32,
+ pub os_version: u32,
+ pub header_size: u32,
+ pub reserved: [u32; 4usize],
+ pub header_version: u32,
+ pub cmdline: [u8; 1536usize],
+}
+#[test]
+fn bindgen_test_layout_boot_img_hdr_v3() {
+ const UNINIT: ::core::mem::MaybeUninit<boot_img_hdr_v3> = ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<boot_img_hdr_v3>(),
+ 1580usize,
+ concat!("Size of: ", stringify!(boot_img_hdr_v3))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<boot_img_hdr_v3>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(boot_img_hdr_v3))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).magic) as usize - ptr as usize },
+ 0usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(magic))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).kernel_size) as usize - ptr as usize },
+ 8usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(kernel_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_size) as usize - ptr as usize },
+ 12usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(ramdisk_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).os_version) as usize - ptr as usize },
+ 16usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(os_version))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).header_size) as usize - ptr as usize },
+ 20usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(header_size))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
+ 24usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(reserved))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).header_version) as usize - ptr as usize },
+ 40usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(header_version))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).cmdline) as usize - ptr as usize },
+ 44usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v3), "::", stringify!(cmdline))
+ );
+}
+impl Default for boot_img_hdr_v3 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct vendor_boot_img_hdr_v3 {
+ pub magic: [u8; 8usize],
+ pub header_version: u32,
+ pub page_size: u32,
+ pub kernel_addr: u32,
+ pub ramdisk_addr: u32,
+ pub vendor_ramdisk_size: u32,
+ pub cmdline: [u8; 2048usize],
+ pub tags_addr: u32,
+ pub name: [u8; 16usize],
+ pub header_size: u32,
+ pub dtb_size: u32,
+ pub dtb_addr: u64,
+}
+#[test]
+fn bindgen_test_layout_vendor_boot_img_hdr_v3() {
+ const UNINIT: ::core::mem::MaybeUninit<vendor_boot_img_hdr_v3> =
+ ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<vendor_boot_img_hdr_v3>(),
+ 2112usize,
+ concat!("Size of: ", stringify!(vendor_boot_img_hdr_v3))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<vendor_boot_img_hdr_v3>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(vendor_boot_img_hdr_v3))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).magic) as usize - ptr as usize },
+ 0usize,
+ concat!("Offset of field: ", stringify!(vendor_boot_img_hdr_v3), "::", stringify!(magic))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).header_version) as usize - ptr as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(header_version)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).page_size) as usize - ptr as usize },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(page_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).kernel_addr) as usize - ptr as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(kernel_addr)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_addr) as usize - ptr as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(ramdisk_addr)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).vendor_ramdisk_size) as usize - ptr as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(vendor_ramdisk_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).cmdline) as usize - ptr as usize },
+ 28usize,
+ concat!("Offset of field: ", stringify!(vendor_boot_img_hdr_v3), "::", stringify!(cmdline))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).tags_addr) as usize - ptr as usize },
+ 2076usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(tags_addr)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).name) as usize - ptr as usize },
+ 2080usize,
+ concat!("Offset of field: ", stringify!(vendor_boot_img_hdr_v3), "::", stringify!(name))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).header_size) as usize - ptr as usize },
+ 2096usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(header_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).dtb_size) as usize - ptr as usize },
+ 2100usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(dtb_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).dtb_addr) as usize - ptr as usize },
+ 2104usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v3),
+ "::",
+ stringify!(dtb_addr)
+ )
+ );
+}
+impl Default for vendor_boot_img_hdr_v3 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct boot_img_hdr_v4 {
+ pub _base: boot_img_hdr_v3,
+ pub signature_size: u32,
+}
+#[test]
+fn bindgen_test_layout_boot_img_hdr_v4() {
+ const UNINIT: ::core::mem::MaybeUninit<boot_img_hdr_v4> = ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<boot_img_hdr_v4>(),
+ 1584usize,
+ concat!("Size of: ", stringify!(boot_img_hdr_v4))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<boot_img_hdr_v4>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(boot_img_hdr_v4))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).signature_size) as usize - ptr as usize },
+ 1580usize,
+ concat!("Offset of field: ", stringify!(boot_img_hdr_v4), "::", stringify!(signature_size))
+ );
+}
+impl Default for boot_img_hdr_v4 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct vendor_boot_img_hdr_v4 {
+ pub _base: vendor_boot_img_hdr_v3,
+ pub vendor_ramdisk_table_size: u32,
+ pub vendor_ramdisk_table_entry_num: u32,
+ pub vendor_ramdisk_table_entry_size: u32,
+ pub bootconfig_size: u32,
+}
+#[test]
+fn bindgen_test_layout_vendor_boot_img_hdr_v4() {
+ const UNINIT: ::core::mem::MaybeUninit<vendor_boot_img_hdr_v4> =
+ ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<vendor_boot_img_hdr_v4>(),
+ 2128usize,
+ concat!("Size of: ", stringify!(vendor_boot_img_hdr_v4))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<vendor_boot_img_hdr_v4>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(vendor_boot_img_hdr_v4))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).vendor_ramdisk_table_size) as usize - ptr as usize },
+ 2112usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v4),
+ "::",
+ stringify!(vendor_ramdisk_table_size)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ ::core::ptr::addr_of!((*ptr).vendor_ramdisk_table_entry_num) as usize - ptr as usize
+ },
+ 2116usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v4),
+ "::",
+ stringify!(vendor_ramdisk_table_entry_num)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ ::core::ptr::addr_of!((*ptr).vendor_ramdisk_table_entry_size) as usize - ptr as usize
+ },
+ 2120usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v4),
+ "::",
+ stringify!(vendor_ramdisk_table_entry_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).bootconfig_size) as usize - ptr as usize },
+ 2124usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_boot_img_hdr_v4),
+ "::",
+ stringify!(bootconfig_size)
+ )
+ );
+}
+impl Default for vendor_boot_img_hdr_v4 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}
+#[repr(C, packed)]
+#[derive(AsBytes, FromBytes, PartialEq, Copy, Clone, Debug)]
+pub struct vendor_ramdisk_table_entry_v4 {
+ pub ramdisk_size: u32,
+ pub ramdisk_offset: u32,
+ pub ramdisk_type: u32,
+ pub ramdisk_name: [u8; 32usize],
+ pub board_id: [u32; 16usize],
+}
+#[test]
+fn bindgen_test_layout_vendor_ramdisk_table_entry_v4() {
+ const UNINIT: ::core::mem::MaybeUninit<vendor_ramdisk_table_entry_v4> =
+ ::core::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::core::mem::size_of::<vendor_ramdisk_table_entry_v4>(),
+ 108usize,
+ concat!("Size of: ", stringify!(vendor_ramdisk_table_entry_v4))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<vendor_ramdisk_table_entry_v4>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(vendor_ramdisk_table_entry_v4))
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_size) as usize - ptr as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_ramdisk_table_entry_v4),
+ "::",
+ stringify!(ramdisk_size)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_offset) as usize - ptr as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_ramdisk_table_entry_v4),
+ "::",
+ stringify!(ramdisk_offset)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_type) as usize - ptr as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_ramdisk_table_entry_v4),
+ "::",
+ stringify!(ramdisk_type)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).ramdisk_name) as usize - ptr as usize },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_ramdisk_table_entry_v4),
+ "::",
+ stringify!(ramdisk_name)
+ )
+ );
+ assert_eq!(
+ unsafe { ::core::ptr::addr_of!((*ptr).board_id) as usize - ptr as usize },
+ 44usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(vendor_ramdisk_table_entry_v4),
+ "::",
+ stringify!(board_id)
+ )
+ );
+}
+impl Default for vendor_ramdisk_table_entry_v4 {
+ fn default() -> Self {
+ let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
+ unsafe {
+ ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+ s.assume_init()
+ }
+ }
+}