kernel/drivers/special/
null.rs

1//! Null character device
2//!
3//! Behavior:
4//! - Read: always returns EOF (0 bytes)
5//! - Write: discards all data and reports success
6//! - `can_read`/`can_write`: always true
7//!
8//! It is registered in the `DeviceManager` with the name `"null"`,
9//! and is expected to appear as `/dev/null` via DevFS.
10
11extern crate alloc;
12
13use alloc::{string::String, sync::Arc};
14use core::any::Any;
15
16use crate::{
17    device::{self, Device, DeviceType, char::CharDevice, manager::DeviceManager},
18    driver_initcall,
19    object::capability::{ControlOps, MemoryMappingOps, selectable::Selectable},
20};
21
22pub struct NullDevice;
23
24impl Selectable for NullDevice {
25    fn wait_until_ready(
26        &self,
27        _interest: crate::object::capability::selectable::ReadyInterest,
28        _trapframe: &mut crate::arch::Trapframe,
29        _timeout_ticks: Option<u64>,
30    ) -> crate::object::capability::selectable::SelectWaitOutcome {
31        crate::object::capability::selectable::SelectWaitOutcome::Ready
32    }
33}
34
35impl Device for NullDevice {
36    fn device_type(&self) -> DeviceType {
37        DeviceType::Char
38    }
39
40    fn name(&self) -> &'static str {
41        "null"
42    }
43
44    fn as_any(&self) -> &dyn Any {
45        self
46    }
47
48    fn as_any_mut(&mut self) -> &mut dyn Any {
49        self
50    }
51
52    fn as_char_device(&self) -> Option<&dyn device::char::CharDevice> {
53        Some(self)
54    }
55}
56
57impl CharDevice for NullDevice {
58    fn read_byte(&self) -> Option<u8> {
59        // Always EOF
60        None
61    }
62
63    fn write_byte(&self, _byte: u8) -> Result<(), &'static str> {
64        // Discard the data
65        Ok(())
66    }
67
68    fn can_read(&self) -> bool {
69        // Always readable (immediate EOF)
70        true
71    }
72
73    fn can_write(&self) -> bool {
74        true
75    }
76}
77
78impl ControlOps for NullDevice {
79    fn control(&self, _command: u32, _arg: usize) -> Result<i32, &'static str> {
80        Err("Control operations not supported")
81    }
82}
83
84impl MemoryMappingOps for NullDevice {
85    fn get_mapping_info(
86        &self,
87        _offset: usize,
88        _length: usize,
89    ) -> Result<(usize, usize, bool), &'static str> {
90        Err("Memory mapping not supported by null device")
91    }
92
93    fn supports_mmap(&self) -> bool {
94        false
95    }
96}
97
98fn register_null_device() {
99    let dm = DeviceManager::get_manager();
100    let dev: Arc<dyn Device> = Arc::new(NullDevice);
101    // Register with explicit name: "null"
102    let id = dm.register_device_with_name(String::from("null"), dev);
103    crate::early_println!("Null device registered as 'null' with ID: {}", id);
104}
105
106driver_initcall!(register_null_device);