tty_device.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. use alloc::{
  2. string::{String, ToString},
  3. sync::{Arc, Weak},
  4. };
  5. use system_error::SystemError;
  6. use unified_init::macros::unified_init;
  7. use crate::{
  8. arch::ipc::signal::Signal,
  9. driver::{
  10. base::{
  11. char::CharDevice,
  12. class::Class,
  13. device::{
  14. bus::Bus,
  15. device_number::{DeviceNumber, Major},
  16. device_register,
  17. driver::Driver,
  18. Device, DeviceKObjType, DeviceType, IdTable,
  19. },
  20. kobject::{KObject, LockedKObjectState},
  21. kset::KSet,
  22. },
  23. serial::serial_init,
  24. },
  25. filesystem::{
  26. devfs::{devfs_register, DevFS, DeviceINode},
  27. kernfs::KernFSInode,
  28. vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
  29. },
  30. init::initcall::INITCALL_DEVICE,
  31. libs::{
  32. rwlock::{RwLock, RwLockWriteGuard},
  33. spinlock::SpinLockGuard,
  34. },
  35. mm::VirtAddr,
  36. net::event_poll::{EPollItem, EventPoll},
  37. process::ProcessManager,
  38. syscall::user_access::{UserBufferReader, UserBufferWriter},
  39. };
  40. use super::{
  41. kthread::tty_flush_thread_init,
  42. pty::unix98pty::ptmx_open,
  43. sysfs::sys_class_tty_instance,
  44. termios::WindowSize,
  45. tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
  46. tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
  47. tty_job_control::TtyJobCtrlManager,
  48. virtual_terminal::vty_init,
  49. };
  50. #[derive(Debug)]
  51. pub struct InnerTtyDevice {
  52. /// 当前设备所述的kset
  53. kset: Option<Arc<KSet>>,
  54. parent_kobj: Option<Weak<dyn KObject>>,
  55. /// 当前设备所述的总线
  56. bus: Option<Weak<dyn Bus>>,
  57. inode: Option<Arc<KernFSInode>>,
  58. driver: Option<Weak<dyn Driver>>,
  59. can_match: bool,
  60. metadata: Metadata,
  61. }
  62. impl InnerTtyDevice {
  63. pub fn new() -> Self {
  64. Self {
  65. kset: None,
  66. parent_kobj: None,
  67. bus: None,
  68. inode: None,
  69. driver: None,
  70. can_match: false,
  71. metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)),
  72. }
  73. }
  74. pub fn metadata_mut(&mut self) -> &mut Metadata {
  75. &mut self.metadata
  76. }
  77. }
  78. #[derive(Debug, PartialEq)]
  79. pub enum TtyType {
  80. Tty,
  81. Pty(PtyType),
  82. }
  83. #[derive(Debug, PartialEq)]
  84. pub enum PtyType {
  85. Ptm,
  86. Pts,
  87. }
  88. #[derive(Debug)]
  89. #[cast_to([sync] Device)]
  90. pub struct TtyDevice {
  91. name: String,
  92. id_table: IdTable,
  93. tty_type: TtyType,
  94. inner: RwLock<InnerTtyDevice>,
  95. kobj_state: LockedKObjectState,
  96. /// TTY所属的文件系统
  97. fs: RwLock<Weak<DevFS>>,
  98. }
  99. impl TtyDevice {
  100. pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> {
  101. let dev_num = id_table.device_number();
  102. let dev = TtyDevice {
  103. name,
  104. id_table,
  105. inner: RwLock::new(InnerTtyDevice::new()),
  106. kobj_state: LockedKObjectState::new(None),
  107. fs: RwLock::new(Weak::default()),
  108. tty_type,
  109. };
  110. dev.inner.write().metadata.raw_dev = dev_num;
  111. Arc::new(dev)
  112. }
  113. pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
  114. self.inner.write()
  115. }
  116. }
  117. impl IndexNode for TtyDevice {
  118. fn open(
  119. &self,
  120. mut data: SpinLockGuard<FilePrivateData>,
  121. mode: &crate::filesystem::vfs::file::FileMode,
  122. ) -> Result<(), SystemError> {
  123. if let FilePrivateData::Tty(_) = &*data {
  124. return Ok(());
  125. }
  126. if self.tty_type == TtyType::Pty(PtyType::Ptm) {
  127. return ptmx_open(data, mode);
  128. }
  129. let dev_num = self.metadata()?.raw_dev;
  130. let (index, driver) =
  131. TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
  132. let tty = TtyDriver::open_tty(index, driver)?;
  133. // 设置privdata
  134. *data = FilePrivateData::Tty(TtyFilePrivateData {
  135. tty: tty.clone(),
  136. mode: *mode,
  137. });
  138. let ret = tty.open(tty.core());
  139. if let Err(err) = ret {
  140. if err == SystemError::ENOSYS {
  141. return Err(SystemError::ENODEV);
  142. }
  143. return Err(err);
  144. }
  145. let driver = tty.core().driver();
  146. // 考虑noctty(当前tty)
  147. if !(mode.contains(FileMode::O_NOCTTY) && dev_num == DeviceNumber::new(Major::TTY_MAJOR, 0)
  148. || dev_num == DeviceNumber::new(Major::TTYAUX_MAJOR, 1)
  149. || (driver.tty_driver_type() == TtyDriverType::Pty
  150. && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
  151. {
  152. let pcb = ProcessManager::current_pcb();
  153. let pcb_tty = pcb.sig_info_irqsave().tty();
  154. if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
  155. TtyJobCtrlManager::proc_set_tty(tty);
  156. }
  157. }
  158. Ok(())
  159. }
  160. fn read_at(
  161. &self,
  162. _offset: usize,
  163. len: usize,
  164. buf: &mut [u8],
  165. data: SpinLockGuard<FilePrivateData>,
  166. ) -> Result<usize, system_error::SystemError> {
  167. let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
  168. (tty_priv.tty(), tty_priv.mode)
  169. } else {
  170. return Err(SystemError::EIO);
  171. };
  172. drop(data);
  173. let ld = tty.ldisc();
  174. let mut offset = 0;
  175. let mut cookie = false;
  176. loop {
  177. let mut size = if len > buf.len() { buf.len() } else { len };
  178. size = ld.read(tty.clone(), buf, size, &mut cookie, offset, mode)?;
  179. // 没有更多数据
  180. if size == 0 {
  181. break;
  182. }
  183. offset += size;
  184. // 缓冲区写满
  185. if offset >= len {
  186. break;
  187. }
  188. // 没有更多数据
  189. if !cookie {
  190. break;
  191. }
  192. }
  193. return Ok(offset);
  194. }
  195. fn write_at(
  196. &self,
  197. _offset: usize,
  198. len: usize,
  199. buf: &[u8],
  200. data: SpinLockGuard<FilePrivateData>,
  201. ) -> Result<usize, system_error::SystemError> {
  202. let mut count = len;
  203. let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
  204. (tty_priv.tty(), tty_priv.mode)
  205. } else {
  206. return Err(SystemError::EIO);
  207. };
  208. drop(data);
  209. let ld = tty.ldisc();
  210. let core = tty.core();
  211. let mut chunk = 2048;
  212. if core.flags().contains(TtyFlag::NO_WRITE_SPLIT) {
  213. chunk = 65536;
  214. }
  215. chunk = chunk.min(count);
  216. let pcb = ProcessManager::current_pcb();
  217. let mut written = 0;
  218. loop {
  219. // 至少需要写多少
  220. let size = chunk.min(count);
  221. // 将数据从buf拷贝到writebuf
  222. let ret = ld.write(tty.clone(), &buf[written..], size, mode)?;
  223. written += ret;
  224. count -= ret;
  225. if count == 0 {
  226. break;
  227. }
  228. if pcb.sig_info_irqsave().sig_pending().has_pending() {
  229. return Err(SystemError::ERESTARTSYS);
  230. }
  231. }
  232. if written > 0 {
  233. // todo: 更新时间
  234. }
  235. Ok(written)
  236. }
  237. fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
  238. todo!()
  239. }
  240. fn as_any_ref(&self) -> &dyn core::any::Any {
  241. self
  242. }
  243. fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
  244. todo!()
  245. }
  246. fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
  247. Ok(self.inner.read().metadata.clone())
  248. }
  249. fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
  250. let mut guard = self.inner_write();
  251. guard.metadata = metadata.clone();
  252. Ok(())
  253. }
  254. fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
  255. let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
  256. (tty_priv.tty(), tty_priv.mode)
  257. } else {
  258. return Err(SystemError::EIO);
  259. };
  260. drop(data);
  261. tty.close(tty.clone())
  262. }
  263. fn resize(&self, _len: usize) -> Result<(), SystemError> {
  264. Ok(())
  265. }
  266. fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
  267. let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
  268. (tty_priv.tty(), tty_priv.mode)
  269. } else {
  270. return Err(SystemError::EIO);
  271. };
  272. match cmd {
  273. TtyIoctlCmd::TIOCSETD
  274. | TtyIoctlCmd::TIOCSBRK
  275. | TtyIoctlCmd::TIOCCBRK
  276. | TtyIoctlCmd::TCSBRK
  277. | TtyIoctlCmd::TCSBRKP => {
  278. TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
  279. if cmd != TtyIoctlCmd::TIOCCBRK {
  280. todo!()
  281. }
  282. }
  283. EventPoll::ADD_EPOLLITEM => {
  284. let _ = UserBufferReader::new(
  285. arg as *const Arc<EPollItem>,
  286. core::mem::size_of::<Arc<EPollItem>>(),
  287. false,
  288. )?;
  289. let epitem = unsafe { &*(arg as *const Arc<EPollItem>) };
  290. let core = tty.core();
  291. core.add_epitem(epitem.clone());
  292. return Ok(0);
  293. }
  294. _ => {}
  295. }
  296. match cmd {
  297. TtyIoctlCmd::TIOCGWINSZ => {
  298. let core = tty.core();
  299. let winsize = *core.window_size();
  300. let mut user_writer = UserBufferWriter::new(
  301. VirtAddr::new(arg).as_ptr::<WindowSize>(),
  302. core::mem::size_of::<WindowSize>(),
  303. true,
  304. )?;
  305. let err = user_writer.copy_one_to_user(&winsize, 0);
  306. if err.is_err() {
  307. return Err(SystemError::EFAULT);
  308. }
  309. return Ok(0);
  310. }
  311. TtyIoctlCmd::TIOCSWINSZ => {
  312. let reader = UserBufferReader::new(
  313. arg as *const (),
  314. core::mem::size_of::<WindowSize>(),
  315. true,
  316. )?;
  317. let user_winsize = reader.read_one_from_user::<WindowSize>(0)?;
  318. let ret = tty.resize(tty.clone(), *user_winsize);
  319. if ret != Err(SystemError::ENOSYS) {
  320. return ret.map(|_| 0);
  321. } else {
  322. return tty.tty_do_resize(*user_winsize).map(|_| 0);
  323. }
  324. }
  325. _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
  326. Ok(_) => {
  327. return Ok(0);
  328. }
  329. Err(e) => {
  330. if e != SystemError::ENOIOCTLCMD {
  331. return Err(e);
  332. }
  333. }
  334. },
  335. }
  336. match tty.ioctl(tty.clone(), cmd, arg) {
  337. Ok(_) => {
  338. return Ok(0);
  339. }
  340. Err(e) => {
  341. if e != SystemError::ENOIOCTLCMD {
  342. return Err(e);
  343. }
  344. }
  345. }
  346. tty.ldisc().ioctl(tty, cmd, arg)?;
  347. Ok(0)
  348. }
  349. fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
  350. let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
  351. (tty_priv.tty.clone(), tty_priv.mode)
  352. } else {
  353. return Err(SystemError::EIO);
  354. };
  355. tty.ldisc().poll(tty)
  356. }
  357. }
  358. impl DeviceINode for TtyDevice {
  359. fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) {
  360. *self.fs.write() = fs;
  361. }
  362. }
  363. impl KObject for TtyDevice {
  364. fn as_any_ref(&self) -> &dyn core::any::Any {
  365. self
  366. }
  367. fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
  368. self.inner.write().inode = inode;
  369. }
  370. fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
  371. self.inner.read().inode.clone()
  372. }
  373. fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
  374. self.inner.read().parent_kobj.clone()
  375. }
  376. fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
  377. self.inner.write().parent_kobj = parent
  378. }
  379. fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
  380. self.inner.read().kset.clone()
  381. }
  382. fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
  383. self.inner.write().kset = kset
  384. }
  385. fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
  386. Some(&DeviceKObjType)
  387. }
  388. fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {}
  389. fn name(&self) -> alloc::string::String {
  390. self.name.to_string()
  391. }
  392. fn set_name(&self, _name: alloc::string::String) {
  393. // self.name = name
  394. }
  395. fn kobj_state(
  396. &self,
  397. ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
  398. self.kobj_state.read()
  399. }
  400. fn kobj_state_mut(
  401. &self,
  402. ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
  403. self.kobj_state.write()
  404. }
  405. fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) {
  406. *self.kobj_state.write() = state
  407. }
  408. }
  409. impl Device for TtyDevice {
  410. fn dev_type(&self) -> crate::driver::base::device::DeviceType {
  411. DeviceType::Char
  412. }
  413. fn id_table(&self) -> crate::driver::base::device::IdTable {
  414. self.id_table.clone()
  415. }
  416. fn bus(&self) -> Option<Weak<dyn Bus>> {
  417. self.inner.read().bus.clone()
  418. }
  419. fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
  420. self.inner.write().bus = bus
  421. }
  422. fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) {
  423. // do nothing
  424. }
  425. fn class(&self) -> Option<Arc<dyn Class>> {
  426. sys_class_tty_instance()
  427. .cloned()
  428. .map(|x| x as Arc<dyn Class>)
  429. }
  430. fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> {
  431. self.inner.read().driver.clone()?.upgrade()
  432. }
  433. fn set_driver(
  434. &self,
  435. driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>,
  436. ) {
  437. self.inner.write().driver = driver
  438. }
  439. fn is_dead(&self) -> bool {
  440. false
  441. }
  442. fn can_match(&self) -> bool {
  443. self.inner.read().can_match
  444. }
  445. fn set_can_match(&self, can_match: bool) {
  446. self.inner.write().can_match = can_match
  447. }
  448. fn state_synced(&self) -> bool {
  449. true
  450. }
  451. }
  452. impl CharDevice for TtyDevice {
  453. fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> {
  454. todo!()
  455. }
  456. fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> {
  457. todo!()
  458. }
  459. fn sync(&self) -> Result<(), SystemError> {
  460. todo!()
  461. }
  462. }
  463. #[derive(Debug, Clone)]
  464. pub struct TtyFilePrivateData {
  465. pub tty: Arc<TtyCore>,
  466. pub mode: FileMode,
  467. }
  468. impl TtyFilePrivateData {
  469. pub fn tty(&self) -> Arc<TtyCore> {
  470. self.tty.clone()
  471. }
  472. }
  473. /// 初始化tty设备和console子设备
  474. #[unified_init(INITCALL_DEVICE)]
  475. #[inline(never)]
  476. pub fn tty_init() -> Result<(), SystemError> {
  477. let tty = TtyDevice::new(
  478. "tty0".to_string(),
  479. IdTable::new(
  480. String::from("tty0"),
  481. Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
  482. ),
  483. TtyType::Tty,
  484. );
  485. let console = TtyDevice::new(
  486. "console".to_string(),
  487. IdTable::new(
  488. String::from("console"),
  489. Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
  490. ),
  491. TtyType::Tty,
  492. );
  493. // 注册tty设备
  494. // CharDevOps::cdev_add(
  495. // tty.clone() as Arc<dyn CharDevice>,
  496. // IdTable::new(
  497. // String::from("tty0"),
  498. // Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 0)),
  499. // ),
  500. // 1,
  501. // )?;
  502. // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 0), 1, "/dev/tty")?;
  503. // 注册console设备
  504. // CharDevOps::cdev_add(
  505. // console.clone() as Arc<dyn CharDevice>,
  506. // IdTable::new(
  507. // String::from("console"),
  508. // Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
  509. // ),
  510. // 1,
  511. // )?;
  512. // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 1), 1, "/dev/tty")?;
  513. // 将这两个设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面
  514. device_register(tty.clone())?;
  515. device_register(console.clone())?;
  516. devfs_register(&tty.name.clone(), tty)?;
  517. devfs_register(&console.name.clone(), console)?;
  518. serial_init()?;
  519. tty_flush_thread_init();
  520. return vty_init();
  521. }