mod.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. use core::cmp::Ordering;
  2. use super::{
  3. block::block_device::BlockDevice,
  4. char::CharDevice,
  5. device::{mkdev, DeviceNumber, IdTable, KObject, BLOCKDEVS, CHARDEVS, DEVICE_MANAGER, DEVMAP},
  6. };
  7. use crate::{kerror, libs::spinlock::SpinLock, syscall::SystemError};
  8. use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
  9. const KOBJMAP_HASH_SIZE: usize = 255;
  10. const DEV_MAJOR_HASH_SIZE: usize = 255;
  11. const DEV_MAJOR_MAX: usize = 512;
  12. const MINOR_BITS: usize = 20;
  13. const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
  14. /* Marks the bottom of the first segment of free char majors */
  15. const DEV_MAJOR_DYN_END: usize = 234;
  16. /* Marks the top and bottom of the second segment of free char majors */
  17. const DEV_MAJOR_DYN_EXT_START: usize = 511;
  18. const DEV_MAJOR_DYN_EXT_END: usize = 384;
  19. /// @brief: 字符设备与块设备管理结构体
  20. #[derive(Debug, Clone)]
  21. struct Probe(Arc<dyn KObject>);
  22. impl Probe {
  23. /// @brief: 新建probe实例
  24. /// @parameter: data: probe实例
  25. /// @return: probe实例
  26. pub fn new(data: Arc<dyn KObject>) -> Self {
  27. Self(data)
  28. }
  29. }
  30. /// @brief: 字符设备和块设备管理实例(锁)
  31. #[derive(Debug)]
  32. pub struct LockedKObjMap(SpinLock<KObjMap>);
  33. impl Default for LockedKObjMap {
  34. fn default() -> Self {
  35. Self(SpinLock::new(KObjMap::default()))
  36. }
  37. }
  38. /// @brief: 字符设备和块设备管理实例
  39. #[derive(Debug, Clone)]
  40. struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
  41. impl Default for KObjMap {
  42. fn default() -> Self {
  43. Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
  44. }
  45. }
  46. /// @brief: obj设备注册
  47. /// @parameter: domain: 管理实例
  48. /// dev_t: 设备号
  49. /// range: 次设备号范围
  50. /// data: 设备实例
  51. /// @return: none
  52. pub fn kobj_map(
  53. domain: Arc<LockedKObjMap>,
  54. dev_t: DeviceNumber,
  55. range: usize,
  56. data: Arc<dyn KObject>,
  57. ) {
  58. if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
  59. for i in 0..range {
  60. map.insert(
  61. mkdev(dev_t.major(), dev_t.minor() + i),
  62. Probe::new(data.clone()),
  63. );
  64. }
  65. }
  66. }
  67. /// @brief: obj设备注销
  68. /// @parameter: domain: 管理实例
  69. /// dev_t: 设备号
  70. /// range: 次设备号范围
  71. /// @return: none
  72. pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
  73. if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
  74. for i in 0..range {
  75. let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i);
  76. match map.get(rm_dev_t) {
  77. Some(_) => {
  78. map.remove(rm_dev_t);
  79. }
  80. None => {}
  81. }
  82. }
  83. }
  84. }
  85. /// @brief: 设备查找
  86. /// @parameter: domain: 管理实例
  87. /// dev_t: 设备号
  88. /// @return: 查找成功,返回设备实例,否则返回None
  89. #[allow(dead_code)]
  90. pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
  91. if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) {
  92. match map.get(&dev_t) {
  93. Some(value) => {
  94. return Some(value.0.clone());
  95. }
  96. None => {
  97. return None;
  98. }
  99. }
  100. }
  101. return None;
  102. }
  103. // 管理字符设备号的map(加锁)
  104. pub struct LockedDevsMap(SpinLock<DevsMap>);
  105. impl Default for LockedDevsMap {
  106. fn default() -> Self {
  107. LockedDevsMap(SpinLock::new(DevsMap::default()))
  108. }
  109. }
  110. // 管理字符设备号的map
  111. #[derive(Debug)]
  112. struct DevsMap(Vec<Vec<DeviceStruct>>);
  113. impl Default for DevsMap {
  114. fn default() -> Self {
  115. DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE])
  116. }
  117. }
  118. // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
  119. #[allow(dead_code)]
  120. #[derive(Debug, Clone)]
  121. pub struct DeviceStruct {
  122. dev_t: DeviceNumber, //起始设备号
  123. minorct: usize, // 次设备号数量
  124. name: &'static str, //字符设备名
  125. }
  126. impl DeviceStruct {
  127. /// @brief: 创建实例
  128. /// @parameter: dev_t: 设备号
  129. /// minorct: 次设备号数量
  130. /// name: 字符设备名
  131. /// char: 字符设备实例
  132. /// @return: 实例
  133. ///
  134. #[allow(dead_code)]
  135. pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
  136. Self {
  137. dev_t,
  138. minorct,
  139. name,
  140. }
  141. }
  142. /// @brief: 获取起始次设备号
  143. /// @parameter: None
  144. /// @return: 起始设备号
  145. ///
  146. #[allow(dead_code)]
  147. pub fn device_number(&self) -> DeviceNumber {
  148. self.dev_t
  149. }
  150. /// @brief: 获取起始次设备号
  151. /// @parameter: None
  152. /// @return: 起始设备号
  153. ///
  154. #[allow(dead_code)]
  155. pub fn base_minor(&self) -> usize {
  156. self.dev_t.minor()
  157. }
  158. /// @brief: 获取次设备号数量
  159. /// @parameter: None
  160. /// @return: 次设备号数量
  161. #[allow(dead_code)]
  162. pub fn minorct(&self) -> usize {
  163. self.minorct
  164. }
  165. }
  166. // 这下面是考虑到 块设备的注册和字符设备的注册在设备号的自动分配上要有所区别,
  167. // 暂时没有去查具体是怎么做区分的,因此暂时还是一样的
  168. /// @brief 块设备框架函数集
  169. pub struct BlockDeviceOps;
  170. impl BlockDeviceOps {
  171. /// @brief: 主设备号转下标
  172. /// @parameter: major: 主设备号
  173. /// @return: 返回下标
  174. #[allow(dead_code)]
  175. fn major_to_index(major: usize) -> usize {
  176. return major % DEV_MAJOR_HASH_SIZE;
  177. }
  178. /// @brief: 动态获取主设备号
  179. /// @parameter: None
  180. /// @return: 如果成功,返回主设备号,否则,返回错误码
  181. #[allow(dead_code)]
  182. fn find_dynamic_major() -> Result<usize, SystemError> {
  183. let blockdevs = BLOCKDEVS.0.lock();
  184. // 寻找主设备号为234~255的设备
  185. for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
  186. if let Some(item) = blockdevs.0.get(index) {
  187. if item.is_empty() {
  188. return Ok(index); // 返回可用的主设备号
  189. }
  190. }
  191. }
  192. // 寻找主设备号在384~511的设备
  193. for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
  194. if let Some(blockdevss) = blockdevs.0.get(Self::major_to_index(index)) {
  195. let mut flag = true;
  196. for item in blockdevss {
  197. if item.device_number().major() == index {
  198. flag = false;
  199. break;
  200. }
  201. }
  202. if flag {
  203. // 如果数组中不存在主设备号等于index的设备
  204. return Ok(index); // 返回可用的主设备号
  205. }
  206. }
  207. }
  208. return Err(SystemError::EBUSY);
  209. }
  210. /// @brief: 注册设备号,该函数需要指定主设备号
  211. /// @parameter: from: 主设备号
  212. /// count: 次设备号数量
  213. /// name: 字符设备名
  214. /// @return: 如果注册成功,返回设备号,否则,返回错误码
  215. #[allow(dead_code)]
  216. pub fn register_blockdev_region(
  217. from: DeviceNumber,
  218. count: usize,
  219. name: &'static str,
  220. ) -> Result<DeviceNumber, SystemError> {
  221. Self::__register_blockdev_region(from, count, name)
  222. }
  223. /// @brief: 注册设备号,该函数自动分配主设备号
  224. /// @parameter: baseminor: 主设备号
  225. /// count: 次设备号数量
  226. /// name: 字符设备名
  227. /// @return: 如果注册成功,返回,否则,返回false
  228. #[allow(dead_code)]
  229. pub fn alloc_blockdev_region(
  230. baseminor: usize,
  231. count: usize,
  232. name: &'static str,
  233. ) -> Result<DeviceNumber, SystemError> {
  234. Self::__register_blockdev_region(mkdev(0, baseminor), count, name)
  235. }
  236. /// @brief: 注册设备号
  237. /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
  238. /// minorct: 次设备号数量
  239. /// name: 字符设备名
  240. /// @return: 如果注册成功,返回设备号,否则,返回错误码
  241. fn __register_blockdev_region(
  242. device_number: DeviceNumber,
  243. minorct: usize,
  244. name: &'static str,
  245. ) -> Result<DeviceNumber, SystemError> {
  246. let mut major = device_number.major();
  247. let baseminor = device_number.minor();
  248. if major >= DEV_MAJOR_MAX {
  249. kerror!(
  250. "DEV {} major requested {} is greater than the maximum {}\n",
  251. name,
  252. major,
  253. DEV_MAJOR_MAX - 1
  254. );
  255. }
  256. if minorct > MINOR_MASK + 1 - baseminor {
  257. kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
  258. name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
  259. }
  260. let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
  261. if major == 0 {
  262. // 如果主设备号为0,则自动分配主设备号
  263. major = Self::find_dynamic_major().expect("Find synamic major error.\n");
  264. }
  265. if let Some(items) = BLOCKDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
  266. let mut insert_index: usize = 0;
  267. for (index, item) in items.iter().enumerate() {
  268. insert_index = index;
  269. match item.device_number().major().cmp(&major) {
  270. Ordering::Less => continue,
  271. Ordering::Greater => {
  272. break; // 大于则向后插入
  273. }
  274. Ordering::Equal => {
  275. if item.device_number().minor() + item.minorct() <= baseminor {
  276. continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
  277. }
  278. if item.base_minor() >= baseminor + minorct {
  279. break; // 在此处插入
  280. }
  281. return Err(SystemError::EBUSY); // 存在重合的次设备号
  282. }
  283. }
  284. }
  285. items.insert(insert_index, blockdev);
  286. }
  287. return Ok(mkdev(major, baseminor));
  288. }
  289. /// @brief: 注销设备号
  290. /// @parameter: major: 主设备号,如果为0,动态分配
  291. /// baseminor: 起始次设备号
  292. /// minorct: 次设备号数量
  293. /// @return: 如果注销成功,返回(),否则,返回错误码
  294. fn __unregister_blockdev_region(
  295. device_number: DeviceNumber,
  296. minorct: usize,
  297. ) -> Result<(), SystemError> {
  298. if let Some(items) = BLOCKDEVS
  299. .0
  300. .lock()
  301. .0
  302. .get_mut(Self::major_to_index(device_number.major()))
  303. {
  304. for (index, item) in items.iter().enumerate() {
  305. if item.device_number() == device_number && item.minorct() == minorct {
  306. // 设备号和数量都相等
  307. items.remove(index);
  308. return Ok(());
  309. }
  310. }
  311. }
  312. return Err(SystemError::EBUSY);
  313. }
  314. /// @brief: 块设备注册
  315. /// @parameter: cdev: 字符设备实例
  316. /// dev_t: 字符设备号
  317. /// range: 次设备号范围
  318. /// @return: none
  319. #[allow(dead_code)]
  320. pub fn bdev_add(bdev: Arc<dyn BlockDevice>, id_table: IdTable) {
  321. if Into::<usize>::into(id_table.device_number()) == 0 {
  322. kerror!("Device number can't be 0!\n");
  323. }
  324. DEVICE_MANAGER.add_device(id_table, bdev.device())
  325. }
  326. /// @brief: block设备注销
  327. /// @parameter: dev_t: 字符设备号
  328. /// range: 次设备号范围
  329. /// @return: none
  330. #[allow(dead_code)]
  331. pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {}
  332. }
  333. /// @brief 字符设备框架函数集
  334. pub struct CharDevOps;
  335. impl CharDevOps {
  336. /// @brief: 主设备号转下标
  337. /// @parameter: major: 主设备号
  338. /// @return: 返回下标
  339. #[allow(dead_code)]
  340. fn major_to_index(major: usize) -> usize {
  341. return major % DEV_MAJOR_HASH_SIZE;
  342. }
  343. /// @brief: 动态获取主设备号
  344. /// @parameter: None
  345. /// @return: 如果成功,返回主设备号,否则,返回错误码
  346. #[allow(dead_code)]
  347. fn find_dynamic_major() -> Result<usize, SystemError> {
  348. let chardevs = CHARDEVS.0.lock();
  349. // 寻找主设备号为234~255的设备
  350. for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
  351. if let Some(item) = chardevs.0.get(index) {
  352. if item.is_empty() {
  353. return Ok(index); // 返回可用的主设备号
  354. }
  355. }
  356. }
  357. // 寻找主设备号在384~511的设备
  358. for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
  359. if let Some(chardevss) = chardevs.0.get(Self::major_to_index(index)) {
  360. let mut flag = true;
  361. for item in chardevss {
  362. if item.device_number().major() == index {
  363. flag = false;
  364. break;
  365. }
  366. }
  367. if flag {
  368. // 如果数组中不存在主设备号等于index的设备
  369. return Ok(index); // 返回可用的主设备号
  370. }
  371. }
  372. }
  373. return Err(SystemError::EBUSY);
  374. }
  375. /// @brief: 注册设备号,该函数需要指定主设备号
  376. /// @parameter: from: 主设备号
  377. /// count: 次设备号数量
  378. /// name: 字符设备名
  379. /// @return: 如果注册成功,返回设备号,否则,返回错误码
  380. #[allow(dead_code)]
  381. pub fn register_chardev_region(
  382. from: DeviceNumber,
  383. count: usize,
  384. name: &'static str,
  385. ) -> Result<DeviceNumber, SystemError> {
  386. Self::__register_chardev_region(from, count, name)
  387. }
  388. /// @brief: 注册设备号,该函数自动分配主设备号
  389. /// @parameter: baseminor: 次设备号
  390. /// count: 次设备号数量
  391. /// name: 字符设备名
  392. /// @return: 如果注册成功,返回,否则,返回false
  393. #[allow(dead_code)]
  394. pub fn alloc_chardev_region(
  395. baseminor: usize,
  396. count: usize,
  397. name: &'static str,
  398. ) -> Result<DeviceNumber, SystemError> {
  399. Self::__register_chardev_region(mkdev(0, baseminor), count, name)
  400. }
  401. /// @brief: 注册设备号
  402. /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
  403. /// minorct: 次设备号数量
  404. /// name: 字符设备名
  405. /// @return: 如果注册成功,返回设备号,否则,返回错误码
  406. fn __register_chardev_region(
  407. device_number: DeviceNumber,
  408. minorct: usize,
  409. name: &'static str,
  410. ) -> Result<DeviceNumber, SystemError> {
  411. let mut major = device_number.major();
  412. let baseminor = device_number.minor();
  413. if major >= DEV_MAJOR_MAX {
  414. kerror!(
  415. "DEV {} major requested {} is greater than the maximum {}\n",
  416. name,
  417. major,
  418. DEV_MAJOR_MAX - 1
  419. );
  420. }
  421. if minorct > MINOR_MASK + 1 - baseminor {
  422. kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
  423. name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
  424. }
  425. let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
  426. if major == 0 {
  427. // 如果主设备号为0,则自动分配主设备号
  428. major = Self::find_dynamic_major().expect("Find synamic major error.\n");
  429. }
  430. if let Some(items) = CHARDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
  431. let mut insert_index: usize = 0;
  432. for (index, item) in items.iter().enumerate() {
  433. insert_index = index;
  434. match item.device_number().major().cmp(&major) {
  435. Ordering::Less => continue,
  436. Ordering::Greater => {
  437. break; // 大于则向后插入
  438. }
  439. Ordering::Equal => {
  440. if item.device_number().minor() + item.minorct() <= baseminor {
  441. continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
  442. }
  443. if item.base_minor() >= baseminor + minorct {
  444. break; // 在此处插入
  445. }
  446. return Err(SystemError::EBUSY); // 存在重合的次设备号
  447. }
  448. }
  449. }
  450. items.insert(insert_index, chardev);
  451. }
  452. return Ok(mkdev(major, baseminor));
  453. }
  454. /// @brief: 注销设备号
  455. /// @parameter: major: 主设备号,如果为0,动态分配
  456. /// baseminor: 起始次设备号
  457. /// minorct: 次设备号数量
  458. /// @return: 如果注销成功,返回(),否则,返回错误码
  459. fn __unregister_chardev_region(
  460. device_number: DeviceNumber,
  461. minorct: usize,
  462. ) -> Result<(), SystemError> {
  463. if let Some(items) = CHARDEVS
  464. .0
  465. .lock()
  466. .0
  467. .get_mut(Self::major_to_index(device_number.major()))
  468. {
  469. for (index, item) in items.iter().enumerate() {
  470. if item.device_number() == device_number && item.minorct() == minorct {
  471. // 设备号和数量都相等
  472. items.remove(index);
  473. return Ok(());
  474. }
  475. }
  476. }
  477. return Err(SystemError::EBUSY);
  478. }
  479. /// @brief: 字符设备注册
  480. /// @parameter: cdev: 字符设备实例
  481. /// dev_t: 字符设备号
  482. /// range: 次设备号范围
  483. /// @return: none
  484. #[allow(dead_code)]
  485. pub fn cdev_add(cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize) {
  486. if Into::<usize>::into(id_table.device_number()) == 0 {
  487. kerror!("Device number can't be 0!\n");
  488. }
  489. DEVICE_MANAGER.add_device(id_table.clone(), cdev.clone());
  490. kobj_map(
  491. DEVMAP.clone(),
  492. id_table.device_number(),
  493. range,
  494. cdev.clone(),
  495. )
  496. }
  497. /// @brief: 字符设备注销
  498. /// @parameter: dev_t: 字符设备号
  499. /// range: 次设备号范围
  500. /// @return: none
  501. #[allow(dead_code)]
  502. pub fn cdev_del(id_table: IdTable, range: usize) {
  503. DEVICE_MANAGER.remove_device(&id_table);
  504. kobj_unmap(DEVMAP.clone(), id_table.device_number(), range);
  505. }
  506. }