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::{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
name_ref(&self) -> &str130 pub fn name_ref(&self) -> &str {
131 &self.name
132 }
133 }
134
135 impl IndexNode for TtyDevice {
open( &self, mut data: SpinLockGuard<FilePrivateData>, mode: &crate::filesystem::vfs::file::FileMode, ) -> Result<(), SystemError>136 fn open(
137 &self,
138 mut data: SpinLockGuard<FilePrivateData>,
139 mode: &crate::filesystem::vfs::file::FileMode,
140 ) -> Result<(), SystemError> {
141 if let FilePrivateData::Tty(_) = &*data {
142 return Ok(());
143 }
144 if self.tty_type == TtyType::Pty(PtyType::Ptm) {
145 return ptmx_open(data, mode);
146 }
147 let dev_num = self.metadata()?.raw_dev;
148
149 let (index, driver) =
150 TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
151
152 let tty = driver.open_tty(Some(index))?;
153
154 // 设置privdata
155 *data = FilePrivateData::Tty(TtyFilePrivateData {
156 tty: tty.clone(),
157 mode: *mode,
158 });
159
160 let ret = tty.open(tty.core());
161 if let Err(err) = ret {
162 if err == SystemError::ENOSYS {
163 return Err(SystemError::ENODEV);
164 }
165 return Err(err);
166 }
167
168 let driver = tty.core().driver();
169 // 考虑noctty(当前tty)
170 if !(mode.contains(FileMode::O_NOCTTY) && dev_num == DeviceNumber::new(Major::TTY_MAJOR, 0)
171 || dev_num == DeviceNumber::new(Major::TTYAUX_MAJOR, 1)
172 || (driver.tty_driver_type() == TtyDriverType::Pty
173 && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
174 {
175 let pcb = ProcessManager::current_pcb();
176 let pcb_tty = pcb.sig_info_irqsave().tty();
177 if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
178 TtyJobCtrlManager::proc_set_tty(tty);
179 }
180 }
181
182 Ok(())
183 }
184
read_at( &self, _offset: usize, len: usize, buf: &mut [u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, system_error::SystemError>185 fn read_at(
186 &self,
187 _offset: usize,
188 len: usize,
189 buf: &mut [u8],
190 data: SpinLockGuard<FilePrivateData>,
191 ) -> Result<usize, system_error::SystemError> {
192 let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
193 (tty_priv.tty(), tty_priv.mode)
194 } else {
195 return Err(SystemError::EIO);
196 };
197
198 drop(data);
199
200 let ld = tty.ldisc();
201 let mut offset = 0;
202 let mut cookie = false;
203 loop {
204 let mut size = if len > buf.len() { buf.len() } else { len };
205 size = ld.read(tty.clone(), buf, size, &mut cookie, offset, mode)?;
206 // 没有更多数据
207 if size == 0 {
208 break;
209 }
210
211 offset += size;
212
213 // 缓冲区写满
214 if offset >= len {
215 break;
216 }
217
218 // 没有更多数据
219 if !cookie {
220 break;
221 }
222 }
223
224 return Ok(offset);
225 }
226
write_at( &self, _offset: usize, len: usize, buf: &[u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, system_error::SystemError>227 fn write_at(
228 &self,
229 _offset: usize,
230 len: usize,
231 buf: &[u8],
232 data: SpinLockGuard<FilePrivateData>,
233 ) -> Result<usize, system_error::SystemError> {
234 let mut count = len;
235 let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
236 (tty_priv.tty(), tty_priv.mode)
237 } else {
238 return Err(SystemError::EIO);
239 };
240 drop(data);
241 let ld = tty.ldisc();
242 let core = tty.core();
243 let mut chunk = 2048;
244 if core.flags().contains(TtyFlag::NO_WRITE_SPLIT) {
245 chunk = 65536;
246 }
247 chunk = chunk.min(count);
248
249 let pcb = ProcessManager::current_pcb();
250 let mut written = 0;
251 loop {
252 // 至少需要写多少
253 let size = chunk.min(count);
254
255 // 将数据从buf拷贝到writebuf
256
257 let ret = ld.write(tty.clone(), &buf[written..], size, mode)?;
258
259 written += ret;
260 count -= ret;
261
262 if count == 0 {
263 break;
264 }
265
266 if pcb.sig_info_irqsave().sig_pending().has_pending() {
267 return Err(SystemError::ERESTARTSYS);
268 }
269 }
270
271 if written > 0 {
272 // todo: 更新时间
273 }
274
275 Ok(written)
276 }
277
fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem>278 fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
279 todo!()
280 }
281
as_any_ref(&self) -> &dyn core::any::Any282 fn as_any_ref(&self) -> &dyn core::any::Any {
283 self
284 }
285
list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError>286 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
287 todo!()
288 }
289
metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError>290 fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
291 Ok(self.inner.read().metadata.clone())
292 }
293
set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>294 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
295 let mut guard = self.inner_write();
296 guard.metadata = metadata.clone();
297
298 Ok(())
299 }
300
close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>301 fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
302 let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
303 (tty_priv.tty(), tty_priv.mode)
304 } else {
305 return Err(SystemError::EIO);
306 };
307 drop(data);
308 tty.close(tty.clone())
309 }
310
resize(&self, _len: usize) -> Result<(), SystemError>311 fn resize(&self, _len: usize) -> Result<(), SystemError> {
312 Ok(())
313 }
314
kernel_ioctl( &self, arg: Arc<dyn KernelIoctlData>, data: &FilePrivateData, ) -> Result<usize, SystemError>315 fn kernel_ioctl(
316 &self,
317 arg: Arc<dyn KernelIoctlData>,
318 data: &FilePrivateData,
319 ) -> Result<usize, SystemError> {
320 let epitem = arg
321 .arc_any()
322 .downcast::<EPollItem>()
323 .map_err(|_| SystemError::EFAULT)?;
324
325 let _ = UserBufferReader::new(
326 &epitem as *const Arc<EPollItem>,
327 core::mem::size_of::<Arc<EPollItem>>(),
328 false,
329 )?;
330
331 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
332 (tty_priv.tty(), tty_priv.mode)
333 } else {
334 return Err(SystemError::EIO);
335 };
336
337 let core = tty.core();
338
339 core.add_epitem(epitem.clone());
340
341 return Ok(0);
342 }
343
ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError>344 fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
345 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
346 (tty_priv.tty(), tty_priv.mode)
347 } else {
348 return Err(SystemError::EIO);
349 };
350
351 match cmd {
352 TtyIoctlCmd::TIOCSETD
353 | TtyIoctlCmd::TIOCSBRK
354 | TtyIoctlCmd::TIOCCBRK
355 | TtyIoctlCmd::TCSBRK
356 | TtyIoctlCmd::TCSBRKP => {
357 TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
358 if cmd != TtyIoctlCmd::TIOCCBRK {
359 todo!()
360 }
361 }
362 _ => {}
363 }
364
365 match cmd {
366 TtyIoctlCmd::TIOCGWINSZ => {
367 let core = tty.core();
368 let winsize = *core.window_size();
369
370 let mut user_writer = UserBufferWriter::new(
371 VirtAddr::new(arg).as_ptr::<WindowSize>(),
372 core::mem::size_of::<WindowSize>(),
373 true,
374 )?;
375
376 let err = user_writer.copy_one_to_user(&winsize, 0);
377 if err.is_err() {
378 return Err(SystemError::EFAULT);
379 }
380 return Ok(0);
381 }
382 TtyIoctlCmd::TIOCSWINSZ => {
383 let reader = UserBufferReader::new(
384 arg as *const (),
385 core::mem::size_of::<WindowSize>(),
386 true,
387 )?;
388
389 let user_winsize = reader.read_one_from_user::<WindowSize>(0)?;
390
391 let ret = tty.resize(tty.clone(), *user_winsize);
392
393 if ret != Err(SystemError::ENOSYS) {
394 return ret.map(|_| 0);
395 } else {
396 return tty.tty_do_resize(*user_winsize).map(|_| 0);
397 }
398 }
399 _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
400 Ok(_) => {
401 return Ok(0);
402 }
403 Err(e) => {
404 if e != SystemError::ENOIOCTLCMD {
405 return Err(e);
406 }
407 }
408 },
409 }
410
411 match tty.ioctl(tty.clone(), cmd, arg) {
412 Ok(_) => {
413 return Ok(0);
414 }
415 Err(e) => {
416 if e != SystemError::ENOIOCTLCMD {
417 return Err(e);
418 }
419 }
420 }
421 tty.ldisc().ioctl(tty, cmd, arg)?;
422
423 Ok(0)
424 }
425
poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError>426 fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
427 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
428 (tty_priv.tty.clone(), tty_priv.mode)
429 } else {
430 return Err(SystemError::EIO);
431 };
432
433 tty.ldisc().poll(tty)
434 }
435 }
436
437 impl DeviceINode for TtyDevice {
set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>)438 fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) {
439 *self.fs.write() = fs;
440 }
441 }
442
443 impl KObject for TtyDevice {
as_any_ref(&self) -> &dyn core::any::Any444 fn as_any_ref(&self) -> &dyn core::any::Any {
445 self
446 }
447
set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>)448 fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
449 self.inner.write().inode = inode;
450 }
451
inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>>452 fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
453 self.inner.read().inode.clone()
454 }
455
parent(&self) -> Option<alloc::sync::Weak<dyn KObject>>456 fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
457 self.inner.read().parent_kobj.clone()
458 }
459
set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>)460 fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
461 self.inner.write().parent_kobj = parent
462 }
463
kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>>464 fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
465 self.inner.read().kset.clone()
466 }
467
set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>)468 fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
469 self.inner.write().kset = kset
470 }
471
kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType>472 fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
473 Some(&DeviceKObjType)
474 }
475
set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>)476 fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {}
477
name(&self) -> alloc::string::String478 fn name(&self) -> alloc::string::String {
479 self.name.to_string()
480 }
481
set_name(&self, _name: alloc::string::String)482 fn set_name(&self, _name: alloc::string::String) {
483 // self.name = name
484 }
485
kobj_state( &self, ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState>486 fn kobj_state(
487 &self,
488 ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
489 self.kobj_state.read()
490 }
491
kobj_state_mut( &self, ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState>492 fn kobj_state_mut(
493 &self,
494 ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
495 self.kobj_state.write()
496 }
497
set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState)498 fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) {
499 *self.kobj_state.write() = state
500 }
501 }
502
503 impl Device for TtyDevice {
dev_type(&self) -> crate::driver::base::device::DeviceType504 fn dev_type(&self) -> crate::driver::base::device::DeviceType {
505 DeviceType::Char
506 }
507
id_table(&self) -> crate::driver::base::device::IdTable508 fn id_table(&self) -> crate::driver::base::device::IdTable {
509 self.id_table.clone()
510 }
511
bus(&self) -> Option<Weak<dyn Bus>>512 fn bus(&self) -> Option<Weak<dyn Bus>> {
513 self.inner.read().bus.clone()
514 }
515
set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>)516 fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
517 self.inner.write().bus = bus
518 }
519
set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>)520 fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) {
521 // do nothing
522 }
523
class(&self) -> Option<Arc<dyn Class>>524 fn class(&self) -> Option<Arc<dyn Class>> {
525 sys_class_tty_instance()
526 .cloned()
527 .map(|x| x as Arc<dyn Class>)
528 }
529
driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>>530 fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> {
531 self.inner.read().driver.clone()?.upgrade()
532 }
533
set_driver( &self, driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>, )534 fn set_driver(
535 &self,
536 driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>,
537 ) {
538 self.inner.write().driver = driver
539 }
540
is_dead(&self) -> bool541 fn is_dead(&self) -> bool {
542 false
543 }
544
can_match(&self) -> bool545 fn can_match(&self) -> bool {
546 self.inner.read().can_match
547 }
548
set_can_match(&self, can_match: bool)549 fn set_can_match(&self, can_match: bool) {
550 self.inner.write().can_match = can_match
551 }
552
state_synced(&self) -> bool553 fn state_synced(&self) -> bool {
554 true
555 }
556
dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>557 fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>> {
558 None
559 }
560
set_dev_parent( &self, _dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>, )561 fn set_dev_parent(
562 &self,
563 _dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>,
564 ) {
565 todo!()
566 }
567 }
568
569 impl CharDevice for TtyDevice {
read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError>570 fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> {
571 todo!()
572 }
573
write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError>574 fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> {
575 todo!()
576 }
577
sync(&self) -> Result<(), SystemError>578 fn sync(&self) -> Result<(), SystemError> {
579 todo!()
580 }
581 }
582
583 #[derive(Debug, Clone)]
584 pub struct TtyFilePrivateData {
585 pub tty: Arc<TtyCore>,
586 pub mode: FileMode,
587 }
588
589 impl TtyFilePrivateData {
tty(&self) -> Arc<TtyCore>590 pub fn tty(&self) -> Arc<TtyCore> {
591 self.tty.clone()
592 }
593 }
594
595 /// 初始化tty设备和console子设备
596 #[unified_init(INITCALL_DEVICE)]
597 #[inline(never)]
tty_init() -> Result<(), SystemError>598 pub fn tty_init() -> Result<(), SystemError> {
599 let console = TtyDevice::new(
600 "console".to_string(),
601 IdTable::new(
602 String::from("console"),
603 Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
604 ),
605 TtyType::Tty,
606 );
607
608 // 将设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面
609 device_register(console.clone())?;
610 devfs_register(&console.name.clone(), console)?;
611
612 serial_init()?;
613
614 tty_flush_thread_init();
615 return vty_init();
616 }
617