Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

网络socket的系统调用接口。 #247

Merged
merged 39 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
86d1fe5
键盘扫描码
guanjinquan Mar 18, 2023
0c463f0
Merge branch 'master' into keyboard_code_translater
guanjinquan Mar 18, 2023
bf0e4ca
新增SystemError枚举类型,使得错误处理更清晰
fslongjin Mar 18, 2023
44ee41f
Merge branch 'master' into keyboard_code_translater
guanjinquan Mar 18, 2023
1c35917
Merge branch 'master' into patch-add-network-stack-support
fslongjin Mar 19, 2023
2409530
按规范修改返回值
guanjinquan Mar 19, 2023
026dde0
修补
guanjinquan Mar 19, 2023
59898cb
存在问题:无法为VirtioNICDriver实现Driver Trait
fslongjin Mar 20, 2023
d3c7a16
更改返回值以及错误码
fslongjin Mar 20, 2023
dda778b
手动为VirtioNICDriver实现send和sync
fslongjin Mar 20, 2023
e79149c
修补
guanjinquan Mar 20, 2023
adf2fa9
Merge branch 'keyboard_code_translater' of github.com:guanjinquan/Dra…
guanjinquan Mar 20, 2023
729b74f
修补
guanjinquan Mar 20, 2023
2eb6be0
完成smoltcp的phy层配置
fslongjin Mar 20, 2023
6337a00
raw socket
fslongjin Mar 21, 2023
849dc45
Merge branch 'patch-add-network-stack-support' of github.com:guanjinq…
guanjinquan Mar 22, 2023
f746d93
格式化代码
guanjinquan Mar 27, 2023
d93a232
初步写完udp和tcp socket
guanjinquan Mar 27, 2023
fb8f350
尝试通过 dhcp socket 获取 虚拟机ip地址
guanjinquan Apr 1, 2023
0013e3e
Merge branch 'master' into patch-add-0.1.6-changelog
fslongjin Apr 3, 2023
dbdb0f2
1
fslongjin Apr 3, 2023
45f6f33
修改virtio-drivers版本,使得dhcp能正常运行
fslongjin Apr 3, 2023
07418cc
修改获取网卡设备的方法(目前有双重加锁问题
fslongjin Apr 5, 2023
b57d5dd
Merge branch 'master' into patch-add-network-stack-support
fslongjin Apr 7, 2023
1c404d1
Merge branch 'master' into patch-add-network-stack-support
fslongjin Apr 10, 2023
a09554c
能够正常通过dhcp获取ipv4地址(具有全局iface btree)
fslongjin Apr 10, 2023
31d8953
format the code
fslongjin Apr 10, 2023
42ea3b5
修改
fslongjin Apr 10, 2023
635f5d9
1
fslongjin Apr 10, 2023
d891d83
删除time的只能在std下运行的代码
fslongjin Apr 10, 2023
1114e9c
Merge branch 'master' into patch-add-network-stack-support
fslongjin Apr 13, 2023
5219a61
1.修复spinlock忘记恢复rflags的问题
fslongjin Apr 13, 2023
cf529b0
声明系统调用
fslongjin Apr 15, 2023
4daeca7
Merge branch 'master' into patch-add-network-stack-support
fslongjin Apr 16, 2023
4df0070
1.把PollStatus结构体改为使用bitflags
fslongjin Apr 17, 2023
d287992
调通udp、tcp
fslongjin Apr 18, 2023
7e47761
调通tcp 的send、udp的send
fslongjin Apr 19, 2023
87e5e28
修复网络系统调用里面,由于返回i32导致C代码无法获得正确的错误码的问题
fslongjin Apr 19, 2023
45f6cd0
在bootstrap里面添加dnsmasq bridge-utils iptables
fslongjin Apr 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
!.gitkeep
DragonOS.iso
.idea/
/tmp/
kernel/kernel
.DS_Store

Expand Down
4 changes: 1 addition & 3 deletions kernel/src/driver/disk/ahci/ahci_inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ impl IndexNode for LockedAhciInode {
}

fn poll(&self) -> Result<PollStatus, SystemError> {
return Ok(PollStatus {
flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
});
return Ok(PollStatus::READ | PollStatus::WRITE);
}

/// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/driver/keyboard/ps2_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
}

fn poll(&self) -> Result<PollStatus, SystemError> {
return Ok(PollStatus {
flags: PollStatus::READ_MASK,
});
return Ok(PollStatus::READ);
}

fn metadata(&self) -> Result<Metadata, SystemError> {
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/driver/net/virtio_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use virtio_drivers::{device::net::VirtIONet, transport::Transport};

use crate::{
driver::{virtio::virtio_impl::HalImpl, Driver},
kdebug, kerror, kinfo,
kerror, kinfo,
libs::spinlock::SpinLock,
net::{generate_iface_id, NET_DRIVERS},
syscall::SystemError,
Expand Down
5 changes: 3 additions & 2 deletions kernel/src/exception/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
printk_color(RED, BLACK, "CR2:%#018lx\n", cr2);

traceback(regs);
current_pcb->state = PROC_STOPPED;
sched();
process_do_exit(-1);
// current_pcb->state = PROC_STOPPED;
// sched();
}

// 15 Intel保留,请勿使用
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/filesystem/devfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,7 @@ impl IndexNode for LockedDevFSInode {
return Err(SystemError::EISDIR);
}

return Ok(PollStatus {
flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
});
return Ok(PollStatus::READ | PollStatus::WRITE);
}

/// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/filesystem/devfs/null_dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ impl IndexNode for LockedNullInode {
}

fn poll(&self) -> Result<PollStatus, SystemError> {
return Ok(PollStatus {
flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
});
return Ok(PollStatus::READ | PollStatus::WRITE);
}

/// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/filesystem/devfs/zero_dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ impl IndexNode for LockedZeroInode {
}

fn poll(&self) -> Result<PollStatus, SystemError> {
return Ok(PollStatus {
flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
});
return Ok(PollStatus::READ | PollStatus::WRITE);
}

/// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/filesystem/fat/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,9 +1411,7 @@ impl IndexNode for LockedFATInode {
return Err(SystemError::EISDIR);
}

return Ok(PollStatus {
flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
});
return Ok(PollStatus::READ | PollStatus::WRITE);
}

fn create(
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/filesystem/procfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,7 @@ impl IndexNode for LockedProcFSInode {
return Err(SystemError::EISDIR);
}

return Ok(PollStatus {
flags: PollStatus::READ_MASK,
});
return Ok(PollStatus::READ);
}

fn fs(&self) -> Arc<dyn FileSystem> {
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/filesystem/ramfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ impl IndexNode for LockedRamFSInode {
return Err(SystemError::EISDIR);
}

return Ok(PollStatus {
flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
});
return Ok(PollStatus::READ | PollStatus::WRITE);
}

fn fs(&self) -> Arc<dyn FileSystem> {
Expand Down
6 changes: 6 additions & 0 deletions kernel/src/filesystem/vfs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ impl File {

return Some(res);
}

/// @brief 获取文件的类型
#[inline]
pub fn file_type(&self) -> FileType {
return self.file_type;
}
}

impl Drop for File {
Expand Down
51 changes: 39 additions & 12 deletions kernel/src/filesystem/vfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
pub mod core;
pub mod file;
pub mod mount;
mod syscall;
pub mod syscall;
mod utils;

use ::core::{any::Any, fmt::Debug};

use alloc::{string::String, sync::Arc, vec::Vec};

use crate::{syscall::SystemError, time::TimeSpec};
use crate::{libs::casting::DowncastArc, syscall::SystemError, time::TimeSpec};

use self::{core::generate_inode_id, file::FileMode};
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
Expand All @@ -36,6 +36,8 @@ pub enum FileType {
Pipe,
/// 符号链接
SymLink,
/// 套接字
Socket,
}

/* these are defined by POSIX and also present in glibc's dirent.h */
Expand Down Expand Up @@ -68,20 +70,18 @@ impl FileType {
FileType::CharDevice => DT_CHR,
FileType::Pipe => DT_FIFO,
FileType::SymLink => DT_LNK,
FileType::Socket => DT_SOCK,
};
}
}

/// @brief inode的状态(由poll方法返回)
#[derive(Debug, Default, PartialEq)]
pub struct PollStatus {
pub flags: u8,
}

impl PollStatus {
pub const WRITE_MASK: u8 = (1u8 << 0);
pub const READ_MASK: u8 = (1u8 << 1);
pub const ERR_MASK: u8 = (1u8 << 2);
bitflags! {
/// @brief inode的状态(由poll方法返回)
pub struct PollStatus: u8 {
const WRITE = 1u8 << 0;
const READ = 1u8 << 1;
const ERROR = 1u8 << 2;
}
}

pub trait IndexNode: Any + Sync + Send + Debug {
Expand Down Expand Up @@ -336,6 +336,12 @@ pub trait IndexNode: Any + Sync + Send + Debug {
}
}

impl DowncastArc for dyn IndexNode {
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
self
}
}

impl dyn IndexNode {
/// @brief 将当前Inode转换为一个具体的结构体(类型由T指定)
/// 如果类型正确,则返回Some,否则返回None
Expand Down Expand Up @@ -482,6 +488,27 @@ pub struct Metadata {
pub raw_dev: usize,
}

impl Default for Metadata {
fn default() -> Self {
return Self {
dev_id: 0,
inode_id: 0,
size: 0,
blk_size: 0,
blocks: 0,
atime: TimeSpec::default(),
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::File,
mode: 0,
nlinks: 1,
uid: 0,
gid: 0,
raw_dev: 0,
};
}
}

/// @brief 所有文件系统都应该实现的trait
pub trait FileSystem: Any + Sync + Send + Debug {
/// @brief 获取当前文件系统的root inode的指针
Expand Down
105 changes: 104 additions & 1 deletion kernel/src/filesystem/vfs/syscall.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::ffi::{c_char, CStr};

use alloc::{boxed::Box, string::ToString};
use alloc::{boxed::Box, string::ToString, vec::Vec};

use crate::{
arch::asm::{current::current_pcb, ptrace::user_mode},
Expand Down Expand Up @@ -435,3 +435,106 @@ pub extern "C" fn sys_dup2(regs: &pt_regs) -> u64 {
return r.unwrap_err().to_posix_errno() as u64;
}
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct IoVec {
/// 缓冲区的起始地址
pub iov_base: *mut u8,
/// 缓冲区的长度
pub iov_len: usize,
}

/// 用于存储多个来自用户空间的IoVec
///
/// 由于目前内核中的文件系统还不支持分散读写,所以暂时只支持将用户空间的IoVec聚合成一个缓冲区,然后进行操作。
/// TODO:支持分散读写
#[derive(Debug)]
pub struct IoVecs(Vec<&'static mut [u8]>);

impl IoVecs {
/// 从用户空间的IoVec中构造IoVecs
///
/// @param iov 用户空间的IoVec
/// @param iovcnt 用户空间的IoVec的数量
/// @param readv 是否为readv系统调用
///
/// @return 构造成功返回IoVecs,否则返回错误码
pub unsafe fn from_user(
iov: *const IoVec,
iovcnt: usize,
_readv: bool,
) -> Result<Self, SystemError> {
// 检查iov指针所在空间是否合法
if !verify_area(
iov as usize as u64,
(iovcnt * core::mem::size_of::<IoVec>()) as u64,
) {
return Err(SystemError::EFAULT);
}

// 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放)
let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt);

let mut slices: Vec<&mut [u8]> = vec![];
slices.reserve(iovs.len());

for iov in iovs.iter() {
if iov.iov_len == 0 {
continue;
}

if !verify_area(iov.iov_base as usize as u64, iov.iov_len as u64) {
return Err(SystemError::EFAULT);
}

slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len));
}

return Ok(Self(slices));
}

/// @brief 将IoVecs中的数据聚合到一个缓冲区中
///
/// @return 返回聚合后的缓冲区
pub fn gather(&self) -> Vec<u8> {
let mut buf = Vec::new();
for slice in self.0.iter() {
buf.extend_from_slice(slice);
}
return buf;
}

/// @brief 将给定的数据分散写入到IoVecs中
pub fn scatter(&mut self, data: &[u8]) {
let mut data: &[u8] = data;
for slice in self.0.iter_mut() {
let len = core::cmp::min(slice.len(), data.len());
if len == 0 {
continue;
}

slice[..len].copy_from_slice(&data[..len]);
data = &data[len..];
}
}

/// @brief 创建与IoVecs等长的缓冲区
///
/// @param set_len 是否设置返回的Vec的len。
/// 如果为true,则返回的Vec的len为所有IoVec的长度之和;
/// 否则返回的Vec的len为0,capacity为所有IoVec的长度之和.
///
/// @return 返回创建的缓冲区
pub fn new_buf(&self, set_len: bool) -> Vec<u8> {
let total_len: usize = self.0.iter().map(|slice| slice.len()).sum();
let mut buf: Vec<u8> = Vec::with_capacity(total_len);

if set_len {
unsafe {
buf.set_len(total_len);
}
}
return buf;
}
}
6 changes: 5 additions & 1 deletion kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(panic_info_message)]
#![feature(drain_filter)] // 允许Vec的drain_filter特性
#![feature(c_void_variant)]
#![feature(trait_upcasting)]
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
Expand Down Expand Up @@ -99,6 +100,9 @@ pub fn panic(info: &PanicInfo) -> ! {
#[no_mangle]
pub extern "C" fn __rust_demo_func() -> i32 {
printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
net_init().expect("Failed to init network");
let r = net_init();
if r.is_err() {
kwarn!("net_init() failed: {:?}", r.err().unwrap());
}
return 0;
}
2 changes: 1 addition & 1 deletion kernel/src/libs/casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use alloc::sync::Arc;
/// assert!(a_arc2.is_some());
/// }
/// ```
trait DowncastArc: Any + Send + Sync {
pub trait DowncastArc: Any + Send + Sync {
/// 请在具体类型中实现这个函数,返回self
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any>;

Expand Down
6 changes: 5 additions & 1 deletion kernel/src/libs/spinlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ impl<T> DerefMut for SpinLockGuard<'_, T> {
/// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况
impl<T> Drop for SpinLockGuard<'_, T> {
fn drop(&mut self) {
self.lock.lock.unlock();
if self.flag != 0 {
self.lock.lock.unlock_irqrestore(&self.flag);
} else {
self.lock.lock.unlock();
}
}
}