os/fs/
mod.rs

1//! # 文件系统模块 (FS)
2//!
3//! 本模块提供了多种具体的文件系统实现,通过实现VFS的`FileSystem`和`Inode` trait与虚拟文件系统层集成。
4//!
5//! ## 支持的文件系统
6//!
7//! - **[tmpfs](tmpfs)**: 临时文件系统(纯内存)
8//!   - 高性能,所有数据存储在内存中
9//!   - 支持配置最大容量限制
10//!   - 适用于`/tmp`、缓存等临时存储
11//!
12//! - **[procfs](proc)**: 进程信息伪文件系统
13//!   - 动态生成进程和系统信息
14//!   - 标准Linux `/proc` 接口
15//!   - 只读,使用Generator模式
16//!
17//! - **[sysfs](sysfs)**: 系统设备伪文件系统
18//!   - 导出设备树和属性
19//!   - 标准Linux `/sys` 接口
20//!   - 使用Builder模式构建设备树
21//!
22//! - **[ext4]**: Linux Ext4文件系统
23//!   - 持久化存储支持
24//!   - 通过块设备访问
25//!   - 支持完整的读写操作
26//!
27//! - **[simple_fs]**: 简单测试文件系统
28//!   - 编译时嵌入镜像
29//!   - 快速启动,用于测试
30//!   - 只读,预加载用户程序
31//!
32//! ## 文件系统初始化流程
33//!
34//! ```no_run
35//! # use crate::fs::*;
36//! # use crate::vfs::*;
37//! // 1. 挂载根文件系统(Ext4或SimpleFS)
38//! init_ext4_from_block_device()
39//!     .or_else(|_| init_simple_fs())?;
40//!
41//! // 2. 创建必要的目录
42//! let root = vfs::get_root_dentry()?;
43//! root.inode.mkdir("dev", FileMode::S_IFDIR | FileMode::S_IRWXU)?;
44//! root.inode.mkdir("proc", FileMode::S_IFDIR | FileMode::S_IRWXU)?;
45//! root.inode.mkdir("sys", FileMode::S_IFDIR | FileMode::S_IRWXU)?;
46//! root.inode.mkdir("tmp", FileMode::S_IFDIR | FileMode::S_IRWXU)?;
47//!
48//! // 3. 挂载伪文件系统
49//! init_procfs()?;
50//! init_sysfs()?;
51//!
52//! // 4. 挂载tmpfs
53//! mount_tmpfs("/tmp", 64)?;  // 64MB
54//!
55//! // 5. 初始化设备文件
56//! init_dev()?;
57//! # Ok::<(), FsError>(())
58//! ```
59//!
60//! ## 文档参考
61//!
62//! 详细文档请参阅: `document/fs/README.md`
63//!
64//! ## 架构说明
65//!
66//! FS模块位于VFS层之下,作为VFS的具体实现:
67//!
68//! ```text
69//! 系统调用层 (sys_open, sys_read, ...)
70//!      ↓
71//! VFS抽象层 (File, Inode, FileSystem traits)
72//!      ↓
73//! FS实现层 (TmpFs, ProcFS, Ext4, ...) ← 本模块
74//!      ↓
75//! 设备层 (BlockDriver, CharDriver)
76//! ```
77pub mod ext4;
78pub mod proc;
79pub mod simple_fs;
80pub mod smfs;
81pub mod sysfs;
82pub mod tmpfs;
83
84use alloc::string::String;
85use alloc::sync::Arc;
86
87use crate::device::BLK_DRIVERS;
88use crate::device::RamDisk;
89use crate::fs::ext4::Ext4FileSystem;
90use crate::fs::simple_fs::SimpleFs;
91use crate::fs::tmpfs::TmpFs;
92// use crate::fs::smfs::SimpleMemoryFileSystem;
93use crate::pr_info;
94use crate::vfs::dev::makedev;
95use crate::vfs::devno::{blkdev_major, chrdev_major};
96use crate::vfs::{FileMode, FsError, MOUNT_TABLE, MountFlags, vfs_lookup};
97
98// pub fn init_ext4() -> Result<(), crate::vfs::FsError> {
99//     unimplemented!()
100// }
101
102// lazy_static! {
103//     /// 根文件系统实例
104//     /// 在系统初始化时创建
105//     /// 只读文件系统,驻留在内存中,不用担心同步问题
106//     pub static ref ROOT_FS: SimpleMemoryFileSystem = SimpleMemoryFileSystem::init();
107// }
108
109/// 嵌入的 simple_fs 镜像
110/// 由 build.rs 在编译时生成
111static SIMPLE_FS_IMAGE: &[u8] = include_bytes!(env!("SIMPLE_FS_IMAGE"));
112
113/// 挂载 simple_fs 作为根文件系统
114pub fn init_simple_fs() -> Result<(), crate::vfs::FsError> {
115    // 1. 创建 RamDisk,从静态镜像初始化
116    pr_info!(
117        "[SimpleFS] Creating RamDisk ({} bytes)",
118        SIMPLE_FS_IMAGE.len()
119    );
120    let ramdisk = RamDisk::from_bytes(SIMPLE_FS_IMAGE.to_vec(), 512, 0);
121
122    // 2. 在 RamDisk 上创建 SimpleFS
123    pr_info!("[SimpleFS] Mounting SimpleFS on RamDisk");
124    let simplefs = SimpleFs::from_ramdisk(ramdisk)?;
125
126    // 3. 挂载为根文件系统
127    MOUNT_TABLE.mount(
128        Arc::new(simplefs),
129        "/",
130        MountFlags::empty(),
131        Some(String::from("ramdisk0")),
132    )?;
133
134    pr_info!("[SimpleFS] Root filesystem mounted at /");
135
136    // 4. 列出根目录内容(调试用)
137    if let Ok(root_dentry) = crate::vfs::get_root_dentry() {
138        pr_info!("[SimpleFS] Root directory contents:");
139        let inode = root_dentry.inode.clone();
140        if let Ok(entries) = inode.readdir() {
141            for entry in entries {
142                pr_info!("  - {} (type: {:?})", entry.name, entry.inode_type);
143            }
144        }
145    }
146
147    Ok(())
148}
149
150/// 从真实的块设备初始化 Ext4 文件系统
151///
152/// 尝试从第一个可用的块设备创建 Ext4 文件系统,并挂载为根文件系统
153pub fn init_ext4_from_block_device() -> Result<(), crate::vfs::FsError> {
154    use crate::config::{EXT4_BLOCK_SIZE, FS_IMAGE_SIZE, VIRTIO_BLK_SECTOR_SIZE};
155    use crate::vfs::FsError;
156
157    pr_info!("[Ext4] Initializing Ext4 filesystem from block device");
158
159    // 1. 获取第一个块设备驱动
160    let blk_drivers = BLK_DRIVERS.read();
161    if blk_drivers.is_empty() {
162        pr_info!("[Ext4] No block device found");
163        return Err(FsError::NoDevice);
164    }
165
166    let block_driver = blk_drivers[0].clone();
167    drop(blk_drivers); // 释放锁
168
169    pr_info!("[Ext4] Using block device: {}", block_driver.get_id());
170
171    // 2. 获取块设备信息
172    // Ext4 文件系统块大小 (必须与 mkfs.ext4 -b 参数一致)
173    let ext4_block_size = EXT4_BLOCK_SIZE;
174    // fs.img 大小 (由 qemu-run.sh 创建)
175    // 计算总块数 (以 Ext4 块为单位, 而非扇区)
176    let total_blocks = FS_IMAGE_SIZE / ext4_block_size;
177
178    pr_info!(
179        "[Ext4] Ext4 block size: {}, Total blocks: {}, Image size: {} MB",
180        ext4_block_size,
181        total_blocks,
182        FS_IMAGE_SIZE / 1024 / 1024
183    );
184
185    // 3. 创建 Ext4 文件系统
186    // 注意: BlockDeviceAdapter 内部必须使用 EXT4_BLOCK_SIZE (4096)
187    let ext4_fs = Ext4FileSystem::open(block_driver, ext4_block_size, total_blocks, 0)?;
188
189    // 4. 挂载为根文件系统
190    pr_info!("[Ext4] Mounting Ext4 as root filesystem");
191    MOUNT_TABLE.mount(
192        ext4_fs,
193        "/",
194        MountFlags::empty(),
195        Some(String::from("virtio-blk0")),
196    )?;
197
198    pr_info!("[Ext4] Root filesystem mounted at /");
199
200    // 5. 列出根目录内容(调试用)
201    if let Ok(root_dentry) = crate::vfs::get_root_dentry() {
202        pr_info!("[Ext4] Root directory contents:");
203        let inode = root_dentry.inode.clone();
204        if let Ok(entries) = inode.readdir() {
205            for entry in entries {
206                pr_info!("  - {} (type: {:?})", entry.name, entry.inode_type);
207            }
208        } else {
209            pr_info!("[Ext4] Failed to read root directory");
210        }
211    }
212
213    Ok(())
214}
215
216/// 挂载 tmpfs 到指定路径
217///
218/// # 参数
219///
220/// - `mount_point`: 挂载点路径(如 "/tmp")
221/// - `max_size_mb`: 最大容量(MB),0 表示无限制
222pub fn mount_tmpfs(mount_point: &str, max_size_mb: usize) -> Result<(), crate::vfs::FsError> {
223    use crate::vfs::FsError;
224    use alloc::string::ToString;
225
226    pr_info!(
227        "[Tmpfs] Creating tmpfs filesystem (max_size: {} MB)",
228        if max_size_mb == 0 {
229            "unlimited".to_string()
230        } else {
231            max_size_mb.to_string()
232        }
233    );
234
235    // 创建 tmpfs
236    let tmpfs = TmpFs::new(max_size_mb);
237
238    // 挂载到指定路径
239    MOUNT_TABLE.mount(
240        tmpfs,
241        mount_point,
242        MountFlags::empty(),
243        Some(String::from("tmpfs")),
244    )?;
245
246    pr_info!("[Tmpfs] Tmpfs mounted at {}", mount_point);
247
248    Ok(())
249}
250
251pub fn init_dev() -> Result<(), FsError> {
252    if let Err(e) = vfs_lookup("/dev") {
253        return Err(e);
254    }
255
256    create_devices()?;
257
258    Ok(())
259}
260
261fn create_devices() -> Result<(), FsError> {
262    // 获取 /dev 目录的 dentry
263    let dev_dentry = vfs_lookup("/dev")?;
264
265    let dev_inode = &dev_dentry.inode;
266
267    // 字符设备:0666 权限
268    let char_mode = FileMode::S_IFCHR | FileMode::from_bits_truncate(0o666);
269
270    // /dev/null (1, 3)
271    dev_inode.mknod("null", char_mode, makedev(chrdev_major::MEM, 3))?;
272
273    // /dev/zero (1, 5)
274    dev_inode.mknod("zero", char_mode, makedev(chrdev_major::MEM, 5))?;
275
276    // /dev/random (1, 8)
277    dev_inode.mknod("random", char_mode, makedev(chrdev_major::MEM, 8))?;
278
279    // /dev/urandom (1, 9)
280    dev_inode.mknod("urandom", char_mode, makedev(chrdev_major::MEM, 9))?;
281
282    // /dev/console (5, 1) - 只读
283    let console_mode = FileMode::S_IFCHR | FileMode::from_bits_truncate(0o600);
284    dev_inode.mknod("console", console_mode, makedev(chrdev_major::CONSOLE, 1))?;
285
286    // /dev/ttyS0 (4, 64)
287    dev_inode.mknod("ttyS0", char_mode, makedev(chrdev_major::TTY, 64))?;
288
289    // 创建 /dev/misc 目录
290    let dir_mode = FileMode::S_IFDIR | FileMode::from_bits_truncate(0o755);
291    dev_inode.mkdir("misc", dir_mode)?;
292
293    // /dev/misc/rtc (10, 135)
294    let misc_dentry = vfs_lookup("/dev/misc")?;
295    misc_dentry
296        .inode
297        .mknod("rtc", char_mode, makedev(chrdev_major::MISC, 135))?;
298
299    // 块设备:0660 权限
300    let block_mode = FileMode::S_IFBLK | FileMode::from_bits_truncate(0o660);
301
302    // /dev/vda (254, 0)
303    dev_inode.mknod("vda", block_mode, makedev(blkdev_major::VIRTIO_BLK, 0))?;
304
305    Ok(())
306}
307
308/// 初始化并挂载 procfs 到 /proc
309pub fn init_procfs() -> Result<(), crate::vfs::FsError> {
310    use crate::fs::proc::ProcFS;
311    use crate::vfs::MountFlags;
312    use alloc::string::ToString;
313
314    pr_info!("[ProcFS] Initializing procfs");
315
316    // 创建 procfs
317    let procfs = ProcFS::new();
318
319    // 初始化文件系统树
320    procfs.init_tree()?;
321
322    // 挂载到 /proc
323    MOUNT_TABLE.mount(
324        procfs,
325        "/proc",
326        MountFlags::empty(),
327        Some(String::from("proc")),
328    )?;
329
330    pr_info!("[ProcFS] Procfs mounted at /proc");
331
332    Ok(())
333}
334
335/// 初始化并挂载 sysfs 到 /sys
336pub fn init_sysfs() -> Result<(), crate::vfs::FsError> {
337    use crate::fs::sysfs::SysFS;
338    use crate::vfs::MountFlags;
339    use alloc::string::ToString;
340
341    pr_info!("[SysFS] Initializing sysfs");
342
343    // 创建 sysfs
344    let sysfs = SysFS::new();
345
346    // 初始化文件系统树 (从设备注册表构建设备树)
347    sysfs.init_tree()?;
348
349    // 挂载到 /sys
350    MOUNT_TABLE.mount(
351        sysfs,
352        "/sys",
353        MountFlags::empty(),
354        Some(String::from("sysfs")),
355    )?;
356
357    pr_info!("[SysFS] Sysfs mounted at /sys");
358
359    Ok(())
360}
361
362#[cfg(test)]
363mod tests;