zerocopy

FuchsiaνŒ€μ΄ λ§Œλ“  zerocopy ν¬λ ˆμ΄νŠΈλŠ” λ°”μ΄νŠΈ μ‹œν€€μŠ€λ₯Ό λ‹€λ₯Έ νƒ€μž…μœΌλ‘œ μ•ˆμ „ν•˜κ²Œ λ³€ν™˜ν•˜κΈ° μœ„ν•œ νŠΈλ ˆμž‡ 및 맀크둜λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

use zerocopy::AsBytes;

#[repr(u32)]
#[derive(AsBytes, Debug, Default)]
enum RequestType {
    #[default]
    In = 0,
    Out = 1,
    Flush = 4,
}

#[repr(C)]
#[derive(AsBytes, Debug, Default)]
struct VirtioBlockRequest {
    request_type: RequestType,
    reserved: u32,
    sector: u64,
}

fn main() {
    let request = VirtioBlockRequest {
        request_type: RequestType::Flush,
        sector: 42,
        ..Default::default()
    };

    assert_eq!(
        request.as_bytes(),
        &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]
    );
}

이 ν¬λ ˆμ΄νŠΈλŠ” νœ˜λ°œμ„±(volatile) 읽기 및 μ“°κΈ°λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ MMIO에 μ ν•©ν•˜μ§€ μ•Šμ§€λ§Œ, ν•˜λ“œμ›¨μ–΄μ™€ κ³΅μœ λ˜κ±°λ‚˜(예: DMAμ—μ„œ) μ™Έμž₯ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 μ „μ†‘λ˜λŠ” ꡬ쑰체λ₯Ό λ‹€λ£¨λŠ” λ°μ—λŠ” μœ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • μ–΄λ–€ νƒ€μž…μ΄ κ°€λŠ₯ν•œ λͺ¨λ“  λ°”μ΄νŠΈ νŒ¨ν„΄λ“€μ— λŒ€ν•΄ μ˜¬λ°”λ₯Έ 값을 κ°€μ§ˆ λ•Œμ—λ§Œ , κ·Έ νƒ€μž…μ΄ FromBytesλ₯Ό κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλ ‡κ²Œ ν•΄μ„œ μ‹ λ’°ν•  수 μ—†λŠ” λ°”μ΄νŠΈ μ‹œν€€μŠ€λ₯Ό μ•ˆμ „ν•˜κ²Œ ν•΄λ‹Ή νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μœ„ μ½”λ“œμ—μ„œ μ •μ˜ν•œ νƒ€μž…μ— λŒ€ν•΄ FromBytesλ₯Ό κ΅¬ν˜„ν•˜λ €κ³  ν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€. RequestType은 κ°€λŠ₯ν•œ λͺ¨λ“  u32 값을 μ‹λ³„μžλ‘œ 받아듀이지 μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 즉 λͺ¨λ“  λ°”μ΄νŠΈ νŒ¨ν„΄μ΄ μœ νš¨ν•œ RequestType값은 μ•„λ‹™λ‹ˆλ‹€.
  • zerocopy::byteorderμ—λŠ” λ°”μ΄νŠΈ μ˜€λ”μ— λ”°λ₯Έ μ„œλ‘œ λ‹€λ₯Έ ν‘œν˜„ 방식을 μ§€μ›ν•˜λŠ” 숫자 νƒ€μž…μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
  • src/bare-metal/useful-crates/zerocopy-example/μ—μ„œ cargo run을 μ‚¬μš©ν•˜μ—¬ μ˜ˆμ‹œλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€(쒅속성 문제둜 인해 ν”Œλ ˆμ΄κ·ΈλΌμš΄λ“œμ—μ„œλŠ” μ‹€ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€).