zerocopy

zerocopy crate(源自 Fuchsia)提供了 trait 和宏,用于确保在字节序列和其他类型之间进行安全转换。

  1. use zerocopy::AsBytes;
  2. #[repr(u32)]
  3. #[derive(AsBytes, Debug, Default)]
  4. enum RequestType {
  5. #[default]
  6. In = 0,
  7. Out = 1,
  8. Flush = 4,
  9. }
  10. #[repr(C)]
  11. #[derive(AsBytes, Debug, Default)]
  12. struct VirtioBlockRequest {
  13. request_type: RequestType,
  14. reserved: u32,
  15. sector: u64,
  16. }
  17. fn main() {
  18. let request = VirtioBlockRequest {
  19. request_type: RequestType::Flush,
  20. sector: 42,
  21. ..Default::default()
  22. };
  23. assert_eq!(
  24. request.as_bytes(),
  25. &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]
  26. );
  27. }

这不适用于 MMIO(因为它不使用易失性读取和写入),但在与硬件共享的结构(例如通过 DMA 传输或发送到外部接口)中进行操作时会很有用。

  • 对于可以接受任何字节模式的类型,都可以实现 FromBytes方法,因此可以对不受信任的字节序列进行安全转换。
  • 如果尝试为这些类型派生 FromBytes,都将会失败,因为 RequestType 不会将所有可能的 u32 值用作判别标识,所以并非所有的字节模式都有效。
  • zerocopy::byteorder 提供了适用于字节顺序感知的数字基元类型。
  • 使用 src/bare-metal/useful-crates/zerocopy-example/ 目录下的 cargo run 运行该示例。(由于存在 crate 依赖项,无法在 Playground 中运行该示例。)