proka_kernel/drivers/block/
ramblk.rs1use crate::drivers::device::{BlockDevice, DeviceError, DeviceType, SharedDeviceOps};
2extern crate alloc;
3use alloc::string::{String, ToString};
4use alloc::vec;
5use alloc::vec::Vec;
6use spin::RwLock;
7
8#[allow(dead_code)]
9pub struct RamBlockDevice {
10 name: String,
11 storage: RwLock<Vec<u8>>,
12 block_size: usize,
13}
14
15impl RamBlockDevice {
16 #[allow(dead_code)]
17 pub fn new(num_blocks: usize, block_size: usize) -> Self {
18 Self {
19 name: "ramdisk".to_string(),
20 storage: RwLock::new(vec![0; num_blocks * block_size]),
21 block_size,
22 }
23 }
24}
25
26impl SharedDeviceOps for RamBlockDevice {
27 fn name(&self) -> &str {
28 &self.name
29 }
30
31 fn device_type(&self) -> DeviceType {
32 DeviceType::Block
33 }
34
35 fn open(&self) -> Result<(), DeviceError> {
36 Ok(())
37 }
38
39 fn close(&self) -> Result<(), DeviceError> {
40 Ok(())
41 }
42
43 fn ioctl(&self, _cmd: u64, _arg: u64) -> Result<u64, DeviceError> {
44 Err(DeviceError::NotSupported)
45 }
46}
47
48impl BlockDevice for RamBlockDevice {
49 fn block_size(&self) -> usize {
50 self.block_size
51 }
52
53 fn num_blocks(&self) -> usize {
54 self.storage.read().len() / self.block_size
55 }
56
57 fn read_blocks(
58 &self,
59 block_idx: usize,
60 num_blocks: usize,
61 buf: &mut [u8],
62 ) -> Result<usize, DeviceError> {
63 let start = block_idx * self.block_size;
64 let end = start + num_blocks * self.block_size;
65 let storage = self.storage.read();
66
67 if end > storage.len() {
68 return Err(DeviceError::AddressOutOfRange);
69 }
70
71 if buf.len() < end - start {
72 return Err(DeviceError::BufferTooSmall);
73 }
74
75 buf[..end - start].copy_from_slice(&storage[start..end]);
76 Ok(num_blocks)
77 }
78
79 fn write_blocks(
80 &self,
81 block_idx: usize,
82 num_blocks: usize,
83 buf: &[u8],
84 ) -> Result<usize, DeviceError> {
85 let start = block_idx * self.block_size;
86 let end = start + num_blocks * self.block_size;
87 let mut storage = self.storage.write();
88
89 if end > storage.len() {
90 return Err(DeviceError::AddressOutOfRange);
91 }
92
93 if buf.len() < end - start {
94 return Err(DeviceError::InvalidParam);
95 }
96
97 storage[start..end].copy_from_slice(&buf[..end - start]);
98 Ok(num_blocks)
99 }
100}