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