Fix typos and add utils

This commit is contained in:
Jianfeng Jiang 2023-05-31 10:46:51 +08:00 committed by Tate, Hongliang Tian
parent b2f2c55c9b
commit d96fe31e36
26 changed files with 388 additions and 71 deletions

4
.gitattributes vendored
View File

@ -8,3 +8,7 @@ regression/apps/signal_c/signal_test filter=lfs diff=lfs merge=lfs -text
regression/apps/busybox/busybox filter=lfs diff=lfs merge=lfs -text regression/apps/busybox/busybox filter=lfs diff=lfs merge=lfs -text
regression/apps/pthread/pthread_test filter=lfs diff=lfs merge=lfs -text regression/apps/pthread/pthread_test filter=lfs diff=lfs merge=lfs -text
regression/apps/hello_pie/hello filter=lfs diff=lfs merge=lfs -text regression/apps/hello_pie/hello filter=lfs diff=lfs merge=lfs -text
regression/apps/network/tcp/client filter=lfs diff=lfs merge=lfs -text
regression/apps/network/tcp/server filter=lfs diff=lfs merge=lfs -text
regression/apps/network/udp/client filter=lfs diff=lfs merge=lfs -text
regression/apps/network/udp/server filter=lfs diff=lfs merge=lfs -text

3
.gitignore vendored
View File

@ -18,3 +18,6 @@ regression/ramdisk/build/
# qemu log file # qemu log file
qemu.log qemu.log
# packet dump file
virtio-net.pcap

137
Cargo.lock generated
View File

@ -59,6 +59,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
[[package]]
name = "atomic-polyfill"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
dependencies = [
"critical-section",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -145,6 +154,12 @@ dependencies = [
name = "cpio-decoder" name = "cpio-decoder"
version = "0.1.0" version = "0.1.0"
[[package]]
name = "critical-section"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52"
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.15" version = "0.8.15"
@ -198,6 +213,38 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "defmt"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "956673bd3cb347512bf988d1e8d89ac9a82b64f6eec54d3c01c3529dac019882"
dependencies = [
"bitflags",
"defmt-macros",
]
[[package]]
name = "defmt-macros"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4abc4821bd84d3d8f49945ddb24d029be9385ed9b77c99bf2f6296847a6a9f0"
dependencies = [
"defmt-parser",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "defmt-parser"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "269924c02afd7f94bc4cecbfa5c379f6ffcf9766b3408fe63d22c728654eccd0"
dependencies = [
"thiserror",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.8.0" version = "1.8.0"
@ -233,6 +280,15 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@ -248,6 +304,19 @@ dependencies = [
"ahash", "ahash",
] ]
[[package]]
name = "heapless"
version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
dependencies = [
"atomic-polyfill",
"hash32",
"rustc_version",
"spin 0.9.4",
"stable_deref_trait",
]
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@ -461,6 +530,7 @@ dependencies = [
"lru", "lru",
"pod", "pod",
"ringbuf", "ringbuf",
"smoltcp",
"spin 0.9.4", "spin 0.9.4",
"time", "time",
"typeflags", "typeflags",
@ -495,6 +565,7 @@ dependencies = [
name = "jinux-virtio" name = "jinux-virtio"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"align_ext",
"bitflags", "bitflags",
"component", "component",
"int-to-c-enum", "int-to-c-enum",
@ -568,6 +639,12 @@ dependencies = [
"hashbrown 0.13.1", "hashbrown 0.13.1",
] ]
[[package]]
name = "managed"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.5.0"
@ -607,6 +684,30 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.56" version = "1.0.56"
@ -668,6 +769,15 @@ dependencies = [
"wait-timeout", "wait-timeout",
] ]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.9" version = "1.0.9"
@ -680,6 +790,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.152" version = "1.0.152"
@ -695,6 +811,21 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "smoltcp"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e9786ac45091b96f946693e05bfa4d8ca93e2d3341237d97a380107a6b38dea"
dependencies = [
"bitflags",
"byteorder",
"cfg-if",
"defmt",
"heapless",
"log",
"managed",
]
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.5.2" version = "0.5.2"
@ -719,6 +850,12 @@ dependencies = [
"lock_api", "lock_api",
] ]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"

View File

@ -7,6 +7,7 @@ input = { name = "jinux-input" }
block = { name = "jinux-block" } block = { name = "jinux-block" }
time = { name = "jinux-time" } time = { name = "jinux-time" }
framebuffer = { name = "jinux-framebuffer" } framebuffer = { name = "jinux-framebuffer" }
network = { name = "jinux-network" }
main = { name = "jinux" } main = { name = "jinux" }
[whitelist] [whitelist]

View File

@ -3,6 +3,7 @@ pub mod hpet;
pub mod pit; pub mod pit;
use core::any::Any; use core::any::Any;
use core::sync::atomic::{AtomicU64, Ordering};
use alloc::{boxed::Box, collections::BinaryHeap, sync::Arc, vec::Vec}; use alloc::{boxed::Box, collections::BinaryHeap, sync::Arc, vec::Vec};
use spin::{Mutex, Once}; use spin::{Mutex, Once};
@ -12,7 +13,7 @@ use crate::arch::x86::kernel;
use crate::trap::IrqAllocateHandle; use crate::trap::IrqAllocateHandle;
pub const TIMER_IRQ_NUM: u8 = 32; pub const TIMER_IRQ_NUM: u8 = 32;
pub static mut TICK: u64 = 0; pub static TICK: AtomicU64 = AtomicU64::new(0);
static TIMER_IRQ: Once<IrqAllocateHandle> = Once::new(); static TIMER_IRQ: Once<IrqAllocateHandle> = Once::new();
@ -30,11 +31,7 @@ pub fn init() {
} }
fn timer_callback(trap_frame: &TrapFrame) { fn timer_callback(trap_frame: &TrapFrame) {
let current_ms; let current_ms = TICK.fetch_add(1, Ordering::SeqCst);
unsafe {
current_ms = TICK;
TICK += 1;
}
let mut timeout_list = TIMEOUT_LIST.get().unwrap().lock(); let mut timeout_list = TIMEOUT_LIST.get().unwrap().lock();
let mut callbacks: Vec<Arc<TimerCallback>> = Vec::new(); let mut callbacks: Vec<Arc<TimerCallback>> = Vec::new();
while let Some(t) = timeout_list.peek() { while let Some(t) = timeout_list.peek() {
@ -121,10 +118,18 @@ where
F: Fn(&TimerCallback) + Send + Sync + 'static, F: Fn(&TimerCallback) + Send + Sync + 'static,
T: Any + Send + Sync, T: Any + Send + Sync,
{ {
unsafe { let timer_callback = TimerCallback::new(
let timer_callback = TimerCallback::new(TICK + timeout, Arc::new(data), Box::new(callback)); TICK.load(Ordering::SeqCst) + timeout,
let arc = Arc::new(timer_callback); Arc::new(data),
TIMEOUT_LIST.get().unwrap().lock().push(arc.clone()); Box::new(callback),
arc );
} let arc = Arc::new(timer_callback);
TIMEOUT_LIST.get().unwrap().lock().push(arc.clone());
arc
}
/// The time since the system boots up.
/// The currently returned results are in milliseconds.
pub fn read_monotonic_milli_seconds() -> u64 {
TICK.load(Ordering::SeqCst)
} }

View File

@ -18,4 +18,4 @@ pub const KVA_START: usize = (usize::MAX) << PAGE_SIZE_BITS;
pub const DEFAULT_LOG_LEVEL: Level = Level::Error; pub const DEFAULT_LOG_LEVEL: Level = Level::Error;
/// This value represent the base timer frequency in Hz /// This value represent the base timer frequency in Hz
pub const TIMER_FREQ: u64 = 100; pub const TIMER_FREQ: u64 = 1000;

View File

@ -3,9 +3,12 @@
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use crate::arch::x86::timer::{add_timeout_list, TimerCallback, TICK}; use crate::arch::x86::timer::{add_timeout_list, TimerCallback, TICK};
use crate::{config::TIMER_FREQ, prelude::*}; use crate::{config::TIMER_FREQ, prelude::*};
use core::time::Duration; use core::{sync::atomic::Ordering, time::Duration};
use spin::Mutex; use spin::Mutex;
#[cfg(target_arch = "x86_64")]
pub use crate::arch::x86::timer::read_monotonic_milli_seconds;
/// A timer invokes a callback function after a specified span of time elapsed. /// A timer invokes a callback function after a specified span of time elapsed.
/// ///
/// A new timer is initially inactive. Only after a timeout value is set with /// A new timer is initially inactive. Only after a timeout value is set with
@ -63,10 +66,9 @@ impl Timer {
} }
let tick_count = let tick_count =
timeout.as_secs() * TIMER_FREQ + timeout.subsec_nanos() as u64 / NANOS_DIVIDE; timeout.as_secs() * TIMER_FREQ + timeout.subsec_nanos() as u64 / NANOS_DIVIDE;
unsafe { let tick = TICK.load(Ordering::SeqCst);
lock.start_tick = TICK; lock.start_tick = tick;
lock.timeout_tick = TICK + tick_count; lock.timeout_tick = tick + tick_count;
}
lock.timer_callback = Some(add_timeout_list(tick_count, self.clone(), timer_callback)); lock.timer_callback = Some(add_timeout_list(tick_count, self.clone(), timer_callback));
} }
@ -75,10 +77,10 @@ impl Timer {
/// If the timer is not set, then the remaining timeout value is zero. /// If the timer is not set, then the remaining timeout value is zero.
pub fn remain(&self) -> Duration { pub fn remain(&self) -> Duration {
let lock = self.inner.lock(); let lock = self.inner.lock();
let tick_remain; let tick_remain = {
unsafe { let tick = TICK.load(Ordering::SeqCst) as i64;
tick_remain = lock.timeout_tick as i64 - TICK as i64; lock.timeout_tick as i64 - tick
} };
if tick_remain <= 0 { if tick_remain <= 0 {
Duration::new(0, 0) Duration::new(0, 0)
} else { } else {

View File

@ -16,7 +16,7 @@ ifneq (, $(wildcard $(INITRAMFS)/. ))
endif endif
.PHONY: all clean prepare_libs .PHONY: all clean prepare_libs copy_special_files
all: $(RAMDISK) all: $(RAMDISK)

View File

@ -3,7 +3,7 @@
use jinux_frame::trap::TrapFrame; use jinux_frame::trap::TrapFrame;
use jinux_pci::msix::MSIX; use jinux_pci::msix::MSIX;
use jinux_util::frame_ptr::InFramePtr; use jinux_util::frame_ptr::InFramePtr;
use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VitrioPciCommonCfg}; use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VirtioPciCommonCfg};
use log::debug; use log::debug;
use spin::Mutex; use spin::Mutex;
@ -11,7 +11,7 @@ use crate::{BlockDevice, BLK_COMPONENT};
pub struct VirtioBlockDevice { pub struct VirtioBlockDevice {
blk_device: Mutex<BLKDevice>, blk_device: Mutex<BLKDevice>,
pub common_cfg: InFramePtr<VitrioPciCommonCfg>, pub common_cfg: InFramePtr<VirtioPciCommonCfg>,
msix: MSIX, msix: MSIX,
} }

View File

@ -6,7 +6,7 @@ use jinux_frame::trap::TrapFrame;
use jinux_pci::msix::MSIX; use jinux_pci::msix::MSIX;
use jinux_util::frame_ptr::InFramePtr; use jinux_util::frame_ptr::InFramePtr;
use jinux_virtio::device::input::device::InputProp; use jinux_virtio::device::input::device::InputProp;
use jinux_virtio::VitrioPciCommonCfg; use jinux_virtio::VirtioPciCommonCfg;
use jinux_virtio::{ use jinux_virtio::{
device::input::{device::InputDevice, InputConfigSelect}, device::input::{device::InputDevice, InputConfigSelect},
PCIVirtioDevice, PCIVirtioDevice,
@ -18,7 +18,7 @@ use virtio_input_decoder::{DecodeType, Decoder};
use crate::INPUTDevice; use crate::INPUTDevice;
pub struct VirtioInputDevice { pub struct VirtioInputDevice {
input_device: InputDevice, input_device: InputDevice,
common_cfg: InFramePtr<VitrioPciCommonCfg>, common_cfg: InFramePtr<VirtioPciCommonCfg>,
msix: Mutex<MSIX>, msix: Mutex<MSIX>,
name: String, name: String,
callbacks: Mutex<Vec<Arc<dyn Fn(DecodeType) + Send + Sync + 'static>>>, callbacks: Mutex<Vec<Arc<dyn Fn(DecodeType) + Send + Sync + 'static>>>,
@ -57,7 +57,7 @@ impl VirtioInputDevice {
let mut msix = virtio_device.msix; let mut msix = virtio_device.msix;
let config_msix_vector = let config_msix_vector =
common_cfg.read_at(offset_of!(VitrioPciCommonCfg, config_msix_vector)) as usize; common_cfg.read_at(offset_of!(VirtioPciCommonCfg, config_msix_vector)) as usize;
let mut event_irq_number = 0; let mut event_irq_number = 0;
for i in 0..msix.table_size as usize { for i in 0..msix.table_size as usize {

View File

@ -8,6 +8,7 @@ edition = "2021"
[dependencies] [dependencies]
bitflags = "1.3" bitflags = "1.3"
spin = "0.9.4" spin = "0.9.4"
align_ext = { path = "../../../framework/libs/align_ext" }
jinux-frame = { path = "../../../framework/jinux-frame" } jinux-frame = { path = "../../../framework/jinux-frame" }
jinux-pci = { path = "../pci" } jinux-pci = { path = "../pci" }
jinux-util = { path = "../../libs/jinux-util" } jinux-util = { path = "../../libs/jinux-util" }

View File

@ -10,7 +10,7 @@ use crate::{
device::block::{BlkReq, BlkResp, ReqType, RespStatus, BLK_SIZE}, device::block::{BlkReq, BlkResp, ReqType, RespStatus, BLK_SIZE},
device::VirtioDeviceError, device::VirtioDeviceError,
queue::{QueueError, VirtQueue}, queue::{QueueError, VirtQueue},
VitrioPciCommonCfg, VirtioPciCommonCfg,
}; };
use super::{BLKFeatures, VirtioBLKConfig}; use super::{BLKFeatures, VirtioBLKConfig};
@ -27,13 +27,13 @@ impl BLKDevice {
pub(crate) fn new( pub(crate) fn new(
cap: &CapabilityVirtioData, cap: &CapabilityVirtioData,
bars: [Option<BAR>; 6], bars: [Option<BAR>; 6],
common_cfg: &InFramePtr<VitrioPciCommonCfg>, common_cfg: &InFramePtr<VirtioPciCommonCfg>,
notify_base_address: usize, notify_base_address: usize,
notify_off_multiplier: u32, notify_off_multiplier: u32,
mut msix_vector_left: Vec<u16>, mut msix_vector_left: Vec<u16>,
) -> Result<Self, VirtioDeviceError> { ) -> Result<Self, VirtioDeviceError> {
let config = VirtioBLKConfig::new(cap, bars); let config = VirtioBLKConfig::new(cap, bars);
let num_queues = common_cfg.read_at(offset_of!(VitrioPciCommonCfg, num_queues)) as u16; let num_queues = common_cfg.read_at(offset_of!(VirtioPciCommonCfg, num_queues)) as u16;
if num_queues != 1 { if num_queues != 1 {
return Err(VirtioDeviceError::QueuesAmountDoNotMatch(num_queues, 1)); return Err(VirtioDeviceError::QueuesAmountDoNotMatch(num_queues, 1));
} }

View File

@ -1,4 +1,4 @@
use crate::{device::VirtioDeviceError, queue::VirtQueue, VitrioPciCommonCfg}; use crate::{device::VirtioDeviceError, queue::VirtQueue, VirtioPciCommonCfg};
use alloc::{boxed::Box, vec::Vec}; use alloc::{boxed::Box, vec::Vec};
use bitflags::bitflags; use bitflags::bitflags;
use jinux_frame::offset_of; use jinux_frame::offset_of;
@ -56,7 +56,7 @@ impl InputDevice {
pub fn new( pub fn new(
cap: &CapabilityVirtioData, cap: &CapabilityVirtioData,
bars: [Option<BAR>; 6], bars: [Option<BAR>; 6],
common_cfg: &InFramePtr<VitrioPciCommonCfg>, common_cfg: &InFramePtr<VirtioPciCommonCfg>,
notify_base_address: usize, notify_base_address: usize,
notify_off_multiplier: u32, notify_off_multiplier: u32,
mut msix_vector_left: Vec<u16>, mut msix_vector_left: Vec<u16>,

View File

@ -1,4 +1,7 @@
use crate::{device::block::device::BLKDevice, Feature, VirtioDeviceType, VitrioPciCommonCfg}; use crate::{
device::block::device::BLKDevice, queue::QueueError, Feature, VirtioDeviceType,
VirtioPciCommonCfg,
};
use alloc::vec::Vec; use alloc::vec::Vec;
use jinux_pci::{ use jinux_pci::{
capability::{vendor::virtio::CapabilityVirtioData, Capability}, capability::{vendor::virtio::CapabilityVirtioData, Capability},
@ -43,11 +46,17 @@ pub enum VirtioDeviceError {
CapabilityListError, CapabilityListError,
} }
impl From<QueueError> for VirtioDeviceError {
fn from(_: QueueError) -> Self {
VirtioDeviceError::QueueUnknownError
}
}
pub struct VirtioInfo { pub struct VirtioInfo {
pub device_type: VirtioDeviceType, pub device_type: VirtioDeviceType,
pub notify_base_address: u64, pub notify_base_address: u64,
pub notify_off_multiplier: u32, pub notify_off_multiplier: u32,
pub common_cfg_frame_ptr: InFramePtr<VitrioPciCommonCfg>, pub common_cfg_frame_ptr: InFramePtr<VirtioPciCommonCfg>,
pub device_cap_cfg: CapabilityVirtioData, pub device_cap_cfg: CapabilityVirtioData,
} }
@ -68,7 +77,7 @@ impl VirtioInfo {
match cap_data.cfg_type { match cap_data.cfg_type {
PCI_VIRTIO_CAP_COMMON_CFG => { PCI_VIRTIO_CAP_COMMON_CFG => {
common_cfg_frame_ptr_some = common_cfg_frame_ptr_some =
Some(VitrioPciCommonCfg::new(&cap_data, bars)); Some(VirtioPciCommonCfg::new(&cap_data, bars));
} }
PCI_VIRTIO_CAP_NOTIFY_CFG => { PCI_VIRTIO_CAP_NOTIFY_CFG => {
notify_off_multiplier = cap_data.option.unwrap(); notify_off_multiplier = cap_data.option.unwrap();
@ -140,7 +149,8 @@ impl VirtioDevice {
} }
pub(crate) fn negotiate_features(features: u64, device_type: VirtioDeviceType) -> u64 { pub(crate) fn negotiate_features(features: u64, device_type: VirtioDeviceType) -> u64 {
let device_specified_features = features & ((1 << 24) - 1); let mask = ((1u64 << 24) - 1) | (((1u64 << 24) - 1) << 50);
let device_specified_features = features & mask;
let device_support_features = match device_type { let device_support_features = match device_type {
VirtioDeviceType::Network => todo!(), VirtioDeviceType::Network => todo!(),
VirtioDeviceType::Block => BLKDevice::negotiate_features(device_specified_features), VirtioDeviceType::Block => BLKDevice::negotiate_features(device_specified_features),

View File

@ -119,7 +119,7 @@ bitflags! {
} }
bitflags! { bitflags! {
/// all device features, bits 0~23 are sepecified by device /// all device features, bits 0~23 and 50~63 are sepecified by device.
/// if using this struct to translate u64, use from_bits_truncate function instead of from_bits /// if using this struct to translate u64, use from_bits_truncate function instead of from_bits
/// ///
struct Feature: u64 { struct Feature: u64 {
@ -144,7 +144,7 @@ bitflags! {
#[derive(Debug, Default, Copy, Clone, Pod)] #[derive(Debug, Default, Copy, Clone, Pod)]
#[repr(C)] #[repr(C)]
pub struct VitrioPciCommonCfg { pub struct VirtioPciCommonCfg {
device_feature_select: u32, device_feature_select: u32,
device_feature: u32, device_feature: u32,
driver_feature_select: u32, driver_feature_select: u32,
@ -164,7 +164,7 @@ pub struct VitrioPciCommonCfg {
queue_device: u64, queue_device: u64,
} }
impl VitrioPciCommonCfg { impl VirtioPciCommonCfg {
pub(crate) fn new(cap: &CapabilityVirtioData, bars: [Option<BAR>; 6]) -> InFramePtr<Self> { pub(crate) fn new(cap: &CapabilityVirtioData, bars: [Option<BAR>; 6]) -> InFramePtr<Self> {
let bar = cap.bar; let bar = cap.bar;
let offset = cap.offset; let offset = cap.offset;
@ -219,7 +219,7 @@ impl VirtioDeviceType {
pub struct PCIVirtioDevice { pub struct PCIVirtioDevice {
/// common config of one device /// common config of one device
pub common_cfg: InFramePtr<VitrioPciCommonCfg>, pub common_cfg: InFramePtr<VirtioPciCommonCfg>,
pub device: VirtioDevice, pub device: VirtioDevice,
pub msix: MSIX, pub msix: MSIX,
} }
@ -269,35 +269,35 @@ impl PCIVirtioDevice {
let common_cfg_frame_ptr = &virtio_info.common_cfg_frame_ptr; let common_cfg_frame_ptr = &virtio_info.common_cfg_frame_ptr;
// Reset device // Reset device
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, device_status), 0 as u8); common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, device_status), 0 as u8);
let num_queues: u16 = let num_queues: u16 =
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, num_queues)); common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, num_queues));
debug!("num_queues:{:x}", num_queues); debug!("num_queues:{:x}", num_queues);
// the table size of msix should be equal to n+1 or 2 where n is the virtqueue amount // the table size of msix should be equal to n+1 or 2 where n is the virtqueue amount
assert!(msix.table_size == 2 || msix.table_size == (num_queues + 1)); assert!(msix.table_size == 2 || msix.table_size == (num_queues + 1));
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, config_msix_vector), offset_of!(VirtioPciCommonCfg, config_msix_vector),
config_msix_vector, config_msix_vector,
); );
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, device_status), offset_of!(VirtioPciCommonCfg, device_status),
(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER).bits(), (DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER).bits(),
); );
// negotiate features // negotiate features
// get the value of device features // get the value of device features
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, device_feature_select), offset_of!(VirtioPciCommonCfg, device_feature_select),
0 as u32, 0 as u32,
); );
let mut low: u32 = let mut low: u32 =
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, device_feature)); common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, device_feature));
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, device_feature_select), offset_of!(VirtioPciCommonCfg, device_feature_select),
1 as u32, 1 as u32,
); );
let mut high: u32 = let mut high: u32 =
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, device_feature)); common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, device_feature));
let mut feature = (high as u64) << 32; let mut feature = (high as u64) << 32;
feature |= low as u64; feature |= low as u64;
// let the device to negotiate Features // let the device to negotiate Features
@ -307,26 +307,26 @@ impl PCIVirtioDevice {
low = driver_features as u32; low = driver_features as u32;
high = (driver_features >> 32) as u32; high = (driver_features >> 32) as u32;
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, driver_feature_select), offset_of!(VirtioPciCommonCfg, driver_feature_select),
0 as u32, 0 as u32,
); );
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, driver_feature), low); common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, driver_feature), low);
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, driver_feature_select), offset_of!(VirtioPciCommonCfg, driver_feature_select),
1 as u32, 1 as u32,
); );
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, driver_feature), high); common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, driver_feature), high);
// change to features ok status // change to features ok status
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, device_status), offset_of!(VirtioPciCommonCfg, device_status),
(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER | DeviceStatus::FEATURES_OK).bits(), (DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER | DeviceStatus::FEATURES_OK).bits(),
); );
let device = VirtioDevice::new(&virtio_info, bars, msix_vector_list).unwrap(); let device = VirtioDevice::new(&virtio_info, bars, msix_vector_list).unwrap();
// change to driver ok status // change to driver ok status
common_cfg_frame_ptr.write_at( common_cfg_frame_ptr.write_at(
offset_of!(VitrioPciCommonCfg, device_status), offset_of!(VirtioPciCommonCfg, device_status),
(DeviceStatus::ACKNOWLEDGE (DeviceStatus::ACKNOWLEDGE
| DeviceStatus::DRIVER | DeviceStatus::DRIVER
| DeviceStatus::FEATURES_OK | DeviceStatus::FEATURES_OK
@ -351,7 +351,7 @@ impl PCIVirtioDevice {
{ {
let config_msix_vector = let config_msix_vector =
self.common_cfg self.common_cfg
.read_at(offset_of!(VitrioPciCommonCfg, config_msix_vector)) as usize; .read_at(offset_of!(VirtioPciCommonCfg, config_msix_vector)) as usize;
for i in 0..self.msix.table_size as usize { for i in 0..self.msix.table_size as usize {
let msix = self.msix.table.get_mut(i).unwrap(); let msix = self.msix.table.get_mut(i).unwrap();
if !msix.irq_handle.is_empty() { if !msix.irq_handle.is_empty() {

View File

@ -1,6 +1,6 @@
//! Virtqueue //! Virtqueue
use super::VitrioPciCommonCfg; use super::VirtioPciCommonCfg;
use alloc::vec::Vec; use alloc::vec::Vec;
use bitflags::bitflags; use bitflags::bitflags;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
@ -55,29 +55,29 @@ pub struct VirtQueue {
impl VirtQueue { impl VirtQueue {
/// Create a new VirtQueue. /// Create a new VirtQueue.
pub(crate) fn new( pub(crate) fn new(
cfg: &InFramePtr<VitrioPciCommonCfg>, cfg: &InFramePtr<VirtioPciCommonCfg>,
idx: usize, idx: usize,
size: u16, size: u16,
notify_base_address: usize, notify_base_address: usize,
notify_off_multiplier: u32, notify_off_multiplier: u32,
msix_vector: u16, msix_vector: u16,
) -> Result<Self, QueueError> { ) -> Result<Self, QueueError> {
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_select), idx as u16); cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_select), idx as u16);
assert_eq!( assert_eq!(
cfg.read_at(offset_of!(VitrioPciCommonCfg, queue_select)), cfg.read_at(offset_of!(VirtioPciCommonCfg, queue_select)),
idx as u16 idx as u16
); );
if !size.is_power_of_two() { if !size.is_power_of_two() {
return Err(QueueError::InvalidArgs); return Err(QueueError::InvalidArgs);
} }
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_size), size); cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_size), size);
cfg.write_at( cfg.write_at(
offset_of!(VitrioPciCommonCfg, queue_msix_vector), offset_of!(VirtioPciCommonCfg, queue_msix_vector),
msix_vector, msix_vector,
); );
assert_eq!( assert_eq!(
cfg.read_at(offset_of!(VitrioPciCommonCfg, queue_msix_vector)), cfg.read_at(offset_of!(VirtioPciCommonCfg, queue_msix_vector)),
msix_vector msix_vector
); );
@ -109,17 +109,17 @@ impl VirtQueue {
debug!("queue_device start paddr:{:x?}", used_frame_ptr.paddr()); debug!("queue_device start paddr:{:x?}", used_frame_ptr.paddr());
cfg.write_at( cfg.write_at(
offset_of!(VitrioPciCommonCfg, queue_desc), offset_of!(VirtioPciCommonCfg, queue_desc),
desc_frame_ptr.paddr() as u64, desc_frame_ptr.paddr() as u64,
); );
cfg.write_at( cfg.write_at(
offset_of!(VitrioPciCommonCfg, queue_driver), offset_of!(VirtioPciCommonCfg, queue_driver),
avail_frame_ptr.paddr() as u64, avail_frame_ptr.paddr() as u64,
); );
cfg.write_at( cfg.write_at(
offset_of!(VitrioPciCommonCfg, queue_device), offset_of!(VirtioPciCommonCfg, queue_device),
used_frame_ptr.paddr() as u64, used_frame_ptr.paddr() as u64,
); );
@ -137,7 +137,7 @@ impl VirtQueue {
temp.write_at(offset_of!(Descriptor, next), i + 1); temp.write_at(offset_of!(Descriptor, next), i + 1);
} }
avail_frame_ptr.write_at(offset_of!(AvailRing, flags), 0 as u16); avail_frame_ptr.write_at(offset_of!(AvailRing, flags), 0 as u16);
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_enable), 1 as u16); cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_enable), 1 as u16);
Ok(VirtQueue { Ok(VirtQueue {
descs, descs,
avail: avail_frame_ptr, avail: avail_frame_ptr,
@ -305,6 +305,14 @@ impl VirtQueue {
self.queue_size self.queue_size
} }
/// whether the driver should notify the device
pub fn should_notify(&self) -> bool {
// read barrier
fence(Ordering::SeqCst);
let flags = self.used.read_at(offset_of!(UsedRing, flags));
flags & 0x0001u16 == 0u16
}
/// notify that there are available rings /// notify that there are available rings
pub fn notify(&mut self) { pub fn notify(&mut self) {
self.notify self.notify

View File

@ -163,6 +163,7 @@ fn match_and_call(
} }
infos.sort(); infos.sort();
debug!("component infos: {infos:?}");
info!("Components initializing..."); info!("Components initializing...");
for i in infos { for i in infos {

View File

@ -24,6 +24,7 @@ virtio-input-decoder = "0.1.4"
ascii = { version = "1.1", default-features = false, features = ["alloc"] } ascii = { version = "1.1", default-features = false, features = ["alloc"] }
intrusive-collections = "0.9.5" intrusive-collections = "0.9.5"
time = { version = "0.3", default-features = false, features = ["alloc"] } time = { version = "0.3", default-features = false, features = ["alloc"] }
smoltcp = { version = "0.9.1", default-features = false, features = ["alloc", "log", "medium-ethernet", "medium-ip", "proto-dhcpv4", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw", "socket-dhcpv4"] }
# parse elf file # parse elf file
xmas-elf = "0.8.0" xmas-elf = "0.8.0"

View File

@ -2,6 +2,7 @@
use crate::events::Observer; use crate::events::Observer;
use crate::fs::utils::{AccessMode, IoEvents, IoctlCmd, Metadata, Poller, SeekFrom, StatusFlags}; use crate::fs::utils::{AccessMode, IoEvents, IoctlCmd, Metadata, Poller, SeekFrom, StatusFlags};
use crate::net::socket::Socket;
use crate::prelude::*; use crate::prelude::*;
use core::any::Any; use core::any::Any;
@ -67,6 +68,10 @@ pub trait FileLike: Send + Sync + Any {
) -> Result<Weak<dyn Observer<IoEvents>>> { ) -> Result<Weak<dyn Observer<IoEvents>>> {
return_errno_with_message!(Errno::EINVAL, "unregister_observer is not supported") return_errno_with_message!(Errno::EINVAL, "unregister_observer is not supported")
} }
fn as_socket(&self) -> Option<&dyn Socket> {
None
}
} }
impl dyn FileLike { impl dyn FileLike {

View File

@ -1,4 +1,5 @@
use crate::events::{Events, Observer, Subject}; use crate::events::{Events, Observer, Subject};
use crate::net::socket::Socket;
use crate::prelude::*; use crate::prelude::*;
use core::cell::Cell; use core::cell::Cell;
@ -101,6 +102,12 @@ impl FileTable {
.ok_or(Error::with_message(Errno::EBADF, "fd not exits")) .ok_or(Error::with_message(Errno::EBADF, "fd not exits"))
} }
pub fn get_socket(&self, sockfd: FileDescripter) -> Result<&dyn Socket> {
self.get_file(sockfd)?
.as_socket()
.ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the fd is not a socket"))
}
pub fn get_entry(&self, fd: FileDescripter) -> Result<&FileTableEntry> { pub fn get_entry(&self, fd: FileDescripter) -> Result<&FileTableEntry> {
self.table self.table
.get(fd as usize) .get(fd as usize)

View File

@ -8,6 +8,7 @@ use keyable_arc::KeyableWeak;
/// A pollee maintains a set of active events, which can be polled with /// A pollee maintains a set of active events, which can be polled with
/// pollers or be monitored with observers. /// pollers or be monitored with observers.
#[derive(Clone)]
pub struct Pollee { pub struct Pollee {
inner: Arc<PolleeInner>, inner: Arc<PolleeInner>,
} }

View File

@ -16,14 +16,17 @@
#![feature(specialization)] #![feature(specialization)]
#![feature(fn_traits)] #![feature(fn_traits)]
#![feature(linked_list_remove)] #![feature(linked_list_remove)]
#![feature(trait_alias)]
#![feature(register_tool)] #![feature(register_tool)]
#![feature(trait_upcasting)] #![feature(trait_upcasting)]
#![register_tool(component_access_control)] #![register_tool(component_access_control)]
use crate::{ use crate::{
prelude::*, prelude::*,
process::status::ProcessStatus,
thread::{kernel_thread::KernelThreadExt, Thread}, thread::{kernel_thread::KernelThreadExt, Thread},
}; };
use jinux_frame::exit_qemu;
use process::Process; use process::Process;
extern crate alloc; extern crate alloc;
@ -36,6 +39,7 @@ pub mod driver;
pub mod error; pub mod error;
pub mod events; pub mod events;
pub mod fs; pub mod fs;
pub mod net;
pub mod prelude; pub mod prelude;
mod process; mod process;
pub mod syscall; pub mod syscall;
@ -46,6 +50,7 @@ pub mod vm;
pub fn init(ramdisk: &[u8]) { pub fn init(ramdisk: &[u8]) {
driver::init(); driver::init();
net::init();
process::fifo_scheduler::init(); process::fifo_scheduler::init();
fs::initramfs::init(ramdisk).unwrap(); fs::initramfs::init(ramdisk).unwrap();
device::init().unwrap(); device::init().unwrap();
@ -56,6 +61,7 @@ fn init_thread() {
"[kernel] Spawn init thread, tid = {}", "[kernel] Spawn init thread, tid = {}",
current_thread!().tid() current_thread!().tid()
); );
net::lazy_init();
// driver::pci::virtio::block::block_device_test(); // driver::pci::virtio::block::block_device_test();
let thread = Thread::spawn_kernel_thread(|| { let thread = Thread::spawn_kernel_thread(|| {
println!("[kernel] Hello world from kernel!"); println!("[kernel] Hello world from kernel!");
@ -70,9 +76,14 @@ fn init_thread() {
); );
print_banner(); print_banner();
run_busybox().expect("run busybox fails"); let busybox = run_busybox().expect("run busybox fails");
loop { loop {
// If busybox becomes zombie, then exit qemu.
if *busybox.status().lock() == ProcessStatus::Zombie {
println!("Exit jinux.");
exit_qemu(jinux_frame::QemuExitCode::Success);
}
// We don't have preemptive scheduler now. // We don't have preemptive scheduler now.
// The long running init thread should yield its own execution to allow other tasks to go on. // The long running init thread should yield its own execution to allow other tasks to go on.
Thread::yield_now(); Thread::yield_now();

View File

@ -17,12 +17,13 @@ pub(crate) use core::any::Any;
pub(crate) use core::ffi::CStr; pub(crate) use core::ffi::CStr;
pub(crate) use int_to_c_enum::TryFromInt; pub(crate) use int_to_c_enum::TryFromInt;
pub(crate) use jinux_frame::config::PAGE_SIZE; pub(crate) use jinux_frame::config::PAGE_SIZE;
pub(crate) use jinux_frame::sync::{Mutex, MutexGuard}; // pub(crate) use jinux_frame::sync::{Mutex, MutexGuard};
pub(crate) use jinux_frame::vm::Vaddr; pub(crate) use jinux_frame::vm::Vaddr;
pub(crate) use jinux_frame::{print, println}; pub(crate) use jinux_frame::{print, println};
pub(crate) use log::{debug, error, info, trace, warn}; pub(crate) use log::{debug, error, info, trace, warn};
pub(crate) use pod::Pod; pub(crate) use pod::Pod;
pub(crate) use spin::RwLock; pub(crate) use spin::RwLock;
pub(crate) use spin::{Mutex, MutexGuard};
/// return current process /// return current process
#[macro_export] #[macro_export]

View File

@ -69,16 +69,30 @@ use crate::syscall::write::sys_write;
use crate::syscall::writev::sys_writev; use crate::syscall::writev::sys_writev;
use jinux_frame::cpu::UserContext; use jinux_frame::cpu::UserContext;
use self::accept::sys_accept;
use self::bind::sys_bind;
use self::connect::sys_connect;
use self::getpeername::sys_getpeername;
use self::getsockname::sys_getsockname;
use self::listen::sys_listen;
use self::pread64::sys_pread64; use self::pread64::sys_pread64;
use self::recvfrom::sys_recvfrom;
use self::sendto::sys_sendto;
use self::setsockopt::sys_setsockopt;
use self::shutdown::sys_shutdown;
use self::socket::sys_socket;
mod accept;
mod access; mod access;
mod arch_prctl; mod arch_prctl;
mod bind;
mod brk; mod brk;
mod chdir; mod chdir;
mod clock_gettime; mod clock_gettime;
mod clock_nanosleep; mod clock_nanosleep;
mod clone; mod clone;
mod close; mod close;
mod connect;
mod constants; mod constants;
mod dup; mod dup;
mod epoll; mod epoll;
@ -93,15 +107,18 @@ mod getdents64;
mod getegid; mod getegid;
mod geteuid; mod geteuid;
mod getgid; mod getgid;
mod getpeername;
mod getpgrp; mod getpgrp;
mod getpid; mod getpid;
mod getppid; mod getppid;
mod getsockname;
mod gettid; mod gettid;
mod gettimeofday; mod gettimeofday;
mod getuid; mod getuid;
mod ioctl; mod ioctl;
mod kill; mod kill;
mod link; mod link;
mod listen;
mod lseek; mod lseek;
mod madvise; mod madvise;
mod mkdir; mod mkdir;
@ -117,6 +134,7 @@ mod pread64;
mod prlimit64; mod prlimit64;
mod read; mod read;
mod readlink; mod readlink;
mod recvfrom;
mod rename; mod rename;
mod rmdir; mod rmdir;
mod rt_sigaction; mod rt_sigaction;
@ -124,9 +142,13 @@ mod rt_sigprocmask;
mod rt_sigreturn; mod rt_sigreturn;
mod sched_yield; mod sched_yield;
mod select; mod select;
mod sendto;
mod set_robust_list; mod set_robust_list;
mod set_tid_address; mod set_tid_address;
mod setpgid; mod setpgid;
mod setsockopt;
mod shutdown;
mod socket;
mod stat; mod stat;
mod symlink; mod symlink;
mod tgkill; mod tgkill;
@ -199,6 +221,17 @@ define_syscall_nums!(
SYS_DUP2 = 33, SYS_DUP2 = 33,
SYS_PAUSE = 34, SYS_PAUSE = 34,
SYS_GETPID = 39, SYS_GETPID = 39,
SYS_SOCKET = 41,
SYS_CONNECT = 42,
SYS_ACCEPT = 43,
SYS_SENDTO = 44,
SYS_RECVFROM = 45,
SYS_SHUTDOWN = 48,
SYS_BIND = 49,
SYS_LISTEN = 50,
SYS_GETSOCKNAME = 51,
SYS_GETPEERNAME = 52,
SYS_SETSOCKOPT = 54,
SYS_CLONE = 56, SYS_CLONE = 56,
SYS_FORK = 57, SYS_FORK = 57,
SYS_EXECVE = 59, SYS_EXECVE = 59,
@ -340,6 +373,17 @@ pub fn syscall_dispatch(
SYS_DUP2 => syscall_handler!(2, sys_dup2, args), SYS_DUP2 => syscall_handler!(2, sys_dup2, args),
SYS_PAUSE => syscall_handler!(0, sys_pause), SYS_PAUSE => syscall_handler!(0, sys_pause),
SYS_GETPID => syscall_handler!(0, sys_getpid), SYS_GETPID => syscall_handler!(0, sys_getpid),
SYS_SOCKET => syscall_handler!(3, sys_socket, args),
SYS_CONNECT => syscall_handler!(3, sys_connect, args),
SYS_ACCEPT => syscall_handler!(3, sys_accept, args),
SYS_SENDTO => syscall_handler!(6, sys_sendto, args),
SYS_RECVFROM => syscall_handler!(6, sys_recvfrom, args),
SYS_SHUTDOWN => syscall_handler!(2, sys_shutdown, args),
SYS_BIND => syscall_handler!(3, sys_bind, args),
SYS_LISTEN => syscall_handler!(2, sys_listen, args),
SYS_GETSOCKNAME => syscall_handler!(3, sys_getsockname, args),
SYS_GETPEERNAME => syscall_handler!(3, sys_getpeername, args),
SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args),
SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()), SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()),
SYS_FORK => syscall_handler!(0, sys_fork, context.clone()), SYS_FORK => syscall_handler!(0, sys_fork, context.clone()),
SYS_EXECVE => syscall_handler!(3, sys_execve, args, context), SYS_EXECVE => syscall_handler!(3, sys_execve, args, context),

View File

@ -1,5 +1,10 @@
use crate::prelude::*; use crate::{
net::socket::SocketAddr,
prelude::*,
util::net::{InAddr, SaFamily, SockAddr, SockAddrIn, SockAddrIn6, SockAddrUn},
};
use jinux_frame::vm::VmIo; use jinux_frame::vm::VmIo;
pub mod net;
/// copy bytes from user space of current process. The bytes len is the len of dest. /// copy bytes from user space of current process. The bytes len is the len of dest.
pub fn read_bytes_from_user(src: Vaddr, dest: &mut [u8]) -> Result<()> { pub fn read_bytes_from_user(src: Vaddr, dest: &mut [u8]) -> Result<()> {
@ -35,3 +40,51 @@ pub fn read_cstring_from_user(addr: Vaddr, max_len: usize) -> Result<CString> {
read_bytes_from_user(addr, &mut buffer)?; read_bytes_from_user(addr, &mut buffer)?;
Ok(CString::from(CStr::from_bytes_until_nul(&buffer)?)) Ok(CString::from(CStr::from_bytes_until_nul(&buffer)?))
} }
pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result<SocketAddr> {
debug_assert!(addr_len >= core::mem::size_of::<SockAddr>());
let sockaddr: SockAddr = read_val_from_user(addr)?;
let socket_addr = match sockaddr.sa_family()? {
SaFamily::AF_UNSPEC => {
return_errno_with_message!(Errno::EINVAL, "the socket addr family is unspecified")
}
SaFamily::AF_UNIX => {
debug_assert!(addr_len >= core::mem::size_of::<SockAddrUn>());
let sock_addr_un: SockAddrUn = read_val_from_user(addr)?;
todo!()
}
SaFamily::AF_INET => {
debug_assert!(addr_len >= core::mem::size_of::<SockAddrIn>());
let sock_addr_in: SockAddrIn = read_val_from_user(addr)?;
SocketAddr::from(sock_addr_in)
}
SaFamily::AF_INET6 => {
debug_assert!(addr_len >= core::mem::size_of::<SockAddrIn6>());
let sock_addr_in6: SockAddrIn6 = read_val_from_user(addr)?;
todo!()
}
_ => {
return_errno_with_message!(Errno::EAFNOSUPPORT, "cannot support address for the family")
}
};
Ok(socket_addr)
}
pub fn write_socket_addr_to_user(
socket_addr: &SocketAddr,
dest: Vaddr,
max_len: usize,
) -> Result<usize> {
match socket_addr {
SocketAddr::Unix => todo!(),
SocketAddr::IPv4(addr, port) => {
let in_addr = InAddr::from(*addr);
let sock_addr_in = SockAddrIn::new(*port, in_addr);
let write_size = core::mem::size_of::<SockAddrIn>();
debug_assert!(max_len >= write_size);
write_val_to_user(dest, &sock_addr_in)?;
Ok(write_size)
}
SocketAddr::IPv6 => todo!(),
}
}

View File

@ -1,5 +1,6 @@
extern crate alloc; extern crate alloc;
use core::fmt::Debug;
use core::marker::PhantomData; use core::marker::PhantomData;
use alloc::sync::Arc; use alloc::sync::Arc;
@ -16,15 +17,30 @@ enum InFramePtrAccessMethod {
VmFrame(Arc<VmFrame>), VmFrame(Arc<VmFrame>),
} }
impl InFramePtrAccessMethod {
fn read_val<T: Pod>(&self, offset: usize) -> Result<T> {
match self {
InFramePtrAccessMethod::Mmio(mmio) => mmio.read_val(offset),
InFramePtrAccessMethod::VmFrame(frame) => frame.read_val(offset),
}
}
}
/// An in-frame pointer to a POD value, enabling safe access /// An in-frame pointer to a POD value, enabling safe access
/// to a POD value given its physical memory address. /// to a POD value given its physical memory address.
#[derive(Debug)]
pub struct InFramePtr<T: 'static> { pub struct InFramePtr<T: 'static> {
access_method: InFramePtrAccessMethod, access_method: InFramePtrAccessMethod,
offset: usize, offset: usize,
marker: PhantomData<&'static mut T>, marker: PhantomData<&'static mut T>,
} }
impl<T: Debug + Pod + 'static> Debug for InFramePtr<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let inner = self.access_method.read_val::<T>(self.offset).unwrap();
f.write_fmt(format_args!("{:?}", inner))
}
}
impl<T: Pod> InFramePtr<T> { impl<T: Pod> InFramePtr<T> {
/// This function only allow the physical address in the MMIO region. /// This function only allow the physical address in the MMIO region.
/// ///
@ -49,6 +65,12 @@ impl<T: Pod> InFramePtr<T> {
}) })
} }
pub fn read(&self) -> T {
self.access_method
.read_val::<T>(self.offset)
.expect("read inner from frame failed")
}
pub fn read_at<F: Pod>(&self, offset: *const F) -> F { pub fn read_at<F: Pod>(&self, offset: *const F) -> F {
match &self.access_method { match &self.access_method {
InFramePtrAccessMethod::Mmio(mmio) => mmio InFramePtrAccessMethod::Mmio(mmio) => mmio