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