1 /// 引入Module
2 use crate::{
3 driver::base::{
4 device::{
5 device_number::{DeviceNumber, Major},
6 Device, DeviceError, IdTable, BLOCKDEVS,
7 },
8 map::{
9 DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START,
10 DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX,
11 },
12 },
13 kerror,
14 };
15
16 use alloc::{sync::Arc, vec::Vec};
17 use core::any::Any;
18 use system_error::SystemError;
19
20 use super::disk_info::Partition;
21
22 /// 该文件定义了 Device 和 BlockDevice 的接口
23 /// Notice 设备错误码使用 Posix 规定的 int32_t 的错误码表示,而不是自己定义错误enum
24
25 // 使用方法:
26 // 假设 blk_dev 是块设备
27 // <blk_dev as Device>::read_at() 调用的是Device的函数
28 // <blk_dev as BlockDevice>::read_at() 调用的是BlockDevice的函数
29
30 /// 定义类型
31 pub type BlockId = usize;
32
33 /// 定义常量
34 pub const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超过 1 << 12.
35 /// 在DragonOS中,我们认为磁盘的每个LBA大小均为512字节。(注意,文件系统的1个扇区可能事实上是多个LBA)
36 pub const LBA_SIZE: usize = 512;
37
38 /// @brief 块设备的迭代器
39 /// @usage 某次操作读/写块设备的[L,R]范围内的字节,
40 /// 那么可以使用此结构体进行迭代遍历,每次调用next()返回一个BlockRange
41 pub struct BlockIter {
42 pub begin: usize, // 迭代器的起始位置 -> 块设备的地址 (单位是字节)
43 pub end: usize,
44 pub blk_size_log2: u8,
45 pub multiblock: bool, // 是否启用连续整块同时遍历
46 }
47
48 /// @brief Range搭配迭代器BlockIter使用,[L,R]区间被分割成多个小的Range
49 /// Range要么是整块,要么是一块的某一部分
50 /// 细节: range = [begin, end) 左闭右开
51 pub struct BlockRange {
52 pub lba_start: usize, // 起始块的lba_id
53 pub lba_end: usize, // 终止块的lba_id
54 pub begin: usize, // 起始位置在块内的偏移量, 如果BlockIter启用Multiblock,则是多个块的偏移量
55 pub end: usize, // 结束位置在块内的偏移量,单位是字节
56 pub blk_size_log2: u8,
57 }
58
59 impl BlockIter {
60 #[allow(dead_code)]
new(start_addr: usize, end_addr: usize, blk_size_log2: u8) -> BlockIter61 pub fn new(start_addr: usize, end_addr: usize, blk_size_log2: u8) -> BlockIter {
62 return BlockIter {
63 begin: start_addr,
64 end: end_addr,
65 blk_size_log2: blk_size_log2,
66 multiblock: false,
67 };
68 }
new_multiblock(start_addr: usize, end_addr: usize, blk_size_log2: u8) -> BlockIter69 pub fn new_multiblock(start_addr: usize, end_addr: usize, blk_size_log2: u8) -> BlockIter {
70 return BlockIter {
71 begin: start_addr,
72 end: end_addr,
73 blk_size_log2: blk_size_log2,
74 multiblock: true,
75 };
76 }
77
78 /// 获取下一个整块或者不完整的块
next_block(&mut self) -> BlockRange79 pub fn next_block(&mut self) -> BlockRange {
80 let blk_size_log2 = self.blk_size_log2;
81 let blk_size = 1usize << self.blk_size_log2;
82 let lba_id = self.begin / blk_size;
83 let begin = self.begin % blk_size;
84 let end = if lba_id == self.end / blk_size {
85 self.end % blk_size
86 } else {
87 blk_size
88 };
89
90 self.begin += end - begin;
91
92 return BlockRange {
93 lba_start: lba_id,
94 lba_end: lba_id + 1,
95 begin: begin,
96 end: end,
97 blk_size_log2: blk_size_log2,
98 };
99 }
100
101 /// 如果能返回多个连续的整块,则返回;否则调用next_block()返回不完整的块
next_multiblock(&mut self) -> BlockRange102 pub fn next_multiblock(&mut self) -> BlockRange {
103 let blk_size_log2 = self.blk_size_log2;
104 let blk_size = 1usize << self.blk_size_log2;
105 let lba_start = self.begin / blk_size;
106 let lba_end = self.end / blk_size;
107
108 // 如果不是整块,先返回非整块的小部分
109 if __bytes_to_lba(self.begin, blk_size)
110 != __bytes_to_lba(self.begin + blk_size - 1, blk_size)
111 || lba_start == lba_end
112 {
113 return self.next_block();
114 }
115
116 let begin = self.begin % blk_size; // 因为是多个整块,这里必然是0
117 let end = __lba_to_bytes(lba_end, blk_size) - self.begin;
118
119 self.begin += end - begin;
120
121 return BlockRange {
122 lba_start: lba_start,
123 lba_end: lba_end,
124 begin: begin,
125 end: end,
126 blk_size_log2: blk_size_log2,
127 };
128 }
129 }
130
131 /// BlockIter 函数实现
132 impl Iterator for BlockIter {
133 type Item = BlockRange;
134
next(&mut self) -> Option<<Self as Iterator>::Item>135 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
136 if self.begin >= self.end {
137 return None;
138 }
139 if self.multiblock {
140 return Some(self.next_multiblock());
141 } else {
142 return Some(self.next_block());
143 }
144 }
145 }
146
147 /// BlockRange 函数实现
148 impl BlockRange {
149 #[allow(dead_code)]
is_empty(&self) -> bool150 pub fn is_empty(&self) -> bool {
151 return self.end == self.begin;
152 }
len(&self) -> usize153 pub fn len(&self) -> usize {
154 return self.end - self.begin;
155 }
156 /// 判断是不是整块
is_full(&self) -> bool157 pub fn is_full(&self) -> bool {
158 return self.len() == (1usize << self.blk_size_log2);
159 }
160 /// 判断是不是多个整块连在一起
is_multi(&self) -> bool161 pub fn is_multi(&self) -> bool {
162 return self.len() >= (1usize << self.blk_size_log2)
163 && (self.len() % (1usize << self.blk_size_log2) == 0);
164 }
165 /// 获取 BlockRange 在块设备内部的起始位置 (单位是字节)
origin_begin(&self) -> usize166 pub fn origin_begin(&self) -> usize {
167 return (self.lba_start << self.blk_size_log2) + self.begin;
168 }
169 /// 获取 BlockRange 在块设备内部的结尾位置 (单位是字节)
origin_end(&self) -> usize170 pub fn origin_end(&self) -> usize {
171 return (self.lba_start << self.blk_size_log2) + self.end;
172 }
173 }
174
175 /// 从字节地址转换到lba id
176 #[inline]
__bytes_to_lba(addr: usize, blk_size: usize) -> BlockId177 pub fn __bytes_to_lba(addr: usize, blk_size: usize) -> BlockId {
178 return addr / blk_size;
179 }
180
181 /// 从lba id转换到字节地址, 返回lba_id的最左侧字节
182 #[inline]
__lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId183 pub fn __lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId {
184 return lba_id * blk_size;
185 }
186
187 /// @brief 块设备应该实现的操作
188 pub trait BlockDevice: Device {
189 /// @brief: 在块设备中,从第lba_id_start个块开始,读取count个块数据,存放到buf中
190 ///
191 /// @parameter lba_id_start: 起始块
192 /// @parameter count: 读取块的数量
193 /// @parameter buf: 目标数组
194 /// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
195 /// 否则返回Err(错误码),其中错误码为负数;
196 /// 如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
read_at( &self, lba_id_start: BlockId, count: usize, buf: &mut [u8], ) -> Result<usize, SystemError>197 fn read_at(
198 &self,
199 lba_id_start: BlockId,
200 count: usize,
201 buf: &mut [u8],
202 ) -> Result<usize, SystemError>;
203
204 /// @brief: 在块设备中,从第lba_id_start个块开始,把buf中的count个块数据,存放到设备中
205 /// @parameter lba_id_start: 起始块
206 /// @parameter count: 写入块的数量
207 /// @parameter buf: 目标数组
208 /// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
209 /// 否则返回Err(错误码),其中错误码为负数;
210 /// 如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
write_at( &self, lba_id_start: BlockId, count: usize, buf: &[u8], ) -> Result<usize, SystemError>211 fn write_at(
212 &self,
213 lba_id_start: BlockId,
214 count: usize,
215 buf: &[u8],
216 ) -> Result<usize, SystemError>;
217
218 /// @brief: 同步磁盘信息,把所有的dirty数据写回硬盘 - 待实现
sync(&self) -> Result<(), SystemError>219 fn sync(&self) -> Result<(), SystemError>;
220
221 /// @brief: 每个块设备都必须固定自己块大小,而且该块大小必须是2的幂次
222 /// @return: 返回一个固定量,硬编码(编程的时候固定的常量).
blk_size_log2(&self) -> u8223 fn blk_size_log2(&self) -> u8;
224
225 // TODO: 待实现 open, close
226
227 /// @brief 本函数用于实现动态转换。
228 /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
as_any_ref(&self) -> &dyn Any229 fn as_any_ref(&self) -> &dyn Any;
230
231 /// @brief 本函数用于将BlockDevice转换为Device。
232 /// 由于实现了BlockDevice的结构体,本身也实现了Device Trait, 因此转换是可能的。
233 /// 思路:在BlockDevice的结构体中新增一个self_ref变量,返回self_ref.upgrade()即可。
device(&self) -> Arc<dyn Device>234 fn device(&self) -> Arc<dyn Device>;
235
236 /// @brief 返回块设备的块大小(单位:字节)
block_size(&self) -> usize237 fn block_size(&self) -> usize;
238
239 /// @brief 返回当前磁盘上的所有分区的Arc指针数组
partitions(&self) -> Vec<Arc<Partition>>240 fn partitions(&self) -> Vec<Arc<Partition>>;
241
write_at_bytes(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError>242 fn write_at_bytes(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
243 // assert!(len <= buf.len());
244 if len > buf.len() {
245 return Err(SystemError::E2BIG);
246 }
247
248 let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
249 let multi = iter.multiblock;
250
251 for range in iter {
252 let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
253 let buf_end = range.origin_end() - offset;
254 let buf_slice = &buf[buf_begin..buf_end];
255 let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
256 let full = multi && range.is_multi() || !multi && range.is_full();
257
258 if full {
259 self.write_at(range.lba_start, count, buf_slice)?;
260 } else {
261 if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
262 return Err(SystemError::E2BIG);
263 }
264
265 let mut temp = Vec::new();
266 temp.resize(1usize << self.blk_size_log2(), 0);
267 // 由于块设备每次读写都是整块的,在不完整写入之前,必须把不完整的地方补全
268 self.read_at(range.lba_start, 1, &mut temp[..])?;
269 // 把数据从临时buffer复制到目标buffer
270 temp[range.begin..range.end].copy_from_slice(&buf_slice);
271 self.write_at(range.lba_start, 1, &temp[..])?;
272 }
273 }
274 return Ok(len);
275 //self.0.lock().write_at(lba_id_start, count, buf)
276 }
277
read_at_bytes( &self, offset: usize, len: usize, buf: &mut [u8], ) -> Result<usize, SystemError>278 fn read_at_bytes(
279 &self,
280 offset: usize,
281 len: usize,
282 buf: &mut [u8],
283 ) -> Result<usize, SystemError> {
284 if len > buf.len() {
285 return Err(SystemError::E2BIG);
286 }
287
288 let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
289 let multi = iter.multiblock;
290
291 // 枚举每一个range
292 for range in iter {
293 let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
294 let buf_end = range.origin_end() - offset;
295 let buf_slice = &mut buf[buf_begin..buf_end];
296 let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
297 let full = multi && range.is_multi() || !multi && range.is_full();
298
299 // 读取整个block作为有效数据
300 if full {
301 // 调用 BlockDevice::read_at() 直接把引用传进去,不是把整个数组move进去
302 self.read_at(range.lba_start, count, buf_slice)?;
303 } else {
304 // 判断块的长度不能超过最大值
305 if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
306 return Err(SystemError::E2BIG);
307 }
308
309 let mut temp = Vec::new();
310 temp.resize(1usize << self.blk_size_log2(), 0);
311 self.read_at(range.lba_start, 1, &mut temp[..])?;
312
313 // 把数据从临时buffer复制到目标buffer
314 buf_slice.copy_from_slice(&temp[range.begin..range.end]);
315 }
316 }
317 return Ok(len);
318
319 // kdebug!(
320 // "ahci read at {lba_id_start}, count={count}, lock={:?}",
321 // self.0
322 // );
323 }
324 }
325
326 /// @brief 块设备框架函数集
327 pub struct BlockDeviceOps;
328
329 impl BlockDeviceOps {
330 /// @brief: 主设备号转下标
331 /// @parameter: major: 主设备号
332 /// @return: 返回下标
333 #[allow(dead_code)]
major_to_index(major: Major) -> usize334 fn major_to_index(major: Major) -> usize {
335 return (major.data() % DEV_MAJOR_HASH_SIZE as u32) as usize;
336 }
337
338 /// @brief: 动态获取主设备号
339 /// @parameter: None
340 /// @return: 如果成功,返回主设备号,否则,返回错误码
341 #[allow(dead_code)]
find_dynamic_major() -> Result<Major, SystemError>342 fn find_dynamic_major() -> Result<Major, SystemError> {
343 let blockdevs = BLOCKDEVS.lock();
344 // 寻找主设备号为234~255的设备
345 for index in ((DEV_MAJOR_DYN_END.data())..DEV_MAJOR_HASH_SIZE).rev() {
346 if let Some(item) = blockdevs.get(index as usize) {
347 if item.is_empty() {
348 return Ok(Major::new(index)); // 返回可用的主设备号
349 }
350 }
351 }
352 // 寻找主设备号在384~511的设备
353 for index in
354 ((DEV_MAJOR_DYN_EXT_END.data() + 1)..(DEV_MAJOR_DYN_EXT_START.data() + 1)).rev()
355 {
356 if let Some(blockdevss) = blockdevs.get(Self::major_to_index(Major::new(index as u32)))
357 {
358 let mut flag = true;
359 for item in blockdevss {
360 if item.device_number().major() == Major::new(index as u32) {
361 flag = false;
362 break;
363 }
364 }
365 if flag {
366 // 如果数组中不存在主设备号等于index的设备
367 return Ok(Major::new(index)); // 返回可用的主设备号
368 }
369 }
370 }
371 return Err(SystemError::EBUSY);
372 }
373
374 /// @brief: 注册设备号,该函数需要指定主设备号
375 /// @parameter: from: 主设备号
376 /// count: 次设备号数量
377 /// name: 字符设备名
378 /// @return: 如果注册成功,返回设备号,否则,返回错误码
379 #[allow(dead_code)]
register_blockdev_region( from: DeviceNumber, count: u32, name: &'static str, ) -> Result<DeviceNumber, SystemError>380 pub fn register_blockdev_region(
381 from: DeviceNumber,
382 count: u32,
383 name: &'static str,
384 ) -> Result<DeviceNumber, SystemError> {
385 Self::__register_blockdev_region(from, count, name)
386 }
387
388 /// @brief: 注册设备号,该函数自动分配主设备号
389 /// @parameter: baseminor: 主设备号
390 /// count: 次设备号数量
391 /// name: 字符设备名
392 /// @return: 如果注册成功,返回,否则,返回false
393 #[allow(dead_code)]
alloc_blockdev_region( baseminor: u32, count: u32, name: &'static str, ) -> Result<DeviceNumber, SystemError>394 pub fn alloc_blockdev_region(
395 baseminor: u32,
396 count: u32,
397 name: &'static str,
398 ) -> Result<DeviceNumber, SystemError> {
399 Self::__register_blockdev_region(
400 DeviceNumber::new(Major::UNNAMED_MAJOR, baseminor),
401 count,
402 name,
403 )
404 }
405
406 /// @brief: 注册设备号
407 /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
408 /// minorct: 次设备号数量
409 /// name: 字符设备名
410 /// @return: 如果注册成功,返回设备号,否则,返回错误码
__register_blockdev_region( device_number: DeviceNumber, minorct: u32, name: &'static str, ) -> Result<DeviceNumber, SystemError>411 fn __register_blockdev_region(
412 device_number: DeviceNumber,
413 minorct: u32,
414 name: &'static str,
415 ) -> Result<DeviceNumber, SystemError> {
416 let mut major = device_number.major();
417 let baseminor = device_number.minor();
418 if major >= DEV_MAJOR_MAX {
419 kerror!(
420 "DEV {} major requested {:?} is greater than the maximum {}\n",
421 name,
422 major,
423 DEV_MAJOR_MAX.data() - 1
424 );
425 }
426 if minorct > DeviceNumber::MINOR_MASK + 1 - baseminor {
427 kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
428 name, baseminor, baseminor + minorct - 1, 0, DeviceNumber::MINOR_MASK);
429 }
430 let blockdev = DeviceStruct::new(DeviceNumber::new(major, baseminor), minorct, name);
431 if major == Major::UNNAMED_MAJOR {
432 // 如果主设备号为0,则自动分配主设备号
433 major = Self::find_dynamic_major().expect("Find synamic major error.\n");
434 }
435 if let Some(items) = BLOCKDEVS.lock().get_mut(Self::major_to_index(major)) {
436 let mut insert_index: usize = 0;
437 for (index, item) in items.iter().enumerate() {
438 insert_index = index;
439 match item.device_number().major().cmp(&major) {
440 core::cmp::Ordering::Less => continue,
441 core::cmp::Ordering::Greater => {
442 break; // 大于则向后插入
443 }
444 core::cmp::Ordering::Equal => {
445 if item.device_number().minor() + item.minorct() <= baseminor {
446 continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
447 }
448 if item.base_minor() >= baseminor + minorct {
449 break; // 在此处插入
450 }
451 return Err(SystemError::EBUSY); // 存在重合的次设备号
452 }
453 }
454 }
455 items.insert(insert_index, blockdev);
456 }
457
458 return Ok(DeviceNumber::new(major, baseminor));
459 }
460
461 /// @brief: 注销设备号
462 /// @parameter: major: 主设备号,如果为0,动态分配
463 /// baseminor: 起始次设备号
464 /// minorct: 次设备号数量
465 /// @return: 如果注销成功,返回(),否则,返回错误码
__unregister_blockdev_region( device_number: DeviceNumber, minorct: u32, ) -> Result<(), SystemError>466 fn __unregister_blockdev_region(
467 device_number: DeviceNumber,
468 minorct: u32,
469 ) -> Result<(), SystemError> {
470 if let Some(items) = BLOCKDEVS
471 .lock()
472 .get_mut(Self::major_to_index(device_number.major()))
473 {
474 for (index, item) in items.iter().enumerate() {
475 if item.device_number() == device_number && item.minorct() == minorct {
476 // 设备号和数量都相等
477 items.remove(index);
478 return Ok(());
479 }
480 }
481 }
482 return Err(SystemError::EBUSY);
483 }
484
485 /// @brief: 块设备注册
486 /// @parameter: cdev: 字符设备实例
487 /// dev_t: 字符设备号
488 /// range: 次设备号范围
489 /// @return: none
490 #[allow(dead_code)]
bdev_add(_bdev: Arc<dyn BlockDevice>, id_table: IdTable) -> Result<(), DeviceError>491 pub fn bdev_add(_bdev: Arc<dyn BlockDevice>, id_table: IdTable) -> Result<(), DeviceError> {
492 if id_table.device_number().data() == 0 {
493 kerror!("Device number can't be 0!\n");
494 }
495 todo!("bdev_add")
496 // return device_manager().add_device(bdev.id_table(), bdev.device());
497 }
498
499 /// @brief: block设备注销
500 /// @parameter: dev_t: 字符设备号
501 /// range: 次设备号范围
502 /// @return: none
503 #[allow(dead_code)]
bdev_del(_devnum: DeviceNumber, _range: usize)504 pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {
505 unimplemented!();
506 }
507 }
508