os/vfs/impls/
char_dev_file.rs

1use crate::device::Driver;
2use crate::sync::SpinLock;
3use crate::uapi::ioctl::Termios;
4use crate::vfs::dev::{major, minor};
5use crate::vfs::devno::{chrdev_major, get_chrdev_driver, misc_minor};
6use crate::vfs::{Dentry, File, FsError, Inode, InodeMetadata, OpenFlags, SeekWhence};
7use alloc::sync::Arc;
8
9/// 字符设备文件
10pub struct CharDeviceFile {
11    /// 关联的 dentry
12    pub dentry: Arc<Dentry>,
13
14    /// 关联的 inode
15    pub inode: Arc<dyn Inode>,
16
17    /// 设备号
18    dev: u64,
19
20    /// 设备驱动(缓存)
21    driver: Option<Arc<dyn Driver>>,
22
23    /// 打开标志位
24    pub flags: OpenFlags,
25
26    /// 偏移量(某些字符设备可能需要)
27    offset: SpinLock<usize>,
28
29    /// 终端属性(用于 TTY 设备)
30    termios: SpinLock<Termios>,
31
32    /// 终端窗口大小(用于 TTY 设备)
33    winsize: SpinLock<crate::uapi::ioctl::WinSize>,
34}
35
36impl CharDeviceFile {
37    /// 创建新的字符设备文件
38    ///
39    /// # 参数
40    /// - `dentry`: 设备文件的 dentry
41    /// - `flags`: 打开标志
42    ///
43    /// # 返回
44    /// - `Ok(CharDeviceFile)`: 成功
45    /// - `Err(FsError::NoDevice)`: 找不到对应的驱动
46    pub fn new(dentry: Arc<Dentry>, flags: OpenFlags) -> Result<Self, FsError> {
47        let inode = dentry.inode.clone();
48        let metadata = inode.metadata()?;
49        let dev = metadata.rdev;
50
51        // 通过硬编码规则查找驱动
52        // 内存设备(major=1)会返回 None,在 read/write 中直接处理
53        let driver = get_chrdev_driver(dev);
54
55        // 检查设备是否支持
56        let maj = major(dev);
57        if driver.is_none() && maj != chrdev_major::MEM {
58            // 既不是内存设备,也找不到驱动
59            return Err(FsError::NoDevice);
60        }
61
62        Ok(Self {
63            dentry,
64            inode,
65            dev,
66            driver,
67            flags,
68            offset: SpinLock::new(0),
69            termios: SpinLock::new(Termios::default()),
70            winsize: SpinLock::new(crate::uapi::ioctl::WinSize {
71                ws_row: 24,
72                ws_col: 80,
73                ws_xpixel: 0,
74                ws_ypixel: 0,
75            }),
76        })
77    }
78
79    /// 处理内存设备的读操作
80    fn mem_device_read(&self, buf: &mut [u8]) -> Result<usize, FsError> {
81        let min = minor(self.dev);
82        match min {
83            3 => {
84                // /dev/null: 总是返回 0
85                Ok(0)
86            }
87            5 => {
88                // /dev/zero: 填充零
89                buf.fill(0);
90                Ok(buf.len())
91            }
92            8 | 9 => {
93                // /dev/random, /dev/urandom: 简单实现(使用时间戳)
94                use crate::arch::timer::get_ticks;
95                let mut seed = get_ticks() as u32;
96                for byte in buf.iter_mut() {
97                    // 简单的 LCG 随机数生成器
98                    seed = seed.wrapping_mul(1103515245).wrapping_add(12345);
99                    *byte = (seed >> 16) as u8;
100                }
101                Ok(buf.len())
102            }
103            _ => Err(FsError::NoDevice),
104        }
105    }
106
107    /// 处理内存设备的写操作
108    fn mem_device_write(&self, buf: &[u8]) -> Result<usize, FsError> {
109        let min = minor(self.dev);
110        match min {
111            3 | 5 => {
112                // /dev/null, /dev/zero: 丢弃所有数据
113                Ok(buf.len())
114            }
115            _ => Err(FsError::NoDevice),
116        }
117    }
118}
119
120impl File for CharDeviceFile {
121    fn readable(&self) -> bool {
122        self.flags.readable()
123    }
124
125    fn writable(&self) -> bool {
126        self.flags.writable()
127    }
128
129    fn read(&self, buf: &mut [u8]) -> Result<usize, FsError> {
130        if !self.readable() {
131            return Err(FsError::PermissionDenied);
132        }
133
134        let maj = major(self.dev);
135
136        // 内存设备特殊处理
137        if maj == chrdev_major::MEM {
138            return self.mem_device_read(buf);
139        }
140
141        // 其他设备:委托给驱动
142        if let Some(ref driver) = self.driver {
143            if let Some(serial) = driver.as_serial() {
144                let is_nonblock = self.flags.contains(OpenFlags::O_NONBLOCK);
145
146                if is_nonblock {
147                    // 非阻塞模式:尝试读取,没有数据则返回 EAGAIN
148                    if let Some(byte) = serial.try_read() {
149                        buf[0] = byte;
150                        let mut count = 1;
151                        // 尽可能多读,但不阻塞
152                        while count < buf.len() {
153                            if let Some(b) = serial.try_read() {
154                                buf[count] = b;
155                                count += 1;
156                            } else {
157                                break;
158                            }
159                        }
160                        Ok(count)
161                    } else {
162                        Err(FsError::WouldBlock)
163                    }
164                } else {
165                    // 阻塞模式:至少读取一个字节
166                    buf[0] = serial.read();
167                    let mut count = 1;
168                    // 尝试读取更多,但不阻塞
169                    while count < buf.len() {
170                        if let Some(b) = serial.try_read() {
171                            buf[count] = b;
172                            count += 1;
173                        } else {
174                            break;
175                        }
176                    }
177                    Ok(count)
178                }
179            } else {
180                Err(FsError::NotSupported)
181            }
182        } else {
183            Err(FsError::NoDevice)
184        }
185    }
186
187    fn write(&self, buf: &[u8]) -> Result<usize, FsError> {
188        if !self.writable() {
189            return Err(FsError::PermissionDenied);
190        }
191
192        let maj = major(self.dev);
193
194        // 内存设备特殊处理
195        if maj == chrdev_major::MEM {
196            return self.mem_device_write(buf);
197        }
198
199        // 其他设备:委托给驱动
200        if let Some(ref driver) = self.driver {
201            if let Some(serial) = driver.as_serial() {
202                serial.write(buf);
203                Ok(buf.len())
204            } else {
205                Err(FsError::NotSupported)
206            }
207        } else {
208            Err(FsError::NoDevice)
209        }
210    }
211
212    fn metadata(&self) -> Result<InodeMetadata, FsError> {
213        self.inode.metadata()
214    }
215
216    fn lseek(&self, offset: isize, whence: SeekWhence) -> Result<usize, FsError> {
217        // 大多数字符设备不支持 seek
218        // 但某些设备(如 /dev/mem)可能需要
219        Err(FsError::NotSupported)
220    }
221
222    fn offset(&self) -> usize {
223        *self.offset.lock()
224    }
225
226    fn flags(&self) -> OpenFlags {
227        self.flags.clone()
228    }
229
230    fn inode(&self) -> Result<Arc<dyn Inode>, FsError> {
231        Ok(self.inode.clone())
232    }
233
234    fn dentry(&self) -> Result<Arc<Dentry>, FsError> {
235        Ok(self.dentry.clone())
236    }
237
238    fn ioctl(&self, request: u32, arg: usize) -> Result<isize, FsError> {
239        use crate::arch::trap::SumGuard;
240        use crate::uapi::errno::{EINVAL, ENOTTY};
241        use crate::uapi::ioctl::*;
242
243        let maj = major(self.dev);
244
245        // 根据设备类型分发 ioctl
246        match maj {
247            chrdev_major::CONSOLE => {
248                // 终端 ioctl
249                self.console_ioctl(request, arg)
250            }
251            chrdev_major::MISC => {
252                // MISC 设备 ioctl (包括 RTC)
253                self.misc_ioctl(request, arg)
254            }
255            _ => Err(FsError::NotSupported),
256        }
257    }
258    fn as_any(&self) -> &dyn core::any::Any {
259        self
260    }
261}
262
263impl CharDeviceFile {
264    /// 控制台设备 ioctl 处理
265    fn console_ioctl(&self, request: u32, arg: usize) -> Result<isize, FsError> {
266        use crate::arch::trap::SumGuard;
267        use crate::uapi::errno::{EINVAL, ENOTTY};
268        use crate::uapi::ioctl::*;
269
270        match request {
271            TCGETS => {
272                if arg == 0 {
273                    return Ok(-EINVAL as isize);
274                }
275
276                unsafe {
277                    let _guard = SumGuard::new();
278                    let termios_ptr = arg as *mut Termios;
279                    if termios_ptr.is_null() {
280                        return Ok(-EINVAL as isize);
281                    }
282
283                    // 清零结构体(包括 padding),避免泄露内核栈数据
284                    core::ptr::write_bytes(
285                        termios_ptr as *mut u8,
286                        0,
287                        core::mem::size_of::<Termios>(),
288                    );
289
290                    // 返回保存的 termios 设置
291                    let termios = *self.termios.lock();
292                    core::ptr::write_volatile(termios_ptr, termios);
293                }
294                Ok(0)
295            }
296
297            TCSETS | TCSETSW | TCSETSF => {
298                if arg == 0 {
299                    return Ok(-EINVAL as isize);
300                }
301
302                {
303                    let _guard = SumGuard::new();
304                    let termios_ptr = arg as *const Termios;
305                    if termios_ptr.is_null() {
306                        return Ok(-EINVAL as isize);
307                    }
308
309                    unsafe {
310                        // 读取新的 termios 设置并保存
311                        let new_termios = core::ptr::read_volatile(termios_ptr);
312                        *self.termios.lock() = new_termios;
313                    }
314                }
315                Ok(0)
316            }
317
318            TIOCGWINSZ => {
319                if arg == 0 {
320                    return Ok(-EINVAL as isize);
321                }
322
323                unsafe {
324                    let _guard = SumGuard::new();
325                    let winsize_ptr = arg as *mut crate::uapi::ioctl::WinSize;
326                    if winsize_ptr.is_null() {
327                        return Ok(-EINVAL as isize);
328                    }
329
330                    // 清零结构体(包括 padding),避免泄露内核栈数据
331                    core::ptr::write_bytes(
332                        winsize_ptr as *mut u8,
333                        0,
334                        core::mem::size_of::<crate::uapi::ioctl::WinSize>(),
335                    );
336
337                    // 返回保存的窗口大小
338                    let winsize = *self.winsize.lock();
339                    core::ptr::write_volatile(winsize_ptr, winsize);
340                }
341                Ok(0)
342            }
343
344            TIOCSWINSZ => {
345                if arg == 0 {
346                    return Ok(-EINVAL as isize);
347                }
348
349                {
350                    let _guard = SumGuard::new();
351                    let winsize_ptr = arg as *const crate::uapi::ioctl::WinSize;
352                    if winsize_ptr.is_null() {
353                        return Ok(-EINVAL as isize);
354                    }
355
356                    unsafe {
357                        // 读取新的窗口大小并保存
358                        let new_winsize = core::ptr::read_volatile(winsize_ptr);
359                        *self.winsize.lock() = new_winsize;
360                    }
361                }
362                Ok(0)
363            }
364
365            // 其他 ioctl 命令不支持
366            _ => Ok(-ENOTTY as isize),
367        }
368    }
369
370    /// MISC 设备 ioctl 处理
371    fn misc_ioctl(&self, request: u32, arg: usize) -> Result<isize, FsError> {
372        use crate::arch::trap::SumGuard;
373        use crate::uapi::errno::EINVAL;
374        use crate::uapi::ioctl::*;
375        use crate::vfs::dev::minor;
376
377        let min = minor(self.dev);
378
379        // RTC 设备 (minor=135)
380        if min == misc_minor::RTC {
381            match request {
382                RTC_RD_TIME => {
383                    if arg == 0 {
384                        return Ok(-EINVAL as isize);
385                    }
386
387                    // 通过驱动获取时间
388                    if let Some(ref driver) = self.driver {
389                        if let Some(rtc) = driver.as_rtc() {
390                            let dt = rtc.read_datetime();
391
392                            unsafe {
393                                let _guard = SumGuard::new();
394                                let rtc_time_ptr = arg as *mut RtcTime;
395                                if rtc_time_ptr.is_null() {
396                                    return Ok(-EINVAL as isize);
397                                }
398
399                                // 清零结构体
400                                core::ptr::write_bytes(
401                                    rtc_time_ptr as *mut u8,
402                                    0,
403                                    core::mem::size_of::<RtcTime>(),
404                                );
405
406                                // 填充时间结构体
407                                let rtc_time = RtcTime {
408                                    tm_sec: dt.second as i32,
409                                    tm_min: dt.minute as i32,
410                                    tm_hour: dt.hour as i32,
411                                    tm_mday: dt.day as i32,
412                                    tm_mon: (dt.month - 1) as i32, // Linux 月份是 0-based
413                                    tm_year: (dt.year - 1900) as i32,
414                                    tm_wday: 0, // 未计算
415                                    tm_yday: 0, // 未计算
416                                    tm_isdst: 0,
417                                };
418
419                                core::ptr::write_volatile(rtc_time_ptr, rtc_time);
420                            }
421                            return Ok(0);
422                        }
423                    }
424                    Err(FsError::NoDevice)
425                }
426                _ => Err(FsError::NotSupported),
427            }
428        } else {
429            Err(FsError::NotSupported)
430        }
431    }
432}