Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@

# Cargo lock
Cargo.lock

/shared
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"entry/Cargo.toml",
],
"rust-analyzer.cargo.features": [
"qemu", "smp", "unittest"
"qemu", "smp",
],
"rust-analyzer.cargo.extraEnv": {
"RUSTFLAGS": "--cfg unittest --check-cfg cfg(unittest)"
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ kerrno = { path = "util/kerrno" }
unittest = { path = "util/unittest" }
kconfig-gen = { path = "xtask/kconfig-gen" }
smoltcp = { version = "0.12.0", package = "x-smoltcp", default-features = false }
fs9p = { path = "fs/fs9p", default-features = false }

[patch.crates-io]
virtio-drivers = { git = "https://github.com/luodeb/virtio-drivers" }
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ NET ?= y
GRAPHIC ?= n
INPUT ?= y
VSOCK ?= y
VIRTIO_9P ?= n
BUS ?= pci
MEM ?= 1g
ACCEL ?= y
Expand Down
14 changes: 12 additions & 2 deletions api/kapi/src/vfs/dev/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use core::bstr::ByteStr;

use kerrno::LinuxResult;
use kerrno::{KErrorKind, LinuxError, LinuxResult};
use knet::{
RecvOptions, SocketAddrEx, SocketOps,
unix::{DgramTransport, UnixAddr, UnixDomainSocket},
Expand All @@ -13,7 +13,17 @@ use knet::{
/// Bind /dev/log as a Unix domain socket for syslog messages
pub fn bind_dev_log() -> LinuxResult<()> {
let server = UnixDomainSocket::new(DgramTransport::new(1));
server.bind(SocketAddrEx::Unix(UnixAddr::Path("/dev/log".into())))?;
if let Err(err) = server.bind(SocketAddrEx::Unix(UnixAddr::Path("/dev/log".into()))) {
let kind = KErrorKind::try_from(err);
if matches!(
kind,
Ok(KErrorKind::Unsupported | KErrorKind::OperationNotSupported)
) {
warn!("/dev/log not supported: {err}");
return Ok(());
}
return Err(LinuxError::from(err));
}
ktask::spawn_with_name(
move || {
let mut buf = [0u8; 65536];
Expand Down
30 changes: 24 additions & 6 deletions api/kapi/src/vfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,27 @@ use fs_ng_vfs::{
path::{Path, PathBuf},
};
pub use kcore::vfs::{Device, DeviceOps, DirMapping, SimpleFs};
use kerrno::LinuxResult;
use kerrno::{LinuxError, LinuxResult};
use kfs::{FS_CONTEXT, FsContext};
pub use tmp::MemoryFs;

const DIR_PERMISSION: NodePermission = NodePermission::from_bits_truncate(0o755);

/// Mount a filesystem at the specified path, creating the path if it doesn't exist
fn mount_at(fs: &FsContext, path: &str, mount_fs: Filesystem) -> LinuxResult<()> {
if fs.resolve(path).is_err() {
fs.create_dir(path, DIR_PERMISSION)?;
match fs.resolve(path) {
Ok(loc) => {
if loc.check_is_dir().is_err() {
// Path exists but is not a directory, replace it with a directory.
fs.remove_file(path)?;
fs.create_dir(path, DIR_PERMISSION)?;
}
}
Err(_) => {
fs.create_dir(path, DIR_PERMISSION)?;
}
}
fs.resolve(path)?.mount(&mount_fs)?;
info!("Mounted {} at {}", mount_fs.name(), path);
Ok(())
}

Expand All @@ -47,11 +55,21 @@ pub fn mount_all() -> LinuxResult<()> {
}
}
path.push("subsystem");
fs.symlink("whatever", &path)?;
if let Err(err) = fs.symlink("whatever", &path) {
let linux_err = LinuxError::from(err);
if linux_err != LinuxError::EEXIST {
return Err(linux_err);
}
}
drop(fs);

#[cfg(feature = "dev-log")]
dev::bind_dev_log().expect("Failed to bind /dev/log");
if let Err(err) = dev::bind_dev_log() {
if err != LinuxError::ENOSYS && err != LinuxError::EOPNOTSUPP {
return Err(err);
}
warn!("/dev/log not available: {err}");
}

Ok(())
}
9 changes: 4 additions & 5 deletions api/kfeat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ sched-cfs = ["ktask/sched-cfs"]
fs = [
"alloc",
"paging",
"kdriver/virtio-blk",
"dep:kfs",
"kruntime/fs",
] # TODO: try to remove "paging"
fs-ext4 = ["fs", "kfs/ext4"]
fs-fat = ["fs", "kfs/fat"]
fs-times = ["fs", "kfs/times"]
fs-ext4 = ["kfs/ext4", "kdriver/virtio-blk", "kruntime/fs"]
fs-fat = ["kfs/fat", "kdriver/virtio-blk", "kruntime/fs"]
fs-9p = ["kfs/fs9p", "kdriver/virtio_9p", "kruntime/fs9p"]
fs-times = ["kfs/times"]

# Networking
net = ["alloc", "paging", "kdriver/virtio-net", "dep:knet", "kruntime/net"]
Expand Down
2 changes: 2 additions & 0 deletions drivers/driver_base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub enum DeviceKind {
Input,
/// Vsock device (e.g., virtio-vsock).
Vsock,
/// 9P filesystem device (e.g., virtio-9p).
Virtio9p,
}

/// The error type for driver operation failures.
Expand Down
2 changes: 2 additions & 0 deletions drivers/kdriver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ virtio-net = ["net", "virtio", "virtio/net"]
virtio-gpu = ["display", "virtio", "virtio/gpu"]
virtio-input = ["input", "virtio", "virtio/input"]
virtio-socket = ["vsock", "virtio", "virtio/socket"]
virtio_9p = ["virtio", "virtio/virtio_9p"]

ramdisk = ["block", "block/ramdisk"]
# bcm2835-sdhci = ["block", "block/bcm2835-sdhci"]
# sdmmc = ["block", "block/sdmmc", "dep:khal", "dep:platconfig"]
Expand Down
8 changes: 7 additions & 1 deletion drivers/kdriver/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const BLOCK_DEV_FEATURES: &[&str] = &["ahci", "ramdisk", "sdmmc", "bcm2835-sdhci
const DISPLAY_DEV_FEATURES: &[&str] = &["virtio-gpu"];
const INPUT_DEV_FEATURES: &[&str] = &["virtio-input"];
const VSOCK_DEV_FEATURES: &[&str] = &["virtio-socket"];
const VIRTIO_9P_DEV_FEATURES: &[&str] = &["virtio-9p"];

fn make_cfg_values(str_list: &[&str]) -> String {
str_list
Expand Down Expand Up @@ -44,6 +45,7 @@ fn main() {
("display", DISPLAY_DEV_FEATURES),
("input", INPUT_DEV_FEATURES),
("vsock", VSOCK_DEV_FEATURES),
("virtio_9p", VIRTIO_9P_DEV_FEATURES),
] {
if !has_feature(dev_kind) {
continue;
Expand Down Expand Up @@ -88,4 +90,8 @@ fn main() {
"cargo::rustc-check-cfg=cfg(vsock_dev, values({}, \"dummy\"))",
make_cfg_values(VSOCK_DEV_FEATURES)
);
}
println!(
"cargo::rustc-check-cfg=cfg(virtio_9p_dev, values({}, \"dummy\"))",
make_cfg_values(VIRTIO_9P_DEV_FEATURES)
);
}
6 changes: 6 additions & 0 deletions drivers/kdriver/src/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ register_vsock_driver!(
<virtio::VirtIoSocket as VirtIoDevMeta>::Device
);

#[cfg(virtio_9p_dev = "virtio-9p")]
register_virtio_9p_driver!(
<virtio::VirtIo9p as VirtIoDevMeta>::Driver,
<virtio::VirtIo9p as VirtIoDevMeta>::Device
);

cfg_if::cfg_if! {
if #[cfg(block_dev = "ramdisk")] {
pub struct RamDiskDriver;
Expand Down
28 changes: 28 additions & 0 deletions drivers/kdriver/src/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,31 @@ cfg_if! {
}
}
}

cfg_if! {
if #[cfg(virtio_9p_dev = "dummy")] {
/// Placeholder 9P filesystem device.
pub struct DummyVirtio9pDev;
/// Placeholder 9P filesystem driver.
pub struct DummyVirtio9pDriver;
register_virtio_9p_driver!(DummyVirtio9pDriver, DummyVirtio9pDev);

impl DriverOps for DummyVirtio9pDev {
fn device_kind(&self) -> DeviceKind {
DeviceKind::Virtio9p
}
fn name(&self) -> &str {
"dummy-virtio_9p"
}
}

impl Virtio9pDriverOps for DummyVirtio9pDev {
fn mount(&mut self, _mount_point: &str) -> DriverResult<()> {
Err(DriverError::Unsupported)
}
fn unmount(&mut self) -> DriverResult<()> {
Err(DriverError::Unsupported)
}
}
}
}
7 changes: 7 additions & 0 deletions drivers/kdriver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ pub use self::structs::BlockDevice;
pub use self::structs::DisplayDevice;
#[cfg(feature = "net")]
pub use self::structs::NetDevice;
#[cfg(feature = "virtio_9p")]
pub use self::structs::Virtio9pDevice;
pub use self::structs::{DeviceContainer, DeviceEnum};

/// A structure that contains all device drivers, organized by their category.
Expand All @@ -61,6 +63,9 @@ pub struct AllDevices {
/// All vsock device drivers.
#[cfg(feature = "vsock")]
pub vsock: DeviceContainer<VsockDevice>,
#[cfg(feature = "virtio_9p")]
/// All virtio-9p device drivers.
pub virtio_9p: DeviceContainer<Virtio9pDevice>,
}

impl AllDevices {
Expand Down Expand Up @@ -98,6 +103,8 @@ impl AllDevices {
DeviceEnum::Input(dev) => self.input.push(dev),
#[cfg(feature = "vsock")]
DeviceEnum::Vsock(dev) => self.vsock.push(dev),
#[cfg(feature = "virtio_9p")]
DeviceEnum::Virtio9p(dev) => self.virtio_9p.push(dev),
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions drivers/kdriver/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ macro_rules! register_vsock_driver {
};
}

/// Define the unified type for 9P filesystem devices.
macro_rules! register_virtio_9p_driver {
($driver_type:ty, $device_type:ty) => {
/// The unified type of the 9P filesystem devices.
pub type Virtio9pDevice = $device_type;
};
}

/// Expand to iterate through all registered drivers under the current build config.
macro_rules! for_each_drivers {
(type $drv_type:ident, $code:block) => {{
Expand Down Expand Up @@ -82,6 +90,11 @@ macro_rules! for_each_drivers {
type $drv_type = <virtio::VirtIoSocket as VirtIoDevMeta>::Driver;
$code
}
#[cfg(virtio_9p_dev = "virtio-9p")]
{
type $drv_type = <virtio::VirtIo9p as VirtIoDevMeta>::Driver;
$code
}
#[cfg(block_dev = "ramdisk")]
{
type $drv_type = crate::drivers::RamDiskDriver;
Expand Down
7 changes: 7 additions & 0 deletions drivers/kdriver/src/structs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ pub enum DeviceEnum {
/// Vsock device.
#[cfg(feature = "vsock")]
Vsock(VsockDevice),
/// 9P filesystem device.
#[cfg(feature = "virtio_9p")]
Virtio9p(Virtio9pDevice),
}

impl DriverOps for DeviceEnum {
Expand All @@ -50,6 +53,8 @@ impl DriverOps for DeviceEnum {
Self::Input(_) => DeviceKind::Input,
#[cfg(feature = "vsock")]
Self::Vsock(_) => DeviceKind::Vsock,
#[cfg(feature = "virtio_9p")]
Self::Virtio9p(_) => DeviceKind::Virtio9p,
_ => unreachable!(),
}
}
Expand All @@ -68,6 +73,8 @@ impl DriverOps for DeviceEnum {
Self::Input(dev) => dev.name(),
#[cfg(feature = "vsock")]
Self::Vsock(dev) => dev.name(),
#[cfg(feature = "virtio_9p")]
Self::Virtio9p(dev) => dev.name(),
_ => unreachable!(),
}
}
Expand Down
8 changes: 8 additions & 0 deletions drivers/kdriver/src/structs/static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub use crate::drivers::InputDevice;
pub use crate::drivers::NetDevice;
#[cfg(feature = "vsock")]
pub use crate::drivers::VsockDevice;
#[cfg(feature = "virtio_9p")]
pub use crate::drivers::Virtio9pDevice;

impl super::DeviceEnum {
/// Constructs a network device.
Expand Down Expand Up @@ -44,4 +46,10 @@ impl super::DeviceEnum {
pub const fn from_vsock(dev: VsockDevice) -> Self {
Self::Vsock(dev)
}

/// Constructs a 9P filesystem device.
#[cfg(feature = "virtio_9p")]
pub const fn from_virtio_9p(dev: Virtio9pDevice) -> Self {
Self::Virtio9p(dev)
}
}
16 changes: 16 additions & 0 deletions drivers/kdriver/src/virtio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ cfg_if! {
}
}

cfg_if! {
if #[cfg(virtio_9p_dev = "virtio-9p")] {
pub struct VirtIo9p;

impl VirtIoDevMeta for VirtIo9p {
const DEVICE_TYPE: DeviceKind = DeviceKind::Virtio9p;
type Device = virtio::VirtIo9pDev<VirtIoHalImpl, VirtIoTransport>;

fn try_new(transport: VirtIoTransport, _irq: Option<usize>) -> DriverResult<DeviceEnum> {
Ok(DeviceEnum::from_virtio_9p(Self::Device::try_new(transport)?))
}
}
}
}

/// A common driver for all VirtIO devices that implements [`DriverProbe`].
pub struct VirtIoDriver<D: VirtIoDevMeta + ?Sized>(PhantomData<D>);

Expand Down Expand Up @@ -153,6 +168,7 @@ impl<D: VirtIoDevMeta> DriverProbe for VirtIoDriver<D> {
(DeviceKind::Input, 0x1052) => {}
(DeviceKind::Display, 0x1050) => {}
(DeviceKind::Vsock, 0x1053) => {}
(DeviceKind::Virtio9p, 0x1009) => {}
_ => return None,
}

Expand Down
6 changes: 4 additions & 2 deletions drivers/virtio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ gpu = ["alloc", "display"]
input = ["alloc", "dep:input"]
net = ["alloc", "dep:net"]
socket = ["alloc", "dep:vsock"]
virtio_9p = ["alloc"]

[dependencies]
zerocopy = "0.8"
driver_base = { workspace = true }
block = { workspace = true, optional = true }
display = { workspace = true, optional = true }
input = { workspace = true, optional = true }
net = { workspace = true, optional = true }
vsock = { workspace = true, optional = true }
log = { workspace = true }
virtio-drivers.workspace = true
virtio-drivers = { workspace = true }
unittest = { workspace = true }
zerocopy = "0.8"

6 changes: 6 additions & 0 deletions drivers/virtio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ mod net;
#[cfg(feature = "net")]
pub use self::net::VirtIoNetDev;

#[cfg(feature = "virtio_9p")]
mod virtio_9p;
#[cfg(feature = "virtio_9p")]
pub use self::virtio_9p::VirtIo9pDev;

#[cfg(unittest)]
pub mod mock_virtio;
#[cfg(feature = "socket")]
Expand Down Expand Up @@ -112,6 +117,7 @@ const fn as_device_kind(t: VirtIoDevType) -> Option<DeviceKind> {
GPU => Some(DeviceKind::Display),
Input => Some(DeviceKind::Input),
Socket => Some(DeviceKind::Vsock),
_9P => Some(DeviceKind::Virtio9p),
_ => None,
}
}
Expand Down
Loading
Loading