drivers/android/binder/rust_binder_main.rs

Source file repositories/reference/linux-study-clean/drivers/android/binder/rust_binder_main.rs

File Facts

System
Linux kernel
Corpus path
drivers/android/binder/rust_binder_main.rs
Extension
.rs
Size
18745 bytes
Lines
619
Domain
Driver Families
Bucket
drivers/android
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct DeliverCode {
    code: u32,
    skip: Atomic<bool>,
}

kernel::list::impl_list_arc_safe! {
    impl ListArcSafe<0> for DeliverCode { untracked; }
}

impl DeliverCode {
    fn new(code: u32) -> Self {
        Self {
            code,
            skip: Atomic::new(false),
        }
    }

    /// Disable this DeliverCode and make it do nothing.
    ///
    /// This is used instead of removing it from the work list, since `LinkedList::remove` is
    /// unsafe, whereas this method is not.
    fn skip(&self) {
        self.skip.store(true, Relaxed);
    }
}

impl DeliverToRead for DeliverCode {
    fn do_work(
        self: DArc<Self>,
        _thread: &Thread,
        writer: &mut BinderReturnWriter<'_>,
    ) -> Result<bool> {
        if !self.skip.load(Relaxed) {
            writer.write_code(self.code)?;
        }
        Ok(true)
    }

    fn cancel(self: DArc<Self>) {}

    fn should_sync_wakeup(&self) -> bool {
        false
    }

    fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
        seq_print!(m, "{}", prefix);
        if self.skip.load(Relaxed) {
            seq_print!(m, "(skipped) ");
        }
        if self.code == defs::BR_TRANSACTION_COMPLETE {
            seq_print!(m, "transaction complete\n");
        } else {
            seq_print!(m, "transaction error: {}\n", self.code);
        }
        Ok(())
    }
}

fn ptr_align(value: usize) -> Option<usize> {
    let size = core::mem::size_of::<usize>() - 1;
    Some(value.checked_add(size)? & !size)
}

// SAFETY: We call register in `init`.
static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };

struct BinderModule {}

impl kernel::Module for BinderModule {
    fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
        // SAFETY: The module initializer never runs twice, so we only call this once.
        unsafe { crate::context::CONTEXTS.init() };

        BINDER_SHRINKER.register(c"android-binder")?;

        // SAFETY: The module is being loaded, so we can initialize binderfs.
        unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? };

        Ok(Self {})
    }
}

/// Makes the inner type Sync.
#[repr(transparent)]
pub struct AssertSync<T>(T);
// SAFETY: Used only to insert C bindings types into globals, which is safe.
unsafe impl<T> Sync for AssertSync<T> {}

/// File operations that rust_binderfs.c can use.
#[no_mangle]

Annotation

Implementation Notes