1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
/* Copyright (c) [2023] [Syswonder Community]
* [Rukos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
//! [ArceOS](https://github.com/rcore-os/arceos) filesystem module.
//!
//! It provides unified filesystem operations for various filesystems.
//!
//! # Cargo Features
//!
//! - `fatfs`: Use [FAT] as the main filesystem and mount it on `/`. This feature
//! is **enabled** by default.
//! - `devfs`: Mount [`axfs_devfs::DeviceFileSystem`] on `/dev`. This feature is
//! **enabled** by default.
//! - `ramfs`: Mount [`axfs_ramfs::RamFileSystem`] on `/tmp`. This feature is
//! **enabled** by default.
//! - `myfs`: Allow users to define their custom filesystems to override the
//! default. In this case, [`MyFileSystemIf`] is required to be implemented
//! to create and initialize other filesystems. This feature is **disabled** by
//! by default, but it will override other filesystem selection features if
//! both are enabled.
//!
//! [FAT]: https://en.wikipedia.org/wiki/File_Allocation_Table
//! [`MyFileSystemIf`]: fops::MyFileSystemIf
#![cfg_attr(all(not(test), not(doc)), no_std)]
#![feature(doc_auto_cfg)]
#[macro_use]
extern crate log;
extern crate alloc;
mod dev;
mod fs;
mod mounts;
mod root;
pub mod api;
pub mod fops;
use alloc::vec::Vec;
use axdriver::{prelude::*, AxDeviceContainer};
cfg_if::cfg_if! {
if #[cfg(feature = "myfs")] {
} else if #[cfg(feature = "fatfs")] {
use lazy_init::LazyInit;
use alloc::sync::Arc;
}
}
pub use root::MountPoint;
/// Initialize an empty filesystems by ramfs.
#[cfg(not(any(feature = "blkfs", feature = "virtio-9p", feature = "net-9p")))]
pub fn init_tempfs() -> MountPoint {
MountPoint::new("/", mounts::ramfs())
}
/// Initializes filesystems by block devices.
pub fn init_blkfs(mut blk_devs: AxDeviceContainer<AxBlockDevice>) -> MountPoint {
info!("Initialize filesystems...");
let dev = blk_devs.take_one().expect("No block device found!");
info!(" use block device 0: {:?}", dev.device_name());
let disk = self::dev::Disk::new(dev);
cfg_if::cfg_if! {
if #[cfg(feature = "myfs")] { // override the default filesystem
let blk_fs = fs::myfs::new_myfs(disk);
} else if #[cfg(feature = "fatfs")] {
static FAT_FS: LazyInit<Arc<fs::fatfs::FatFileSystem>> = LazyInit::new();
FAT_FS.init_by(Arc::new(fs::fatfs::FatFileSystem::new(disk)));
FAT_FS.init();
let blk_fs = FAT_FS.clone();
}
}
MountPoint::new("/", blk_fs)
}
/// Initializes common filesystems.
pub fn prepare_commonfs(mount_points: &mut Vec<self::root::MountPoint>) {
#[cfg(feature = "devfs")]
let mount_point = MountPoint::new("/dev", mounts::devfs());
mount_points.push(mount_point);
#[cfg(feature = "ramfs")]
let mount_point = MountPoint::new("/tmp", mounts::ramfs());
mount_points.push(mount_point);
// Mount another ramfs as procfs
#[cfg(feature = "procfs")]
let mount_point = MountPoint::new("/proc", mounts::procfs().unwrap());
mount_points.push(mount_point);
// Mount another ramfs as sysfs
#[cfg(feature = "sysfs")]
let mount_point = MountPoint::new("/sys", mounts::sysfs().unwrap());
mount_points.push(mount_point);
}
/// Initializes root filesystems.
pub fn init_filesystems(mount_points: Vec<self::root::MountPoint>) {
self::root::init_rootfs(mount_points);
}