Browse Source

merge upstream

val213 5 months ago
parent
commit
b9f04fc3a4
54 changed files with 1265 additions and 350 deletions
  1. 8 8
      .github/workflows/makefile.yml
  2. 109 0
      docs/kernel/boot/cmdline.md
  3. 1 2
      docs/kernel/boot/index.rst
  4. 1 0
      kernel/Cargo.toml
  5. 6 0
      kernel/crates/kcmdline_macros/Cargo.toml
  6. 74 0
      kernel/crates/kcmdline_macros/src/lib.rs
  7. 11 1
      kernel/crates/rust-slabmalloc/src/lib.rs
  8. 14 0
      kernel/crates/rust-slabmalloc/src/pages.rs
  9. 30 4
      kernel/crates/rust-slabmalloc/src/sc.rs
  10. 9 12
      kernel/crates/rust-slabmalloc/src/zone.rs
  11. 1 1
      kernel/src/arch/x86_64/syscall/mod.rs
  12. 18 15
      kernel/src/driver/net/mod.rs
  13. 1 1
      kernel/src/driver/net/virtio_net.rs
  14. 29 5
      kernel/src/driver/serial/serial8250/serial8250_pio.rs
  15. 0 2
      kernel/src/driver/tty/sysfs.rs
  16. 1 7
      kernel/src/driver/tty/termios.rs
  17. 57 2
      kernel/src/driver/tty/tty_core.rs
  18. 6 1
      kernel/src/driver/tty/tty_port.rs
  19. 1 50
      kernel/src/driver/tty/virtual_terminal/mod.rs
  20. 7 12
      kernel/src/driver/tty/virtual_terminal/virtual_console.rs
  21. 2 2
      kernel/src/filesystem/eventfd.rs
  22. 19 12
      kernel/src/filesystem/vfs/core.rs
  23. 9 0
      kernel/src/filesystem/vfs/mount.rs
  24. 8 8
      kernel/src/init/boot.rs
  25. 476 0
      kernel/src/init/cmdline.rs
  26. 19 4
      kernel/src/init/init.rs
  27. 61 16
      kernel/src/init/initial_kthread.rs
  28. 1 0
      kernel/src/init/mod.rs
  29. 2 2
      kernel/src/ipc/pipe.rs
  30. 2 1
      kernel/src/lib.rs
  31. 1 2
      kernel/src/libs/lib_ui/textui.rs
  32. 1 1
      kernel/src/mm/allocator/kernel_allocator.rs
  33. 15 1
      kernel/src/mm/allocator/slab.rs
  34. 35 26
      kernel/src/net/event_poll/mod.rs
  35. 2 3
      kernel/src/net/socket/buffer.rs
  36. 1 1
      kernel/src/net/socket/inet/common/mod.rs
  37. 15 5
      kernel/src/net/socket/inet/stream/inner.rs
  38. 16 7
      kernel/src/net/socket/inet/stream/mod.rs
  39. 1 1
      kernel/src/net/socket/inet/syscall.rs
  40. 1 1
      kernel/src/net/socket/unix/mod.rs
  41. 3 7
      kernel/src/net/socket/unix/seqpacket/inner.rs
  42. 6 10
      kernel/src/net/socket/unix/seqpacket/mod.rs
  43. 1 4
      kernel/src/net/socket/unix/stream/mod.rs
  44. 8 8
      kernel/src/net/syscall.rs
  45. 1 1
      kernel/src/net/syscall_util.rs
  46. 1 1
      tools/BUILD_CONTAINER_VERSION
  47. 1 0
      tools/bootstrap.sh
  48. 1 2
      tools/write_disk_image.sh
  49. 1 1
      user/apps/ping/src/ping.rs
  50. 22 6
      user/apps/test-uevent/src/main.rs
  51. 3 3
      user/apps/test_seqpacket/src/main.rs
  52. 5 4
      user/apps/test_seqpacket/src/seq_pair.rs
  53. 95 69
      user/apps/test_seqpacket/src/seq_socket.rs
  54. 46 18
      user/apps/test_unix_stream_socket/src/main.rs

+ 8 - 8
.github/workflows/makefile.yml

@@ -12,14 +12,14 @@ jobs:
     name: Format check ${{ matrix.arch }}
     runs-on: ubuntu-latest
     continue-on-error: true
-    container: dragonos/dragonos-dev:v1.3
+    container: dragonos/dragonos-dev:v1.4
 
     strategy:
       matrix:
         arch: [x86_64, riscv64]
 
     steps:
-    - run: echo "Running in dragonos/dragonos-dev:v1.3"
+    - run: echo "Running in dragonos/dragonos-dev:v1.4"
     - uses: actions/checkout@v3
 
     - name: Format check
@@ -35,14 +35,14 @@ jobs:
     name: Kernel static test ${{ matrix.arch }}
     runs-on: ubuntu-latest
     continue-on-error: true
-    container: dragonos/dragonos-dev:v1.3
+    container: dragonos/dragonos-dev:v1.4
 
     strategy:
       matrix:
         arch: [x86_64, riscv64]
 
     steps:
-    - run: echo "Running in dragonos/dragonos-dev:v1.3"
+    - run: echo "Running in dragonos/dragonos-dev:v1.4"
 
     - uses: actions/checkout@v3
 
@@ -56,10 +56,10 @@ jobs:
   build-x86_64:
 
     runs-on: ubuntu-latest
-    container: dragonos/dragonos-dev:v1.3
+    container: dragonos/dragonos-dev:v1.4
 
     steps:
-    - run: echo "Running in dragonos/dragonos-dev:v1.3"
+    - run: echo "Running in dragonos/dragonos-dev:v1.4"
 
     - uses: actions/checkout@v3
     - name: build the DragonOS
@@ -78,10 +78,10 @@ jobs:
   build-riscv64:
 
     runs-on: ubuntu-latest
-    container: dragonos/dragonos-dev:v1.3
+    container: dragonos/dragonos-dev:v1.4
 
     steps:
-    - run: echo "Running in dragonos/dragonos-dev:v1.3"
+    - run: echo "Running in dragonos/dragonos-dev:v1.4"
 
     - uses: actions/checkout@v3
       with:

+ 109 - 0
docs/kernel/boot/cmdline.md

@@ -0,0 +1,109 @@
+# 内核启动命令行参数
+
+:::{note}
+本文作者: 
+- 龙进 <[email protected]>
+:::
+
+## 概述
+
+&emsp;&emsp;DragonOS内核启动命令行参数解析模块旨在提供类似Linux的内核启动命令行参数解析支持,以便更灵活地让内核执行不同的行为。该模块允许内核在启动时接收并解析命令行参数,根据参数的不同类型执行相应的回调函数或设置环境变量。
+
+:::{note}
+暂时不支持设置回调函数
+:::
+
+## 设计方案
+
+
+### 参数类型
+
+内核启动命令行参数分为三种类型:
+
+- Arg类型
+- KV类型
+- EarlyKV类型
+
+#### Arg类型
+
+Arg类型的参数在命令行中只有名称,没有值。分为以下两种类型:
+
+- ArgNormal:默认值为`false`,如果命令行中包含这个参数,则会设置为`true`。
+- ArgInv:默认值为`true`,如果命令行中包含这个参数,则会设置为`false`。
+
+#### KV类型
+
+KV类型的参数在命令行中表现为`name=value`,`value`按照逗号分隔。内核模块可提供参数的默认值。
+
+#### EarlyKV类型
+
+EarlyKV类型的参数与KV类型类似,但它们在内存管理初始化之前被解析。
+
+### Module标志
+
+Module标志类似于`usbprobe.xxxx`。
+
+### 参数声明
+提供宏来声明内核命令行参数。
+### procfs支持
+
+:::{note}
+TODO: 在`/proc/cmdline`下显示当前内核的启动命令行参数。
+:::
+
+## 声明内核启动命令行参数的宏
+
+### Arg类型参数声明
+```rust
+kernel_cmdline_param_arg!(varname, name, default_bool, inv);
+```
+- `varname`:参数的变量名
+- `name`:参数的名称
+- `default_bool`:默认值
+- `inv`:是否反转
+
+### KV类型参数声明
+
+```rust
+kernel_cmdline_param_kv!(varname, name, default_str);
+```
+
+- `varname`:参数的变量名
+- `name`:参数的名称
+- `default_str`:默认值
+
+### 内存管理初始化之前的KV类型参数声明
+
+```rust
+kernel_cmdline_param_early_kv!(varname, name, default_str);
+```
+
+- `varname`:参数的变量名
+- `name`:参数的名称
+- `default_str`:默认值
+
+## 示例
+
+以下示例展示了如何声明和使用KV类型参数:
+```rust
+kernel_cmdline_param_kv!(ROOTFS_PATH_PARAM, root, "");
+if let Some(rootfs_dev_path) = ROOTFS_PATH_PARAM.value_str() {
+    .......
+} else {
+    .......
+};
+```
+
+### 使用方式
+
+1. 在内核代码中,使用`kernel_cmdline_param_kv!`宏声明所需的KV类型参数。
+2. 在内核初始化过程中,通过参数的`value_str()`或者`value_bool()`方法获取参数值。
+3. 根据参数值执行相应的操作。
+
+通过以上步骤,开发者可以灵活地使用内核启动命令行参数来控制内核行为。
+
+
+## TODO
+
+- 支持在`/proc/cmdline`下显示当前内核的启动命令行参数。(需要在procfs重构后)
+- 支持设置回调函数,调用回调函数来设置参数值

+ 1 - 2
docs/kernel/boot/index.rst

@@ -1,10 +1,9 @@
 引导加载
 ====================================
-
-   DragonOS采用GRUB2作为其引导加载程序,支持Multiboot2协议引导。目前仅支持GRUB2.06版本。
    
 .. toctree::
    :maxdepth: 1
    :caption: 目录
 
    bootloader
+   cmdline

+ 1 - 0
kernel/Cargo.toml

@@ -41,6 +41,7 @@ fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev
 hashbrown = "=0.13.2"
 ida = { path = "crates/ida" }
 intertrait = { path = "crates/intertrait" }
+kcmdline_macros = { path = "crates/kcmdline_macros" }
 kdepends = { path = "crates/kdepends" }
 klog_types = { path = "crates/klog_types" }
 linkme = "=0.3.27"

+ 6 - 0
kernel/crates/kcmdline_macros/Cargo.toml

@@ -0,0 +1,6 @@
+[package]
+name = "kcmdline_macros"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]

+ 74 - 0
kernel/crates/kcmdline_macros/src/lib.rs

@@ -0,0 +1,74 @@
+#![no_std]
+#![deny(clippy::all)]
+#![allow(clippy::crate_in_macro_def)]
+
+/// 定义一个bool类型的参数
+///
+/// # 参数
+///
+/// - `$varname`: 参数的变量名
+/// - `$name`: 参数的名称
+/// - `$default_bool`: 默认值
+/// - `$inv`: 是否反转
+#[macro_export]
+macro_rules! kernel_cmdline_param_arg {
+    ($varname:ident, $name:ident, $default_bool:expr, $inv:expr) => {
+        #[::linkme::distributed_slice(crate::init::cmdline::KCMDLINE_PARAM_ARG)]
+        static $varname: crate::init::cmdline::KernelCmdlineParameter =
+            crate::init::cmdline::KernelCmdlineParamBuilder::new(
+                stringify!($name),
+                crate::init::cmdline::KCmdlineParamType::Arg,
+            )
+            .default_bool($default_bool)
+            .inv($inv)
+            .build()
+            .unwrap();
+    };
+}
+
+/// 定义一个key-value类型的参数
+///
+/// # 参数
+/// - `$varname`: 参数的变量名
+/// - `$name`: 参数的名称
+/// - `$default_str`: 默认值
+#[macro_export]
+macro_rules! kernel_cmdline_param_kv {
+    ($varname:ident, $name:ident, $default_str:expr) => {
+        #[::linkme::distributed_slice(crate::init::cmdline::KCMDLINE_PARAM_KV)]
+        static $varname: crate::init::cmdline::KernelCmdlineParameter =
+            crate::init::cmdline::KernelCmdlineParamBuilder::new(
+                stringify!($name),
+                crate::init::cmdline::KCmdlineParamType::KV,
+            )
+            .default_str($default_str)
+            .build()
+            .unwrap();
+    };
+}
+
+/// 定义一个内存管理初始化之前就要设置的key-value类型的参数
+///
+/// # 参数
+/// - `$varname`: 参数的变量名
+/// - `$name`: 参数的名称
+/// - `$default_str`: 默认值
+#[macro_export]
+macro_rules! kernel_cmdline_param_early_kv {
+    ($varname:ident, $name:ident, $default_str:expr) => {
+        #[::linkme::distributed_slice(crate::init::cmdline::KCMDLINE_PARAM_EARLY_KV)]
+        static $varname: crate::init::cmdline::KernelCmdlineParameter = {
+            static ___KV: crate::init::cmdline::KernelCmdlineEarlyKV = {
+                const { assert!($default_str.len() < KernelCmdlineEarlyKV::VALUE_MAX_LEN) };
+                crate::init::cmdline::KernelCmdlineParamBuilder::new(
+                    stringify!($name),
+                    crate::init::cmdline::KCmdlineParamType::EarlyKV,
+                )
+                .default_str($default_str)
+                .build_early_kv()
+                .unwrap()
+            };
+            crate::init::cmdline::KernelCmdlineParameter::EarlyKV(&___KV)
+        };
+    };
+}

+ 11 - 1
kernel/crates/rust-slabmalloc/src/lib.rs

@@ -65,7 +65,12 @@ pub enum AllocationError {
 /// Needs to adhere to safety requirements of a rust allocator (see GlobalAlloc et. al.).
 pub unsafe trait Allocator<'a> {
     fn allocate(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocationError>;
-    fn deallocate(&mut self, ptr: NonNull<u8>, layout: Layout) -> Result<(), AllocationError>;
+    unsafe fn deallocate(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        slab_callback: &'static dyn CallBack,
+    ) -> Result<(), AllocationError>;
 
     /// Refill the allocator with a [`ObjectPage`].
     ///
@@ -77,3 +82,8 @@ pub unsafe trait Allocator<'a> {
         new_page: &'a mut ObjectPage<'a>,
     ) -> Result<(), AllocationError>;
 }
+
+/// 将slab_page归还Buddy的回调函数
+pub trait CallBack: Send + Sync {
+    unsafe fn free_slab_page(&self, _: *mut u8, _: usize) {}
+}

+ 14 - 0
kernel/crates/rust-slabmalloc/src/pages.rs

@@ -255,6 +255,20 @@ pub trait AllocablePage {
         self.bitfield().clear_bit(idx);
         Ok(())
     }
+
+    /// 统计page中还可以分配多少个object
+    fn free_obj_count(&self) -> usize {
+        // 统计page中还可以分配多少个object
+        let mut free_obj_count = 0;
+
+        // 遍历page中的bitfield(用来统计内存分配情况的u64数组)
+        for b in self.bitfield().iter() {
+            let bitval = b.load(Ordering::Relaxed);
+            free_obj_count += bitval.count_zeros() as usize;
+        }
+
+        free_obj_count
+    }
 }
 
 /// Holds allocated data within a 4 KiB page.

+ 30 - 4
kernel/crates/rust-slabmalloc/src/sc.rs

@@ -59,21 +59,29 @@ pub struct SCAllocator<'a, P: AllocablePage> {
     pub(crate) slabs: PageList<'a, P>,
     /// List of full ObjectPages (everything allocated in these don't need to search them).
     pub(crate) full_slabs: PageList<'a, P>,
+    /// Free objects count
+    pub(crate) free_obj_count: usize,
+    /// Maximum free objects num for this `SCAllocator`.
+    pub(crate) free_limit: usize,
 }
 
 /// Creates an instance of a scallocator, we do this in a macro because we
 /// re-use the code in const and non-const functions
 macro_rules! new_sc_allocator {
-    ($size:expr) => {
+    ($size:expr) => {{
+        let obj_per_page = cmin((P::SIZE - OBJECT_PAGE_METADATA_OVERHEAD) / $size, 8 * 64);
         SCAllocator {
             size: $size,
             allocation_count: 0,
-            obj_per_page: cmin((P::SIZE - OBJECT_PAGE_METADATA_OVERHEAD) / $size, 8 * 64),
+            obj_per_page,
             empty_slabs: PageList::new(),
             slabs: PageList::new(),
             full_slabs: PageList::new(),
+            // TODO: 优化free_limit的计算: https://bbs.dragonos.org.cn/t/topic/358
+            free_limit: 2 * obj_per_page,
+            free_obj_count: 0,
         }
-    };
+    }};
 }
 
 impl<'a, P: AllocablePage> SCAllocator<'a, P> {
@@ -241,6 +249,7 @@ impl<'a, P: AllocablePage> SCAllocator<'a, P> {
         *page.next() = Rawlink::none();
         trace!("adding page to SCAllocator {:p}", page);
         self.insert_empty(page);
+        self.free_obj_count += self.obj_per_page;
     }
 
     /// Allocates a block of memory descriped by `layout`.
@@ -294,6 +303,7 @@ impl<'a, P: AllocablePage> SCAllocator<'a, P> {
                 self.size,
                 ptr as usize
             );
+            self.free_obj_count -= 1;
         }
 
         res
@@ -304,7 +314,12 @@ impl<'a, P: AllocablePage> SCAllocator<'a, P> {
     /// May return an error in case an invalid `layout` is provided.
     /// The function may also move internal slab pages between lists partial -> empty
     /// or full -> partial lists.
-    pub fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) -> Result<(), AllocationError> {
+    pub unsafe fn deallocate(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        slab_callback: &'static dyn CallBack,
+    ) -> Result<(), AllocationError> {
         assert!(layout.size() <= self.size);
         assert!(self.size <= (P::SIZE - OBJECT_PAGE_METADATA_OVERHEAD));
         trace!(
@@ -324,6 +339,17 @@ impl<'a, P: AllocablePage> SCAllocator<'a, P> {
 
         let ret = slab_page.deallocate(ptr, new_layout);
         debug_assert!(ret.is_ok(), "Slab page deallocate won't fail at the moment");
+        self.free_obj_count += 1;
+        let is_empty_after_dealloc = slab_page.is_empty(self.obj_per_page);
+
+        // 如果slab_page是空白的,且空闲块数大于free_limit,将slab_page归还buddy
+        if self.free_obj_count >= self.free_limit && is_empty_after_dealloc {
+            self.slabs.remove_from_list(slab_page);
+            // 将slab_page归还buddy
+            slab_callback.free_slab_page(slab_page as *const P as *mut u8, P::SIZE);
+        }
+        self.check_page_assignments();
+
         ret
     }
 }

+ 9 - 12
kernel/crates/rust-slabmalloc/src/zone.rs

@@ -3,7 +3,6 @@
 //! The ZoneAllocator achieves this by having many `SCAllocator`
 
 use crate::*;
-use core::sync::atomic::Ordering;
 
 /// Creates an instance of a zone, we do this in a macro because we
 /// re-use the code in const and non-const functions
@@ -139,16 +138,8 @@ impl<'a> ZoneAllocator<'a> {
 
             // 遍历scallocator中的部分分配的page(partial_page)
             for slab_page in scallocator.slabs.iter_mut() {
-                // 统计page中还可以分配多少个object
-                let mut free_obj_count = 0;
-                // 遍历page中的bitfield(用来统计内存分配情况的u64数组)
-                for b in slab_page.bitfield().iter() {
-                    let bitval = b.load(Ordering::Relaxed);
-                    let free_count = bitval.count_zeros() as usize;
-                    free_obj_count += free_count;
-                }
                 // 剩余可分配object数乘上page中规定的每个object的大小,即空闲空间
-                free += free_obj_count * scallocator.size();
+                free += slab_page.free_obj_count() * scallocator.size();
             }
             // 遍历scallocator中的empty_page,把空页空间也加上去
             free +=
@@ -178,9 +169,15 @@ unsafe impl<'a> crate::Allocator<'a> for ZoneAllocator<'a> {
     /// # Arguments
     ///  * `ptr` - Address of the memory location to free.
     ///  * `layout` - Memory layout of the block pointed to by `ptr`.
-    fn deallocate(&mut self, ptr: NonNull<u8>, layout: Layout) -> Result<(), AllocationError> {
+    ///  * `slab_callback` - The callback function to free slab_page in buddy.
+    unsafe fn deallocate(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        slab_callback: &'static dyn CallBack,
+    ) -> Result<(), AllocationError> {
         match ZoneAllocator::get_slab(layout.size()) {
-            Slab::Base(idx) => self.small_slabs[idx].deallocate(ptr, layout),
+            Slab::Base(idx) => self.small_slabs[idx].deallocate(ptr, layout, slab_callback),
             Slab::Unsupported => Err(AllocationError::InvalidLayout),
         }
     }

+ 1 - 1
kernel/src/arch/x86_64/syscall/mod.rs

@@ -133,7 +133,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
                 show &= false;
             }
         }
-        show = false;
+        show &= false;
         if show {
             debug!("[SYS] [Pid: {:?}] [Call: {:?}]", pid, to_print);
         }

+ 18 - 15
kernel/src/driver/net/mod.rs

@@ -241,24 +241,27 @@ impl IfaceCommon {
             self.poll_at_ms.store(0, Ordering::Relaxed);
         }
 
-        if has_events {
-            // log::debug!("IfaceCommon::poll: has_events");
-            // We never try to hold the write lock in the IRQ context, and we disable IRQ when
-            // holding the write lock. So we don't need to disable IRQ when holding the read lock.
-            self.bounds.read().iter().for_each(|bound_socket| {
-                bound_socket.on_iface_events();
+        // if has_events {
+
+        // log::debug!("IfaceCommon::poll: has_events");
+        // We never try to hold the write lock in the IRQ context, and we disable IRQ when
+        // holding the write lock. So we don't need to disable IRQ when holding the read lock.
+        self.bounds.read().iter().for_each(|bound_socket| {
+            bound_socket.on_iface_events();
+            if has_events {
                 bound_socket
                     .wait_queue()
                     .wakeup(Some(ProcessState::Blocked(true)));
-            });
-
-            // let closed_sockets = self
-            //     .closing_sockets
-            //     .lock_irq_disabled()
-            //     .extract_if(|closing_socket| closing_socket.is_closed())
-            //     .collect::<Vec<_>>();
-            // drop(closed_sockets);
-        }
+            }
+        });
+
+        // let closed_sockets = self
+        //     .closing_sockets
+        //     .lock_irq_disabled()
+        //     .extract_if(|closing_socket| closing_socket.is_closed())
+        //     .collect::<Vec<_>>();
+        // drop(closed_sockets);
+        // }
     }
 
     pub fn update_ip_addrs(&self, ip_addrs: &[smoltcp::wire::IpCidr]) -> Result<(), SystemError> {

+ 1 - 1
kernel/src/driver/net/virtio_net.rs

@@ -257,7 +257,7 @@ impl Device for VirtIONetDevice {
 
 impl VirtIODevice for VirtIONetDevice {
     fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
-        log::warn!("VirtioInterface: poll_ifaces_try_lock_onetime -> poll_ifaces");
+        // log::warn!("VirtioInterface: poll_ifaces_try_lock_onetime -> poll_ifaces");
         poll_ifaces();
         return Ok(IrqReturn::Handled);
     }

+ 29 - 5
kernel/src/driver/serial/serial8250/serial8250_pio.rs

@@ -19,12 +19,14 @@ use crate::{
         },
         serial::{AtomicBaudRate, BaudRate, DivisorFraction, UartPort},
         tty::{
+            console::ConsoleSwitch,
             kthread::send_to_tty_refresh_thread,
             termios::WindowSize,
             tty_core::{TtyCore, TtyCoreData},
             tty_driver::{TtyDriver, TtyDriverManager, TtyOperation},
-            virtual_terminal::{vc_manager, VirtConsole},
+            virtual_terminal::{vc_manager, virtual_console::VirtualConsoleData, VirtConsole},
         },
+        video::console::dummycon::dummy_console,
     },
     exception::{
         irqdata::IrqHandlerData,
@@ -32,7 +34,7 @@ use crate::{
         manage::irq_manager,
         IrqNumber,
     },
-    libs::rwlock::RwLock,
+    libs::{rwlock::RwLock, spinlock::SpinLock},
 };
 use system_error::SystemError;
 
@@ -265,9 +267,20 @@ impl UartPort for Serial8250PIOPort {
     }
 
     fn handle_irq(&self) -> Result<(), SystemError> {
-        if let Some(c) = self.read_one_byte() {
-            send_to_tty_refresh_thread(&[c]);
+        let mut buf = [0; 8];
+        let mut index = 0;
+
+        // Read up to the size of the buffer
+        while index < buf.len() {
+            if let Some(c) = self.read_one_byte() {
+                buf[index] = c;
+                index += 1;
+            } else {
+                break; // No more bytes to read
+            }
         }
+
+        send_to_tty_refresh_thread(&buf[0..index]);
         Ok(())
     }
 
@@ -385,7 +398,18 @@ impl TtyOperation for Serial8250PIOTtyDriverInner {
         if tty.core().index() >= unsafe { PIO_PORTS.len() } {
             return Err(SystemError::ENODEV);
         }
-        let vc = VirtConsole::new(None);
+
+        *tty.core().window_size_write() = WindowSize::DEFAULT;
+        let vc_data = Arc::new(SpinLock::new(VirtualConsoleData::new(usize::MAX)));
+        let mut vc_data_guard = vc_data.lock_irqsave();
+        vc_data_guard.set_driver_funcs(Arc::downgrade(&dummy_console()) as Weak<dyn ConsoleSwitch>);
+        vc_data_guard.init(
+            Some(tty.core().window_size().row.into()),
+            Some(tty.core().window_size().col.into()),
+            true,
+        );
+        drop(vc_data_guard);
+        let vc = VirtConsole::new(Some(vc_data));
         let vc_index = vc_manager().alloc(vc.clone()).ok_or(SystemError::EBUSY)?;
         self.do_install(driver, tty, vc.clone()).inspect_err(|_| {
             vc_manager().free(vc_index);

+ 0 - 2
kernel/src/driver/tty/sysfs.rs

@@ -12,7 +12,6 @@ use crate::{
         kobject::KObject,
         subsys::SubSysPrivate,
     },
-    filesystem::sysfs::AttributeGroup,
     init::initcall::INITCALL_SUBSYS,
 };
 
@@ -62,7 +61,6 @@ impl Class for TtyClass {
     fn subsystem(&self) -> &SubSysPrivate {
         return &self.subsystem;
     }
-
 }
 
 /// 初始化帧缓冲区子系统

+ 1 - 7
kernel/src/driver/tty/termios.rs

@@ -2,7 +2,7 @@ use super::tty_ldisc::LineDisciplineType;
 
 /// ## 窗口大小
 #[repr(C)]
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Default)]
 pub struct WindowSize {
     /// 行
     pub row: u16,
@@ -26,12 +26,6 @@ impl WindowSize {
     }
 }
 
-impl Default for WindowSize {
-    fn default() -> Self {
-        Self::DEFAULT
-    }
-}
-
 #[derive(Debug, Clone, Copy)]
 pub struct Termios {
     pub input_mode: InputMode,

+ 57 - 2
kernel/src/driver/tty/tty_core.rs

@@ -31,7 +31,7 @@ use super::{
         TtyLineDiscipline,
     },
     tty_port::TtyPort,
-    virtual_terminal::{vc_manager, virtual_console::VirtualConsoleData},
+    virtual_terminal::{vc_manager, virtual_console::VirtualConsoleData, DrawRegion},
 };
 
 #[derive(Debug)]
@@ -103,7 +103,7 @@ impl TtyCore {
         self.line_discipline.clone()
     }
 
-    pub fn write_without_serial(&self, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
+    pub fn write_to_core(&self, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
         self.core
             .driver()
             .driver_funcs()
@@ -489,6 +489,61 @@ impl TtyCoreData {
     pub fn add_epitem(&self, epitem: Arc<EPollItem>) {
         self.epitems.lock().push_back(epitem)
     }
+
+    pub fn eptiems(&self) -> &SpinLock<LinkedList<Arc<EPollItem>>> {
+        &self.epitems
+    }
+
+    pub fn do_write(&self, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
+        // 关闭中断
+        if let Some(vc_data) = self.vc_data() {
+            let mut vc_data_guard = vc_data.lock_irqsave();
+            let mut offset = 0;
+
+            // 这个参数是用来扫描unicode字符的,但是这部分目前未完成,先写着
+            let mut rescan = false;
+            let mut ch: u32 = 0;
+
+            let mut draw = DrawRegion::default();
+
+            // 首先隐藏光标再写
+            vc_data_guard.hide_cursor();
+
+            while nr != 0 {
+                if !rescan {
+                    ch = buf[offset] as u32;
+                    offset += 1;
+                    nr -= 1;
+                }
+
+                let (tc, rescan_last) = vc_data_guard.translate(&mut ch);
+                if tc.is_none() {
+                    // 表示未转换完成
+                    continue;
+                }
+
+                let tc = tc.unwrap();
+                rescan = rescan_last;
+
+                if vc_data_guard.is_control(tc, ch) {
+                    vc_data_guard.flush(&mut draw);
+                    vc_data_guard.do_control(ch);
+                    continue;
+                }
+
+                if !vc_data_guard.console_write_normal(tc, ch, &mut draw) {
+                    continue;
+                }
+            }
+
+            vc_data_guard.flush(&mut draw);
+
+            // TODO: notify update
+            return Ok(offset);
+        } else {
+            return Ok(0);
+        }
+    }
 }
 
 impl TtyOperation for TtyCore {

+ 6 - 1
kernel/src/driver/tty/tty_port.rs

@@ -4,7 +4,10 @@ use alloc::sync::{Arc, Weak};
 use kdepends::thingbuf::mpsc;
 use system_error::SystemError;
 
-use crate::libs::spinlock::{SpinLock, SpinLockGuard};
+use crate::{
+    libs::spinlock::{SpinLock, SpinLockGuard},
+    net::event_poll::EventPoll,
+};
 
 use super::tty_core::TtyCore;
 
@@ -85,6 +88,8 @@ pub trait TtyPort: Sync + Send + Debug {
             return ld.receive_buf(tty, buf, None, count);
         }
 
+        EventPoll::wakeup_epoll(tty.core().eptiems(), None)?;
+
         ret
     }
 }

+ 1 - 50
kernel/src/driver/tty/virtual_terminal/mod.rs

@@ -300,55 +300,6 @@ impl TtyConsoleDriverInner {
         Ok(Self { console })
     }
 
-    fn do_write(&self, tty: &TtyCoreData, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
-        // 关闭中断
-        let vc_data = tty.vc_data().unwrap();
-        let mut vc_data_guard = vc_data.lock_irqsave();
-
-        let mut offset = 0;
-
-        // 这个参数是用来扫描unicode字符的,但是这部分目前未完成,先写着
-        let mut rescan = false;
-        let mut ch: u32 = 0;
-
-        let mut draw = DrawRegion::default();
-
-        // 首先隐藏光标再写
-        vc_data_guard.hide_cursor();
-
-        while nr != 0 {
-            if !rescan {
-                ch = buf[offset] as u32;
-                offset += 1;
-                nr -= 1;
-            }
-
-            let (tc, rescan_last) = vc_data_guard.translate(&mut ch);
-            if tc.is_none() {
-                // 表示未转换完成
-                continue;
-            }
-
-            let tc = tc.unwrap();
-            rescan = rescan_last;
-
-            if vc_data_guard.is_control(tc, ch) {
-                vc_data_guard.flush(&mut draw);
-                vc_data_guard.do_control(ch);
-                continue;
-            }
-
-            if !vc_data_guard.console_write_normal(tc, ch, &mut draw) {
-                continue;
-            }
-        }
-
-        vc_data_guard.flush(&mut draw);
-
-        // TODO: notify update
-        return Ok(offset);
-    }
-
     fn do_install(&self, tty: Arc<TtyCore>, vc: &Arc<VirtConsole>) -> Result<(), SystemError> {
         let tty_core = tty.core();
 
@@ -426,7 +377,7 @@ impl TtyOperation for TtyConsoleDriverInner {
         //     loop {}
         // }
         send_to_default_serial8250_port(buf);
-        let ret = self.do_write(tty, buf, nr);
+        let ret = tty.do_write(buf, nr);
         self.flush_chars(tty);
         ret
     }

+ 7 - 12
kernel/src/driver/tty/virtual_terminal/virtual_console.rs

@@ -206,7 +206,7 @@ impl VirtualConsoleData {
         }
     }
 
-    pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
+    pub fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
         if let Some(rows) = rows {
             self.rows = rows;
         }
@@ -242,7 +242,7 @@ impl VirtualConsoleData {
         self.driver_funcs.as_ref().unwrap().upgrade().unwrap()
     }
 
-    pub(super) fn set_driver_funcs(&mut self, func: Weak<dyn ConsoleSwitch>) {
+    pub fn set_driver_funcs(&mut self, func: Weak<dyn ConsoleSwitch>) {
         self.driver_funcs = Some(func);
     }
 
@@ -312,7 +312,7 @@ impl VirtualConsoleData {
     ///
     /// ### 返回值
     /// ### (转换后的字符:i32,是否需要更多的数据才能进行转换:bool)
-    pub(super) fn translate(&mut self, c: &mut u32) -> (Option<u32>, bool) {
+    pub fn translate(&mut self, c: &mut u32) -> (Option<u32>, bool) {
         if self.vc_state != VirtualConsoleState::ESnormal {
             // 在控制字符状态下不需要翻译
             return (Some(*c), false);
@@ -440,7 +440,7 @@ impl VirtualConsoleData {
     const CTRL_ALWAYS: u32 = 0x0800f501;
 
     /// ## 用于判断tc(终端字符)在当前VC下是不是需要显示的控制字符
-    pub(super) fn is_control(&self, tc: u32, c: u32) -> bool {
+    pub fn is_control(&self, tc: u32, c: u32) -> bool {
         // 当前vc状态机不在正常状态,即在接收特殊字符的状态,则是控制字符
         if self.vc_state != VirtualConsoleState::ESnormal {
             return true;
@@ -1257,7 +1257,7 @@ impl VirtualConsoleData {
 
     /// ## 处理终端控制字符
     #[inline(never)]
-    pub(super) fn do_control(&mut self, ch: u32) {
+    pub fn do_control(&mut self, ch: u32) {
         // 首先检查是否处于 ANSI 控制字符串状态
         if self.vc_state.is_ansi_control_string() && (8..=13).contains(&ch) {
             return;
@@ -1534,12 +1534,7 @@ impl VirtualConsoleData {
     }
 
     #[inline(never)]
-    pub(super) fn console_write_normal(
-        &mut self,
-        mut tc: u32,
-        c: u32,
-        draw: &mut DrawRegion,
-    ) -> bool {
+    pub fn console_write_normal(&mut self, mut tc: u32, c: u32, draw: &mut DrawRegion) -> bool {
         let mut attr = self.attr;
         let himask = self.hi_font_mask;
         let charmask = if himask == 0 { 0xff } else { 0x1ff };
@@ -1753,7 +1748,7 @@ impl VirtualConsoleData {
         return (self.attr & 0x88) | ((self.attr & 0x70) >> 4) | ((self.attr & 0x07) << 4);
     }
 
-    pub(super) fn flush(&self, draw: &mut DrawRegion) {
+    pub fn flush(&self, draw: &mut DrawRegion) {
         if draw.x.is_none() {
             return;
         }

+ 2 - 2
kernel/src/filesystem/eventfd.rs

@@ -137,7 +137,7 @@ impl IndexNode for EventFdInode {
 
         let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32);
         // 唤醒epoll中等待的进程
-        EventPoll::wakeup_epoll(&self.epitems, pollflag)?;
+        EventPoll::wakeup_epoll(&self.epitems, Some(pollflag))?;
 
         return Ok(8);
     }
@@ -184,7 +184,7 @@ impl IndexNode for EventFdInode {
 
         let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32);
         // 唤醒epoll中等待的进程
-        EventPoll::wakeup_epoll(&self.epitems, pollflag)?;
+        EventPoll::wakeup_epoll(&self.epitems, Some(pollflag))?;
         return Ok(8);
     }
 

+ 19 - 12
kernel/src/filesystem/vfs/core.rs

@@ -5,7 +5,7 @@ use log::{error, info};
 use system_error::SystemError;
 
 use crate::{
-    driver::base::block::manager::block_dev_manager,
+    driver::base::block::{gendisk::GenDisk, manager::block_dev_manager},
     filesystem::{
         devfs::devfs_init,
         fat::fs::FATFileSystem,
@@ -28,6 +28,7 @@ use super::{
 
 /// 当没有指定根文件系统时,尝试的根文件系统列表
 const ROOTFS_TRY_LIST: [&str; 4] = ["/dev/sda1", "/dev/sda", "/dev/vda1", "/dev/vda"];
+kernel_cmdline_param_kv!(ROOTFS_PATH_PARAM, root, "");
 
 /// @brief 原子地生成新的Inode号。
 /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的
@@ -116,20 +117,26 @@ fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemE
     return Ok(());
 }
 
+fn try_find_gendisk_as_rootfs(path: &str) -> Option<Arc<GenDisk>> {
+    if let Some(gd) = block_dev_manager().lookup_gendisk_by_path(path) {
+        info!("Use {} as rootfs", path);
+        return Some(gd);
+    }
+    return None;
+}
+
 pub fn mount_root_fs() -> Result<(), SystemError> {
     info!("Try to mount root fs...");
     block_dev_manager().print_gendisks();
-
-    let gendisk = ROOTFS_TRY_LIST
-        .iter()
-        .find_map(|&path| {
-            if let Some(gd) = block_dev_manager().lookup_gendisk_by_path(path) {
-                info!("Use {} as rootfs", path);
-                return Some(gd);
-            }
-            return None;
-        })
-        .ok_or(SystemError::ENODEV)?;
+    let gendisk = if let Some(rootfs_dev_path) = ROOTFS_PATH_PARAM.value_str() {
+        try_find_gendisk_as_rootfs(rootfs_dev_path)
+            .unwrap_or_else(|| panic!("Failed to find rootfs device {}", rootfs_dev_path))
+    } else {
+        ROOTFS_TRY_LIST
+            .iter()
+            .find_map(|&path| try_find_gendisk_as_rootfs(path))
+            .ok_or(SystemError::ENODEV)?
+    };
 
     let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(gendisk);
     if fatfs.is_err() {

+ 9 - 0
kernel/src/filesystem/vfs/mount.rs

@@ -399,6 +399,15 @@ impl IndexNode for MountFSInode {
         return self.inner_inode.ioctl(cmd, data, private_data);
     }
 
+    #[inline]
+    fn kernel_ioctl(
+        &self,
+        arg: Arc<dyn crate::net::event_poll::KernelIoctlData>,
+        data: &FilePrivateData,
+    ) -> Result<usize, SystemError> {
+        return self.inner_inode.kernel_ioctl(arg, data);
+    }
+
     #[inline]
     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
         return self.inner_inode.list();

+ 8 - 8
kernel/src/init/boot.rs

@@ -46,13 +46,20 @@ impl BootParams {
 
     /// 开机命令行参数字符串
     pub fn boot_cmdline_str(&self) -> &str {
-        core::str::from_utf8(self.boot_cmdline()).unwrap()
+        core::str::from_utf8(&self.boot_cmdline()[..self.boot_cmdline_len()]).unwrap()
     }
 
     pub fn bootloader_name(&self) -> Option<&str> {
         self.bootloader_name.as_deref()
     }
 
+    pub fn boot_cmdline_len(&self) -> usize {
+        self.boot_command_line
+            .iter()
+            .position(|&x| x == 0)
+            .unwrap_or(self.boot_command_line.len())
+    }
+
     /// 追加开机命令行参数
     ///
     /// 如果开机命令行参数已经满了,则不会追加。
@@ -149,13 +156,6 @@ pub fn boot_callbacks() -> &'static dyn BootCallbacks {
 }
 
 pub(super) fn boot_callback_except_early() {
-    boot_callbacks()
-        .init_kernel_cmdline()
-        .inspect_err(|e| {
-            log::error!("Failed to init kernel cmdline: {:?}", e);
-        })
-        .ok();
-
     let mut boot_params = boot_params().write();
     boot_params.bootloader_name = boot_callbacks()
         .init_bootloader_name()

+ 476 - 0
kernel/src/init/cmdline.rs

@@ -0,0 +1,476 @@
+use core::{
+    str,
+    sync::atomic::{fence, Ordering},
+};
+
+use alloc::{ffi::CString, vec::Vec};
+
+use crate::libs::spinlock::SpinLock;
+
+use super::boot_params;
+
+#[::linkme::distributed_slice]
+pub static KCMDLINE_PARAM_EARLY_KV: [KernelCmdlineParameter] = [..];
+
+#[::linkme::distributed_slice]
+pub static KCMDLINE_PARAM_KV: [KernelCmdlineParameter] = [..];
+
+#[::linkme::distributed_slice]
+pub static KCMDLINE_PARAM_ARG: [KernelCmdlineParameter] = [..];
+
+static KERNEL_CMDLINE_PARAM_MANAGER: KernelCmdlineManager = KernelCmdlineManager::new();
+
+#[inline(always)]
+pub fn kenrel_cmdline_param_manager() -> &'static KernelCmdlineManager {
+    &KERNEL_CMDLINE_PARAM_MANAGER
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum KCmdlineParamType {
+    /// bool类型参数
+    Arg,
+    /// key-value类型参数
+    KV,
+    /// 内存管理初始化之前的KV参数
+    EarlyKV,
+}
+
+pub struct KernelCmdlineParamBuilder {
+    name: &'static str,
+    ty: KCmdlineParamType,
+    default_str: &'static str,
+    default_bool: bool,
+    inv: bool,
+}
+
+impl KernelCmdlineParamBuilder {
+    pub const fn new(name: &'static str, ty: KCmdlineParamType) -> Self {
+        Self {
+            name,
+            ty,
+            default_str: "",
+            default_bool: false,
+            inv: false,
+        }
+    }
+
+    pub const fn default_str(mut self, default_str: &'static str) -> Self {
+        self.default_str = default_str;
+        self
+    }
+
+    pub const fn default_bool(mut self, default_bool: bool) -> Self {
+        self.default_bool = default_bool;
+        self
+    }
+
+    pub const fn inv(mut self, inv: bool) -> Self {
+        self.inv = inv;
+        self
+    }
+
+    pub const fn build_early_kv(self) -> Option<KernelCmdlineEarlyKV> {
+        if matches!(self.ty, KCmdlineParamType::EarlyKV) {
+            Some(KernelCmdlineEarlyKV {
+                name: self.name,
+                value: [0; KernelCmdlineEarlyKV::VALUE_MAX_LEN],
+                index: 0,
+                initialized: false,
+                default: self.default_str,
+            })
+        } else {
+            None
+        }
+    }
+
+    pub const fn build(self) -> Option<KernelCmdlineParameter> {
+        match self.ty {
+            KCmdlineParamType::Arg => Some(KernelCmdlineParameter::Arg(KernelCmdlineArg {
+                name: self.name,
+                value: self.default_bool,
+                initialized: false,
+                inv: self.inv,
+                default: self.default_bool,
+            })),
+            KCmdlineParamType::KV => Some(KernelCmdlineParameter::KV(KernelCmdlineKV {
+                name: self.name,
+                value: None,
+                initialized: false,
+                default: self.default_str,
+            })),
+            _ => None,
+        }
+    }
+}
+
+#[allow(dead_code)]
+pub enum KernelCmdlineParameter {
+    Arg(KernelCmdlineArg),
+    KV(KernelCmdlineKV),
+    EarlyKV(&'static KernelCmdlineEarlyKV),
+}
+
+impl KernelCmdlineParameter {
+    pub fn name(&self) -> &str {
+        match self {
+            KernelCmdlineParameter::Arg(v) => v.name,
+            KernelCmdlineParameter::KV(v) => v.name,
+            KernelCmdlineParameter::EarlyKV(v) => v.name,
+        }
+    }
+
+    /// 获取bool类型参数的值
+    pub fn value_bool(&self) -> Option<bool> {
+        match self {
+            KernelCmdlineParameter::Arg(v) => Some(v.value()),
+            _ => None,
+        }
+    }
+
+    /// 获取key-value类型参数的值
+    pub fn value_str(&self) -> Option<&str> {
+        match self {
+            KernelCmdlineParameter::Arg(_) => None,
+            KernelCmdlineParameter::KV(v) => v
+                .value
+                .as_ref()
+                .and_then(|v| str::from_utf8(v.as_bytes()).ok()),
+            KernelCmdlineParameter::EarlyKV(v) => v.value_str(),
+        }
+    }
+
+    pub fn is_arg(&self) -> bool {
+        matches!(self, KernelCmdlineParameter::Arg(_))
+    }
+
+    pub fn is_kv(&self) -> bool {
+        matches!(self, KernelCmdlineParameter::KV(_))
+    }
+
+    pub fn is_early_kv(&self) -> bool {
+        matches!(self, KernelCmdlineParameter::EarlyKV(_))
+    }
+
+    /// 强行获取可变引用
+    ///
+    /// # Safety
+    ///
+    /// 只能在内核初始化阶段pid0使用!
+    #[allow(clippy::mut_from_ref)]
+    unsafe fn force_mut(&self) -> &mut Self {
+        let p = self as *const Self as *mut Self;
+        p.as_mut().unwrap()
+    }
+}
+
+#[derive(Debug)]
+pub struct KernelCmdlineArg {
+    name: &'static str,
+    value: bool,
+    initialized: bool,
+    /// 是否反转
+    inv: bool,
+    default: bool,
+}
+
+impl KernelCmdlineArg {
+    pub fn value(&self) -> bool {
+        volatile_read!(self.value)
+    }
+}
+
+pub struct KernelCmdlineKV {
+    name: &'static str,
+    value: Option<CString>,
+    initialized: bool,
+    default: &'static str,
+}
+
+/// 在内存管理初始化之前的KV参数
+pub struct KernelCmdlineEarlyKV {
+    name: &'static str,
+    value: [u8; Self::VALUE_MAX_LEN],
+    index: usize,
+    initialized: bool,
+    default: &'static str,
+}
+
+impl KernelCmdlineEarlyKV {
+    pub const VALUE_MAX_LEN: usize = 256;
+
+    pub fn value(&self) -> &[u8] {
+        &self.value[..self.index]
+    }
+
+    pub fn value_str(&self) -> Option<&str> {
+        core::str::from_utf8(&self.value[..self.index]).ok()
+    }
+
+    /// 强行获取可变引用
+    ///
+    /// # Safety
+    ///
+    /// 只能在内核初始化阶段pid0使用!
+    #[allow(clippy::mut_from_ref)]
+    unsafe fn force_mut(&self) -> &mut Self {
+        let p = self as *const Self as *mut Self;
+        p.as_mut().unwrap()
+    }
+}
+
+pub struct KernelCmdlineManager {
+    inner: SpinLock<InnerKernelCmdlineManager>,
+}
+
+pub(super) struct InnerKernelCmdlineManager {
+    /// init进程的路径
+    init_path: Option<CString>,
+    init_args: Vec<CString>,
+    init_envs: Vec<CString>,
+}
+
+impl KernelCmdlineManager {
+    const fn new() -> Self {
+        Self {
+            inner: SpinLock::new(InnerKernelCmdlineManager {
+                init_path: None,
+                init_args: Vec::new(),
+                init_envs: Vec::new(),
+            }),
+        }
+    }
+
+    pub(super) fn init_proc_path(&self) -> Option<CString> {
+        self.inner.lock().init_path.clone()
+    }
+
+    pub(super) fn init_proc_args(&self) -> Vec<CString> {
+        self.inner.lock().init_args.clone()
+    }
+
+    pub(super) fn init_proc_envs(&self) -> Vec<CString> {
+        self.inner.lock().init_envs.clone()
+    }
+
+    /// 在内存管理初始化之前设置部分参数
+    pub fn early_init(&self) {
+        let boot_params = boot_params().read();
+
+        for argument in self.split_args(boot_params.boot_cmdline_str()) {
+            let (node, option, value) = match self.split_arg(argument) {
+                Some(v) => v,
+                None => continue,
+            };
+            // 查找参数
+            if let Some(param) = self.find_param(node, option, KCmdlineParamType::EarlyKV) {
+                let param = unsafe { param.force_mut() };
+                match param {
+                    KernelCmdlineParameter::EarlyKV(p) => {
+                        let p = unsafe { p.force_mut() };
+                        if let Some(value) = value {
+                            let value = value.as_bytes();
+                            let len = value.len().min(KernelCmdlineEarlyKV::VALUE_MAX_LEN);
+                            p.value[..len].copy_from_slice(&value[..len]);
+                            p.index = len;
+                        }
+                        p.initialized = true;
+                    }
+                    _ => unreachable!(),
+                }
+                fence(Ordering::SeqCst);
+            }
+        }
+
+        // 初始化默认值
+        KCMDLINE_PARAM_EARLY_KV.iter().for_each(|x| {
+            let x = unsafe { x.force_mut() };
+            if let KernelCmdlineParameter::EarlyKV(v) = x {
+                if !v.initialized {
+                    let v = unsafe { v.force_mut() };
+                    let len = v.default.len().min(KernelCmdlineEarlyKV::VALUE_MAX_LEN);
+                    v.value[..len].copy_from_slice(v.default.as_bytes());
+                    v.index = len;
+                    v.initialized = true;
+                }
+            }
+        });
+    }
+
+    /// 在内存管理初始化之后设置命令行参数
+    pub fn init(&self) {
+        let mut inner = self.inner.lock();
+        let boot_params = boot_params().read();
+        // `--`以后的参数都是init进程的参数
+        let mut kernel_cmdline_end = false;
+        for argument in self.split_args(boot_params.boot_cmdline_str()) {
+            if kernel_cmdline_end {
+                if inner.init_path.is_none() {
+                    panic!("cmdline: init proc path is not set while init proc args are set");
+                }
+                if !argument.is_empty() {
+                    inner.init_args.push(CString::new(argument).unwrap());
+                }
+                continue;
+            }
+
+            if argument == "--" {
+                kernel_cmdline_end = true;
+                continue;
+            }
+
+            let (node, option, value) = match self.split_arg(argument) {
+                Some(v) => v,
+                None => continue,
+            };
+            if option == "init" && value.is_some() {
+                if inner.init_path.is_some() {
+                    panic!("cmdline: init proc path is set twice");
+                }
+                inner.init_path = Some(CString::new(value.unwrap()).unwrap());
+                continue;
+            }
+            // log::debug!(
+            //     "cmdline: node: {:?}, option: {:?}, value: {:?}",
+            //     node,
+            //     option,
+            //     value
+            // );
+            if let Some(param) = self.find_param(node, option, KCmdlineParamType::KV) {
+                let param = unsafe { param.force_mut() };
+                match param {
+                    KernelCmdlineParameter::KV(p) => {
+                        if p.value.is_some() {
+                            log::warn!("cmdline: parameter {} is set twice", p.name);
+                            continue;
+                        }
+                        p.value = Some(CString::new(value.unwrap()).unwrap());
+                        p.initialized = true;
+                    }
+                    _ => unreachable!(),
+                }
+                fence(Ordering::SeqCst);
+            } else if let Some(param) = self.find_param(node, option, KCmdlineParamType::Arg) {
+                let param = unsafe { param.force_mut() };
+                match param {
+                    KernelCmdlineParameter::Arg(p) => {
+                        if p.initialized {
+                            log::warn!("cmdline: parameter {} is set twice", p.name);
+                            continue;
+                        }
+                        p.value = !p.inv;
+                        p.initialized = true;
+                    }
+                    _ => unreachable!(),
+                }
+                fence(Ordering::SeqCst);
+            } else if node.is_none() {
+                if let Some(val) = value {
+                    inner
+                        .init_envs
+                        .push(CString::new(format!("{}={}", option, val)).unwrap());
+                } else if !option.is_empty() {
+                    inner.init_args.push(CString::new(option).unwrap());
+                }
+            }
+        }
+        fence(Ordering::SeqCst);
+        // 初始化默认值
+        self.default_initialize();
+        fence(Ordering::SeqCst);
+    }
+
+    fn default_initialize(&self) {
+        KCMDLINE_PARAM_ARG.iter().for_each(|x| {
+            let x = unsafe { x.force_mut() };
+            if let KernelCmdlineParameter::Arg(v) = x {
+                if !v.initialized {
+                    v.value = v.default;
+                    v.initialized = true;
+                }
+            }
+            fence(Ordering::SeqCst);
+        });
+
+        KCMDLINE_PARAM_KV.iter().for_each(|x| {
+            let x = unsafe { x.force_mut() };
+            if let KernelCmdlineParameter::KV(v) = x {
+                if !v.initialized {
+                    v.value = Some(CString::new(v.default).unwrap());
+                    v.initialized = true;
+                }
+            }
+            fence(Ordering::SeqCst);
+        });
+    }
+
+    fn find_param(
+        &self,
+        node: Option<&str>,
+        option: &str,
+        param_typ: KCmdlineParamType,
+    ) -> Option<&KernelCmdlineParameter> {
+        let list = match param_typ {
+            KCmdlineParamType::Arg => &KCMDLINE_PARAM_ARG,
+            KCmdlineParamType::KV => &KCMDLINE_PARAM_KV,
+            KCmdlineParamType::EarlyKV => &KCMDLINE_PARAM_EARLY_KV,
+        };
+
+        list.iter().find(|x| {
+            let name = x.name();
+            if let Some(node) = node {
+                // 加1是因为有一个点号
+                name.len() == (node.len() + option.len() + 1)
+                    && name.starts_with(node)
+                    && name[node.len() + 1..].starts_with(option)
+            } else {
+                name == option
+            }
+        })
+    }
+
+    fn split_arg<'a>(&self, arg: &'a str) -> Option<(Option<&'a str>, &'a str, Option<&'a str>)> {
+        let mut iter = arg.splitn(2, '=');
+        let key = iter.next().unwrap();
+        let value = iter.next();
+        let value = value.map(|v| v.trim());
+        if value.is_some() && iter.next().is_some() {
+            log::warn!("cmdline: invalid argument: {}", arg);
+            return None;
+        }
+
+        let mut iter = key.splitn(2, '.');
+        let v1 = iter.next().map(|v| v.trim());
+        let v2 = iter.next().map(|v| v.trim());
+        let v3 = iter.next().map(|v| v.trim());
+        let v = [v1, v2, v3];
+
+        let mut key_split_len = 0;
+        v.iter().for_each(|x| {
+            if x.is_some() {
+                key_split_len += 1
+            }
+        });
+
+        let (node, option) = match key_split_len {
+            1 => (None, v[0].unwrap()),
+            2 => (Some(v[0].unwrap()), v[1].unwrap()),
+            _ => {
+                log::warn!("cmdline: invalid argument: {}", arg);
+                return None;
+            }
+        };
+
+        Some((node, option, value))
+    }
+
+    fn split_args<'a>(&self, cmdline: &'a str) -> impl Iterator<Item = &'a str> {
+        // 是否在引号内
+        let mut in_quote = false;
+        cmdline.split(move |c: char| {
+            if c == '"' {
+                in_quote = !in_quote;
+            }
+            !in_quote && c.is_whitespace()
+        })
+    }
+}

+ 19 - 4
kernel/src/init/init.rs

@@ -31,7 +31,10 @@ use crate::{
     },
 };
 
-use super::boot::boot_callback_except_early;
+use super::{
+    boot::{boot_callback_except_early, boot_callbacks},
+    cmdline::kenrel_cmdline_param_manager,
+};
 
 /// The entry point for the kernel
 ///
@@ -52,9 +55,7 @@ pub fn start_kernel() -> ! {
 #[inline(never)]
 fn do_start_kernel() {
     init_before_mem_init();
-    early_init_logging();
 
-    early_setup_arch().expect("setup_arch failed");
     unsafe { mm_init() };
 
     if scm_reinit().is_ok() {
@@ -62,8 +63,10 @@ fn do_start_kernel() {
             warn!("Failed to init textui: {:?}", e);
         }
     }
-
+    // 初始化内核命令行参数
+    kenrel_cmdline_param_manager().init();
     boot_callback_except_early();
+
     init_intertrait();
 
     vfs_init().expect("vfs init failed");
@@ -99,4 +102,16 @@ fn init_before_mem_init() {
     serial_early_init().expect("serial early init failed");
     let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
     scm_init(video_ok);
+
+    early_init_logging();
+
+    early_setup_arch().expect("setup_arch failed");
+
+    boot_callbacks()
+        .init_kernel_cmdline()
+        .inspect_err(|e| {
+            log::error!("Failed to init kernel cmdline: {:?}", e);
+        })
+        .ok();
+    kenrel_cmdline_param_manager().early_init();
 }

+ 61 - 16
kernel/src/init/initial_kthread.rs

@@ -14,12 +14,17 @@ use crate::{
     },
     filesystem::vfs::core::mount_root_fs,
     net::net_core::net_init,
-    process::{kthread::KernelThreadMechanism, stdio::stdio_init, ProcessFlags, ProcessManager},
+    process::{
+        exec::ProcInitInfo, kthread::KernelThreadMechanism, stdio::stdio_init, ProcessFlags,
+        ProcessManager,
+    },
     smp::smp_init,
     syscall::Syscall,
 };
 
-use super::initcall::do_initcalls;
+use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
+
+const INIT_PROC_TRYLIST: [&str; 3] = ["/bin/dragonreach", "/bin/init", "/bin/sh"];
 
 pub fn initial_kernel_thread() -> i32 {
     kernel_init().unwrap_or_else(|err| {
@@ -73,39 +78,79 @@ fn switch_to_user() -> ! {
     *current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
     drop(current_pcb);
 
+    let mut proc_init_info = ProcInitInfo::new("");
+    proc_init_info.envs.push(CString::new("PATH=/").unwrap());
+    proc_init_info.args = kenrel_cmdline_param_manager().init_proc_args();
+    proc_init_info.envs = kenrel_cmdline_param_manager().init_proc_envs();
+
     let mut trap_frame = TrapFrame::new();
-    // 逐个尝试运行init进程
-    if try_to_run_init_process("/bin/dragonreach", &mut trap_frame).is_err()
-        && try_to_run_init_process("/bin/init", &mut trap_frame).is_err()
-        && try_to_run_init_process("/bin/sh", &mut trap_frame).is_err()
-    {
-        panic!("Failed to run init process: No working init found.");
-    }
 
+    if let Some(path) = kenrel_cmdline_param_manager().init_proc_path() {
+        log::info!("Boot with specified init process: {:?}", path);
+
+        try_to_run_init_process(
+            path.as_c_str().to_str().unwrap(),
+            &mut proc_init_info,
+            &mut trap_frame,
+        )
+        .unwrap_or_else(|e| {
+            panic!(
+                "Failed to run specified init process: {:?}, err: {:?}",
+                path, e
+            )
+        });
+    } else {
+        let mut ok = false;
+        for path in INIT_PROC_TRYLIST.iter() {
+            if try_to_run_init_process(path, &mut proc_init_info, &mut trap_frame).is_ok() {
+                ok = true;
+                break;
+            }
+        }
+        if !ok {
+            panic!("Failed to run init process: No working init found.");
+        }
+    }
+    drop(proc_init_info);
     // 需要确保执行到这里之后,上面所有的资源都已经释放(比如arc之类的)
     compiler_fence(Ordering::SeqCst);
 
     unsafe { arch_switch_to_user(trap_frame) };
 }
 
-fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
-    if let Err(e) = run_init_process(path, trap_frame) {
+fn try_to_run_init_process(
+    path: &str,
+    proc_init_info: &mut ProcInitInfo,
+    trap_frame: &mut TrapFrame,
+) -> Result<(), SystemError> {
+    proc_init_info.proc_name = CString::new(path).unwrap();
+    proc_init_info.args.insert(0, CString::new(path).unwrap());
+    if let Err(e) = run_init_process(proc_init_info, trap_frame) {
         if e != SystemError::ENOENT {
             error!(
                 "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
                 e
             );
         }
+
+        proc_init_info.args.remove(0);
         return Err(e);
     }
     Ok(())
 }
 
-fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
-    let argv = vec![CString::new(path).unwrap()];
-    let envp = vec![CString::new("PATH=/").unwrap()];
-
+fn run_init_process(
+    proc_init_info: &ProcInitInfo,
+    trap_frame: &mut TrapFrame,
+) -> Result<(), SystemError> {
     compiler_fence(Ordering::SeqCst);
-    Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
+    let path = proc_init_info.proc_name.to_str().unwrap();
+
+    Syscall::do_execve(
+        path.to_string(),
+        proc_init_info.args.clone(),
+        proc_init_info.envs.clone(),
+        trap_frame,
+    )?;
     Ok(())
 }

+ 1 - 0
kernel/src/init/mod.rs

@@ -2,6 +2,7 @@ use crate::libs::rwlock::RwLock;
 
 use self::boot::BootParams;
 pub mod boot;
+pub mod cmdline;
 #[allow(clippy::module_inception)]
 pub mod init;
 pub mod initcall;

+ 2 - 2
kernel/src/ipc/pipe.rs

@@ -267,7 +267,7 @@ impl IndexNode for LockedPipeInode {
 
         let pollflag = EPollEventType::from_bits_truncate(inode.poll(&data)? as u32);
         // 唤醒epoll中等待的进程
-        EventPoll::wakeup_epoll(&inode.epitems, pollflag)?;
+        EventPoll::wakeup_epoll(&inode.epitems, Some(pollflag))?;
 
         //返回读取的字节数
         return Ok(num);
@@ -413,7 +413,7 @@ impl IndexNode for LockedPipeInode {
 
         let pollflag = EPollEventType::from_bits_truncate(inode.poll(&data)? as u32);
         // 唤醒epoll中等待的进程
-        EventPoll::wakeup_epoll(&inode.epitems, pollflag)?;
+        EventPoll::wakeup_epoll(&inode.epitems, Some(pollflag))?;
 
         // 返回写入的字节数
         return Ok(len);

+ 2 - 1
kernel/src/lib.rs

@@ -81,7 +81,8 @@ extern crate smoltcp;
 extern crate intertrait;
 #[cfg(target_arch = "x86_64")]
 extern crate x86;
-
+#[macro_use]
+extern crate kcmdline_macros;
 extern crate klog_types;
 extern crate uefi;
 extern crate uefi_raw;

+ 1 - 2
kernel/src/libs/lib_ui/textui.rs

@@ -1045,9 +1045,8 @@ pub extern "C" fn rs_textui_putchar(character: u8, fr_color: u32, bk_color: u32)
         let port = current_vc.port();
         let tty = port.port_data().internal_tty();
         if let Some(tty) = tty {
-            send_to_default_serial8250_port(&[character]);
             return tty
-                .write_without_serial(buf.as_bytes(), buf.len())
+                .write_to_core(buf.as_bytes(), buf.len())
                 .map(|_| 0)
                 .unwrap_or_else(|e| e.to_posix_errno());
         }

+ 1 - 1
kernel/src/mm/allocator/kernel_allocator.rs

@@ -51,7 +51,7 @@ impl KernelAllocator {
         return Ok(NonNull::from(slice));
     }
 
-    unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) {
+    pub(super) unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) {
         // 由于buddy分配的页数量是2的幂,因此释放的时候也需要按照2的幂向上取整。
         let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two();
         let page_frame_count = PageFrameCount::new(count);

+ 15 - 1
kernel/src/mm/allocator/slab.rs

@@ -4,12 +4,16 @@ use alloc::boxed::Box;
 use log::debug;
 use slabmalloc::*;
 
+use crate::{arch::MMArch, mm::MemoryManagementArch, KERNEL_ALLOCATOR};
+
 // 全局slab分配器
 pub(crate) static mut SLABALLOCATOR: Option<SlabAllocator> = None;
 
 // slab初始化状态
 pub(crate) static mut SLABINITSTATE: AtomicBool = AtomicBool::new(false);
 
+static SLAB_CALLBACK: SlabCallback = SlabCallback;
+
 /// slab分配器,实际为一堆小的allocator,可以在里面装4K的page
 /// 利用这些allocator可以为对象分配不同大小的空间
 pub(crate) struct SlabAllocator {
@@ -52,7 +56,7 @@ impl SlabAllocator {
     ) -> Result<(), AllocationError> {
         if let Some(nptr) = NonNull::new(ptr) {
             self.zone
-                .deallocate(nptr, layout)
+                .deallocate(nptr, layout, &SLAB_CALLBACK)
                 .expect("Couldn't deallocate");
             return Ok(());
         } else {
@@ -80,3 +84,13 @@ pub unsafe fn slab_usage() -> SlabUsage {
         SlabUsage::new(0, 0)
     }
 }
+
+/// 归还slab_page给buddy的回调
+pub struct SlabCallback;
+impl CallBack for SlabCallback {
+    unsafe fn free_slab_page(&self, base_addr: *mut u8, size: usize) {
+        assert_eq!(base_addr as usize & (MMArch::PAGE_SIZE - 1), 0); // 确认地址4k对齐
+        assert_eq!(size, MMArch::PAGE_SIZE); // 确认释放的slab_page大小
+        KERNEL_ALLOCATOR.free_in_buddy(base_addr, Layout::from_size_align_unchecked(size, 1));
+    }
+}

+ 35 - 26
kernel/src/net/event_poll/mod.rs

@@ -716,41 +716,50 @@ impl EventPoll {
     /// ### epoll的回调,支持epoll的文件有事件到来时直接调用该方法即可
     pub fn wakeup_epoll(
         epitems: &SpinLock<LinkedList<Arc<EPollItem>>>,
-        pollflags: EPollEventType,
+        pollflags: Option<EPollEventType>,
     ) -> Result<(), SystemError> {
         let mut epitems_guard = epitems.try_lock_irqsave()?;
         // 一次只取一个,因为一次也只有一个进程能拿到对应文件的🔓
         if let Some(epitem) = epitems_guard.pop_front() {
-            let epoll = epitem.epoll().upgrade().unwrap();
-            let mut epoll_guard = epoll.try_lock()?;
-            let binding = epitem.clone();
-            let event_guard = binding.event().read();
-            let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
-
-            // 检查事件合理性以及是否有感兴趣的事件
-            if !(ep_events
-                .difference(EPollEventType::EP_PRIVATE_BITS)
-                .is_empty()
-                || pollflags.difference(ep_events).is_empty())
-            {
-                // TODO: 未处理pm相关
+            let pollflags = pollflags.unwrap_or({
+                if let Some(file) = epitem.file.upgrade() {
+                    EPollEventType::from_bits_truncate(file.poll()? as u32)
+                } else {
+                    EPollEventType::empty()
+                }
+            });
 
-                // 首先将就绪的epitem加入等待队列
-                epoll_guard.ep_add_ready(epitem.clone());
+            if let Some(epoll) = epitem.epoll().upgrade() {
+                let mut epoll_guard = epoll.try_lock()?;
+                let binding = epitem.clone();
+                let event_guard = binding.event().read();
+                let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
 
-                if epoll_guard.ep_has_waiter() {
-                    if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE)
-                        && !pollflags.contains(EPollEventType::POLLFREE)
-                    {
-                        // 避免惊群
-                        epoll_guard.ep_wake_one();
-                    } else {
-                        epoll_guard.ep_wake_all();
+                // 检查事件合理性以及是否有感兴趣的事件
+                if !(ep_events
+                    .difference(EPollEventType::EP_PRIVATE_BITS)
+                    .is_empty()
+                    || pollflags.difference(ep_events).is_empty())
+                {
+                    // TODO: 未处理pm相关
+
+                    // 首先将就绪的epitem加入等待队列
+                    epoll_guard.ep_add_ready(epitem.clone());
+
+                    if epoll_guard.ep_has_waiter() {
+                        if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE)
+                            && !pollflags.contains(EPollEventType::POLLFREE)
+                        {
+                            // 避免惊群
+                            epoll_guard.ep_wake_one();
+                        } else {
+                            epoll_guard.ep_wake_all();
+                        }
                     }
                 }
-            }
 
-            epitems_guard.push_back(epitem);
+                epitems_guard.push_back(epitem);
+            }
         }
         Ok(())
     }

+ 2 - 3
kernel/src/net/socket/buffer.rs

@@ -1,7 +1,6 @@
 use alloc::vec::Vec;
 
 use alloc::{string::String, sync::Arc};
-use log::debug;
 use system_error::SystemError;
 
 use crate::libs::spinlock::SpinLock;
@@ -43,14 +42,14 @@ impl Buffer {
         let len = core::cmp::min(buf.len(), read_buffer.len());
         buf[..len].copy_from_slice(&read_buffer[..len]);
         let _ = read_buffer.split_off(len);
-        log::debug!("recv buf {}", String::from_utf8_lossy(buf));
+        // log::debug!("recv buf {}", String::from_utf8_lossy(buf));
 
         return Ok(len);
     }
 
     pub fn write_read_buffer(&self, buf: &[u8]) -> Result<usize, SystemError> {
         let mut buffer = self.read_buffer.lock_irqsave();
-        log::debug!("send buf {}", String::from_utf8_lossy(buf));
+        // log::debug!("send buf {}", String::from_utf8_lossy(buf));
         let len = buf.len();
         if self.metadata.buf_size - buffer.len() < len {
             return Err(SystemError::ENOBUFS);

+ 1 - 1
kernel/src/net/socket/inet/common/mod.rs

@@ -45,7 +45,7 @@ impl BoundInner {
             //     iface
             // }
             // 强绑VirtualIO
-            log::debug!("Not bind to any iface, bind to virtIO");
+            // log::debug!("Not bind to any iface, bind to virtIO");
             let iface = NET_DEVICES
                 .read_irqsave()
                 .get(&0)

+ 15 - 5
kernel/src/net/socket/inet/stream/inner.rs

@@ -3,6 +3,7 @@ use core::sync::atomic::{AtomicU32, AtomicUsize};
 use crate::libs::rwlock::RwLock;
 use crate::net::socket::EPollEventType;
 use crate::net::socket::{self, inet::Types};
+use alloc::boxed::Box;
 use alloc::vec::Vec;
 use smoltcp;
 use system_error::SystemError::{self, *};
@@ -30,13 +31,13 @@ where
 
 #[derive(Debug)]
 pub enum Init {
-    Unbound(smoltcp::socket::tcp::Socket<'static>),
+    Unbound(Box<smoltcp::socket::tcp::Socket<'static>>),
     Bound((socket::inet::BoundInner, smoltcp::wire::IpEndpoint)),
 }
 
 impl Init {
     pub(super) fn new() -> Self {
-        Init::Unbound(new_smoltcp_socket())
+        Init::Unbound(Box::new(new_smoltcp_socket()))
     }
 
     /// 传入一个已经绑定的socket
@@ -55,7 +56,7 @@ impl Init {
     ) -> Result<Self, SystemError> {
         match self {
             Init::Unbound(socket) => {
-                let bound = socket::inet::BoundInner::bind(socket, &local_endpoint.addr)?;
+                let bound = socket::inet::BoundInner::bind(*socket, &local_endpoint.addr)?;
                 bound
                     .port_manager()
                     .bind_port(Types::Tcp, local_endpoint.port)?;
@@ -73,7 +74,7 @@ impl Init {
         match self {
             Init::Unbound(socket) => {
                 let (bound, address) =
-                    socket::inet::BoundInner::bind_ephemeral(socket, remote_endpoint.addr)
+                    socket::inet::BoundInner::bind_ephemeral(*socket, remote_endpoint.addr)
                         .map_err(|err| (Self::new(), err))?;
                 let bound_port = bound
                     .port_manager()
@@ -125,7 +126,7 @@ impl Init {
         } else {
             smoltcp::wire::IpListenEndpoint::from(local)
         };
-        log::debug!("listen at {:?}", listen_addr);
+        // log::debug!("listen at {:?}", listen_addr);
         let mut inners = Vec::new();
         if let Err(err) = || -> Result<(), SystemError> {
             for _ in 0..(backlog - 1) {
@@ -440,4 +441,13 @@ impl Inner {
             Inner::Established(est) => est.with_mut(|socket| socket.recv_capacity()),
         }
     }
+
+    pub fn iface(&self) -> Option<&alloc::sync::Arc<dyn crate::driver::net::Iface>> {
+        match self {
+            Inner::Init(_) => None,
+            Inner::Connecting(conn) => Some(conn.inner.iface()),
+            Inner::Listening(listen) => Some(listen.inners[0].iface()),
+            Inner::Established(est) => Some(est.inner.iface()),
+        }
+    }
 }

+ 16 - 7
kernel/src/net/socket/inet/stream/mod.rs

@@ -185,11 +185,19 @@ impl TcpSocket {
     }
 
     pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
-        poll_ifaces();
-        match self.inner.read().as_ref().expect("Tcp Inner is None") {
-            Inner::Established(inner) => inner.recv_slice(buf),
-            _ => Err(EINVAL),
-        }
+        self.inner
+            .read()
+            .as_ref()
+            .map(|inner| {
+                inner.iface().unwrap().poll();
+                let result = match inner {
+                    Inner::Established(inner) => inner.recv_slice(buf),
+                    _ => Err(EINVAL),
+                };
+                inner.iface().unwrap().poll();
+                result
+            })
+            .unwrap()
     }
 
     pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> {
@@ -221,6 +229,7 @@ impl TcpSocket {
     // should only call on accept
     fn is_acceptable(&self) -> bool {
         // (self.poll() & EP::EPOLLIN.bits() as usize) != 0
+        self.inner.read().as_ref().unwrap().iface().unwrap().poll();
         EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLIN)
     }
 }
@@ -233,7 +242,7 @@ impl Socket for TcpSocket {
     fn get_name(&self) -> Result<Endpoint, SystemError> {
         match self.inner.read().as_ref().expect("Tcp Inner is None") {
             Inner::Init(Init::Unbound(_)) => Ok(Endpoint::Ip(UNSPECIFIED_LOCAL_ENDPOINT)),
-            Inner::Init(Init::Bound((_, local))) => Ok(Endpoint::Ip(local.clone())),
+            Inner::Init(Init::Bound((_, local))) => Ok(Endpoint::Ip(*local)),
             Inner::Connecting(connecting) => Ok(Endpoint::Ip(connecting.get_name())),
             Inner::Established(established) => Ok(Endpoint::Ip(established.local_endpoint())),
             Inner::Listening(listening) => Ok(Endpoint::Ip(listening.get_name())),
@@ -255,7 +264,7 @@ impl Socket for TcpSocket {
     }
 
     fn poll(&self) -> usize {
-        self.pollee.load(core::sync::atomic::Ordering::Relaxed)
+        self.pollee.load(core::sync::atomic::Ordering::SeqCst)
     }
 
     fn listen(&self, backlog: usize) -> Result<(), SystemError> {

+ 1 - 1
kernel/src/net/socket/inet/syscall.rs

@@ -11,7 +11,7 @@ fn create_inet_socket(
     socket_type: Type,
     protocol: smoltcp::wire::IpProtocol,
 ) -> Result<Arc<dyn Socket>, SystemError> {
-    log::debug!("type: {:?}, protocol: {:?}", socket_type, protocol);
+    // log::debug!("type: {:?}, protocol: {:?}", socket_type, protocol);
     use smoltcp::wire::IpProtocol::*;
     use Type::*;
     match socket_type {

+ 1 - 1
kernel/src/net/socket/unix/mod.rs

@@ -27,7 +27,7 @@ impl family::Family for Unix {
 
 impl Unix {
     pub fn new_pairs(socket_type: Type) -> Result<(Arc<Inode>, Arc<Inode>), SystemError> {
-        log::debug!("socket_type {:?}", socket_type);
+        // log::debug!("socket_type {:?}", socket_type);
         match socket_type {
             Type::SeqPacket => seqpacket::SeqpacketSocket::new_pairs(),
             Type::Stream | Type::Datagram => stream::StreamSocket::new_pairs(),

+ 3 - 7
kernel/src/net/socket/unix/seqpacket/inner.rs

@@ -62,11 +62,7 @@ pub(super) struct Listener {
 impl Listener {
     pub(super) fn new(inode: Endpoint, backlog: usize) -> Self {
         log::debug!("backlog {}", backlog);
-        let back = if backlog > 1024 {
-            1024 as usize
-        } else {
-            backlog
-        };
+        let back = if backlog > 1024 { 1024_usize } else { backlog };
         return Self {
             inode,
             backlog: AtomicUsize::new(back),
@@ -82,7 +78,7 @@ impl Listener {
         log::debug!(" incom len {}", incoming_conns.len());
         let conn = incoming_conns
             .pop_front()
-            .ok_or_else(|| SystemError::EAGAIN_OR_EWOULDBLOCK)?;
+            .ok_or(SystemError::EAGAIN_OR_EWOULDBLOCK)?;
         let socket =
             Arc::downcast::<SeqpacketSocket>(conn.inner()).map_err(|_| SystemError::EINVAL)?;
         let peer = match &*socket.inner.read() {
@@ -190,7 +186,7 @@ impl Connected {
         if self.can_send()? {
             return self.send_slice(buf);
         } else {
-            log::debug!("can not send {:?}", String::from_utf8_lossy(&buf[..]));
+            log::debug!("can not send {:?}", String::from_utf8_lossy(buf));
             return Err(SystemError::ENOBUFS);
         }
     }

+ 6 - 10
kernel/src/net/socket/unix/seqpacket/mod.rs

@@ -230,11 +230,7 @@ impl Socket for SeqpacketSocket {
         if !self.is_nonblocking() {
             loop {
                 wq_wait_event_interruptible!(self.wait_queue, self.is_acceptable(), {})?;
-                match self
-                    .try_accept()
-                    .map(|(seqpacket_socket, remote_endpoint)| {
-                        (seqpacket_socket, Endpoint::from(remote_endpoint))
-                    }) {
+                match self.try_accept() {
                     Ok((socket, epoint)) => return Ok((socket, epoint)),
                     Err(_) => continue,
                 }
@@ -260,7 +256,7 @@ impl Socket for SeqpacketSocket {
     }
 
     fn close(&self) -> Result<(), SystemError> {
-        log::debug!("seqpacket close");
+        // log::debug!("seqpacket close");
         self.shutdown.recv_shutdown();
         self.shutdown.send_shutdown();
         Ok(())
@@ -274,7 +270,7 @@ impl Socket for SeqpacketSocket {
         };
 
         if let Some(endpoint) = endpoint {
-            return Ok(Endpoint::from(endpoint));
+            return Ok(endpoint);
         } else {
             return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
         }
@@ -289,7 +285,7 @@ impl Socket for SeqpacketSocket {
         };
 
         if let Some(endpoint) = endpoint {
-            return Ok(Endpoint::from(endpoint));
+            return Ok(endpoint);
         } else {
             return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
         }
@@ -402,7 +398,7 @@ impl Socket for SeqpacketSocket {
         flags: MessageFlag,
         _address: Option<Endpoint>,
     ) -> Result<(usize, Endpoint), SystemError> {
-        log::debug!("recvfrom flags {:?}", flags);
+        // log::debug!("recvfrom flags {:?}", flags);
         if flags.contains(MessageFlag::OOB) {
             return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
         }
@@ -417,7 +413,7 @@ impl Socket for SeqpacketSocket {
                 match &*self.inner.write() {
                     Inner::Connected(connected) => match connected.recv_slice(buffer) {
                         Ok(usize) => {
-                            log::debug!("recvs from successfully");
+                            // log::debug!("recvs from successfully");
                             return Ok((usize, connected.peer_endpoint().unwrap().clone()));
                         }
                         Err(_) => continue,

+ 1 - 4
kernel/src/net/socket/unix/stream/mod.rs

@@ -231,10 +231,7 @@ impl Socket for StreamSocket {
         //目前只实现了阻塞式实现
         loop {
             wq_wait_event_interruptible!(self.wait_queue, self.is_acceptable(), {})?;
-            match self
-                .try_accept()
-                .map(|(stream_socket, remote_endpoint)| (stream_socket, remote_endpoint))
-            {
+            match self.try_accept() {
                 Ok((socket, endpoint)) => {
                     debug!("server accept!:{:?}", endpoint);
                     return Ok((socket, endpoint));

+ 8 - 8
kernel/src/net/syscall.rs

@@ -41,18 +41,18 @@ impl Syscall {
         protocol: usize,
     ) -> Result<usize, SystemError> {
         // 打印收到的参数
-        log::debug!(
-            "socket: address_family={:?}, socket_type={:?}, protocol={:?}",
-            address_family,
-            socket_type,
-            protocol
-        );
+        // log::debug!(
+        //     "socket: address_family={:?}, socket_type={:?}, protocol={:?}",
+        //     address_family,
+        //     socket_type,
+        //     protocol
+        // );
         let address_family = socket::AddressFamily::try_from(address_family as u16)?;
         let type_arg = SysArgSocketType::from_bits_truncate(socket_type as u32);
         let is_nonblock = type_arg.is_nonblock();
         let is_close_on_exec = type_arg.is_cloexec();
         let stype = socket::Type::try_from(type_arg)?;
-        log::debug!("type_arg {:?}  stype {:?}", type_arg, stype);
+        // log::debug!("type_arg {:?}  stype {:?}", type_arg, stype);
 
         let inode = socket::create_socket(
             address_family,
@@ -256,7 +256,7 @@ impl Syscall {
         let socket: Arc<socket::Inode> = ProcessManager::current_pcb()
             .get_socket(fd as i32)
             .ok_or(SystemError::EBADF)?;
-        log::debug!("bind: socket={:?}", socket);
+        // log::debug!("bind: socket={:?}", socket);
         socket.bind(endpoint)?;
         Ok(0)
     }

+ 1 - 1
kernel/src/net/syscall_util.rs

@@ -296,7 +296,7 @@ impl From<Endpoint> for SockAddr {
                 }
                 let addr_un = SockAddrUn {
                     sun_family: AddressFamily::Unix as u16,
-                    sun_path: sun_path,
+                    sun_path,
                 };
                 return SockAddr { addr_un };
             }

+ 1 - 1
tools/BUILD_CONTAINER_VERSION

@@ -1 +1 @@
-v1.3
+v1.4

+ 1 - 0
tools/bootstrap.sh

@@ -232,6 +232,7 @@ rustInstall() {
 
         echo "正在安装DragonOS所需的rust组件...首次安装需要一些时间来更新索引,请耐心等待..."
         cargo install cargo-binutils
+		cargo install bpf-linker
 		rustup toolchain install nightly-2023-08-15-x86_64-unknown-linux-gnu
 		rustup toolchain install $RUST_VERSION-x86_64-unknown-linux-gnu
 		rustup component add rust-src --toolchain $RUST_VERSION-x86_64-unknown-linux-gnu

+ 1 - 2
tools/write_disk_image.sh

@@ -126,9 +126,8 @@ cfg_content='set timeout=15
     set default=0
     insmod efi_gop
     menuentry "DragonOS" {
-    multiboot2 /boot/kernel.elf "KERNEL_ELF"
+    multiboot2 /boot/kernel.elf init=/bin/dragonreach
 }'
-
 # 增加insmod efi_gop防止32位uefi启动报错
 echo "echo '${cfg_content}' >  ${boot_folder}/grub/grub.cfg" | sh
 fi

+ 1 - 1
user/apps/ping/src/ping.rs

@@ -101,7 +101,7 @@ impl Ping {
 
         for i in 0..this.config.count {
             let _this = this.clone();
-            let handle = thread::spawn(move||{
+            let handle = thread::spawn(move || {
                 _this.ping(i).unwrap();
             });
             _send.fetch_add(1, Ordering::SeqCst);

+ 22 - 6
user/apps/test-uevent/src/main.rs

@@ -1,7 +1,7 @@
 use libc::{sockaddr,  recvfrom, bind, sendto, socket, AF_NETLINK, SOCK_DGRAM, getpid, c_void};
 use nix::libc;
 use std::os::unix::io::RawFd;
-use std::{ mem, io};
+use std::{io, mem};
 
 #[repr(C)]
 struct Nlmsghdr {
@@ -33,7 +33,11 @@ fn bind_netlink_socket(sock: RawFd) -> io::Result<()> {
     addr.nl_groups = 1;
 
     let ret = unsafe {
-        bind(sock, &addr as *const _ as *const sockaddr, mem::size_of::<libc::sockaddr_nl>() as u32)
+        bind(
+            sock,
+            &addr as *const _ as *const sockaddr,
+            mem::size_of::<libc::sockaddr_nl>() as u32,
+        )
     };
 
     if ret < 0 {
@@ -90,7 +94,10 @@ fn receive_uevent(sock: RawFd) -> io::Result<String> {
     // 检查套接字文件描述符是否有效
     if sock < 0 {
         println!("Invalid socket file descriptor: {}", sock);
-        return Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid socket file descriptor"));
+        return Err(io::Error::new(
+            io::ErrorKind::InvalidInput,
+            "Invalid socket file descriptor",
+        ));
     }
 
     let mut buf = [0u8; 1024];
@@ -100,7 +107,10 @@ fn receive_uevent(sock: RawFd) -> io::Result<String> {
     // 检查缓冲区指针和长度是否有效
     if buf.is_empty() {
         println!("Buffer is empty");
-        return Err(io::Error::new(io::ErrorKind::InvalidInput, "Buffer is empty"));
+        return Err(io::Error::new(
+            io::ErrorKind::InvalidInput,
+            "Buffer is empty",
+        ));
     }
     let len = unsafe {
         recvfrom(
@@ -122,13 +132,19 @@ fn receive_uevent(sock: RawFd) -> io::Result<String> {
     let nlmsghdr_size = mem::size_of::<Nlmsghdr>();
     if (len as usize) < nlmsghdr_size {
         println!("Received message is too short");
-        return Err(io::Error::new(io::ErrorKind::InvalidData, "Received message is too short"));
+        return Err(io::Error::new(
+            io::ErrorKind::InvalidData,
+            "Received message is too short",
+        ));
     }
 
     let nlmsghdr = unsafe { &*(buf.as_ptr() as *const Nlmsghdr) };
     if nlmsghdr.nlmsg_len as isize > len {
         println!("Received message is incomplete");
-        return Err(io::Error::new(io::ErrorKind::InvalidData, "Received message is incomplete"));
+        return Err(io::Error::new(
+            io::ErrorKind::InvalidData,
+            "Received message is incomplete",
+        ));
     }
 
     let message_data = &buf[nlmsghdr_size..nlmsghdr.nlmsg_len as usize];

+ 3 - 3
user/apps/test_seqpacket/src/main.rs

@@ -1,8 +1,8 @@
-mod seq_socket;
 mod seq_pair;
+mod seq_socket;
 
-use seq_socket::test_seq_socket;
 use seq_pair::test_seq_pair;
+use seq_socket::test_seq_socket;
 
 fn main() -> Result<(), std::io::Error> {
     if let Err(e) = test_seq_socket() {
@@ -187,4 +187,4 @@ fn main() -> Result<(), std::io::Error> {
 //     let len = socket1.read(&mut buf)?;
 //     println!("sock1 receive: {:?}", String::from_utf8_lossy(&buf[..len]));
 //     Ok(())
-// }
+// }

+ 5 - 4
user/apps/test_seqpacket/src/seq_pair.rs

@@ -1,16 +1,17 @@
 use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
 use std::fs::File;
-use std::io::{Read, Write,Error};
+use std::io::{Error, Read, Write};
 use std::os::fd::FromRawFd;
 
-pub fn test_seq_pair()->Result<(),Error>{
+pub fn test_seq_pair() -> Result<(), Error> {
     // 创建 socket pair
     let (sock1, sock2) = socketpair(
         AddressFamily::Unix,
         SockType::SeqPacket, // 使用 SeqPacket 类型
         None,                // 协议默认
         SockFlag::empty(),
-    ).expect("Failed to create socket pair");
+    )
+    .expect("Failed to create socket pair");
 
     let mut socket1 = unsafe { File::from_raw_fd(sock1) };
     let mut socket2 = unsafe { File::from_raw_fd(sock2) };
@@ -36,4 +37,4 @@ pub fn test_seq_pair()->Result<(),Error>{
     let len = socket1.read(&mut buf)?;
     println!("sock1 receive: {:?}", String::from_utf8_lossy(&buf[..len]));
     Ok(())
-}
+}

+ 95 - 69
user/apps/test_seqpacket/src/seq_socket.rs

@@ -1,16 +1,14 @@
-
 use libc::*;
-use std::{fs, str};
 use std::ffi::CString;
 use std::io::Error;
 use std::mem;
 use std::os::unix::io::RawFd;
+use std::{fs, str};
 
 const SOCKET_PATH: &str = "/test.seqpacket";
 const MSG1: &str = "Hello, Unix SEQPACKET socket from Client!";
 const MSG2: &str = "Hello, Unix SEQPACKET socket from Server!";
 
-
 fn create_seqpacket_socket() -> Result<RawFd, Error> {
     unsafe {
         let fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
@@ -33,7 +31,12 @@ fn bind_socket(fd: RawFd) -> Result<(), Error> {
             addr.sun_path[i] = byte as i8;
         }
 
-        if bind(fd, &addr as *const _ as *const sockaddr, mem::size_of_val(&addr) as socklen_t) == -1 {
+        if bind(
+            fd,
+            &addr as *const _ as *const sockaddr,
+            mem::size_of_val(&addr) as socklen_t,
+        ) == -1
+        {
             return Err(Error::last_os_error());
         }
     }
@@ -68,7 +71,13 @@ fn accept_connection(fd: RawFd) -> Result<RawFd, Error> {
 fn send_message(fd: RawFd, msg: &str) -> Result<(), Error> {
     unsafe {
         let msg_bytes = msg.as_bytes();
-        if send(fd, msg_bytes.as_ptr() as *const libc::c_void, msg_bytes.len(), 0) == -1 {
+        if send(
+            fd,
+            msg_bytes.as_ptr() as *const libc::c_void,
+            msg_bytes.len(),
+            0,
+        ) == -1
+        {
             return Err(Error::last_os_error());
         }
     }
@@ -78,7 +87,12 @@ fn send_message(fd: RawFd, msg: &str) -> Result<(), Error> {
 fn receive_message(fd: RawFd) -> Result<String, Error> {
     let mut buffer = [0; 1024];
     unsafe {
-        let len = recv(fd, buffer.as_mut_ptr() as *mut libc::c_void, buffer.len(), 0);
+        let len = recv(
+            fd,
+            buffer.as_mut_ptr() as *mut libc::c_void,
+            buffer.len(),
+            0,
+        );
         if len == -1 {
             return Err(Error::last_os_error());
         }
@@ -86,70 +100,82 @@ fn receive_message(fd: RawFd) -> Result<String, Error> {
     }
 }
 
-pub fn test_seq_socket() ->Result<(), Error>{
-        // Create and bind the server socket
-        fs::remove_file(&SOCKET_PATH).ok();
-
-        let server_fd = create_seqpacket_socket()?;
-        bind_socket(server_fd)?;
-        listen_socket(server_fd)?;
-
-        // Accept connection in a separate thread
-        let server_thread = std::thread::spawn(move || {
-            let client_fd = accept_connection(server_fd).expect("Failed to accept connection");
-    
-            // Receive and print message
-            let received_msg = receive_message(client_fd).expect("Failed to receive message");
-            println!("Server: Received message: {}", received_msg);
-            
-            send_message(client_fd, MSG2).expect("Failed to send message");
-    
-            // Close client connection
-            unsafe { close(client_fd) };
-        });
-    
-        // Create and connect the client socket
-        let client_fd = create_seqpacket_socket()?;
-        unsafe {
-            let mut addr = sockaddr_un {
-                sun_family: AF_UNIX as u16,
-                sun_path: [0; 108],
-            };
-            let path_cstr = CString::new(SOCKET_PATH).unwrap();
-            let path_bytes = path_cstr.as_bytes();
-            // Convert u8 to i8
-            for (i, &byte) in path_bytes.iter().enumerate() {
-                addr.sun_path[i] = byte as i8;
-            }
-            if connect(client_fd, &addr as *const _ as *const sockaddr, mem::size_of_val(&addr) as socklen_t) == -1 {
-                return Err(Error::last_os_error());
-            }
-        }
-        send_message(client_fd, MSG1)?;
-        let received_msg = receive_message(client_fd).expect("Failed to receive message");
-        println!("Client: Received message: {}", received_msg);
-        // get peer_name
-        unsafe {
-            let mut addrss = sockaddr_un {
-                sun_family: AF_UNIX as u16,
-                sun_path: [0; 108],
-            };
-            let mut len = mem::size_of_val(&addrss) as socklen_t;
-            let res = getpeername(client_fd, &mut addrss as *mut _ as *mut sockaddr, &mut len);
-            if res == -1 {
-                return Err(Error::last_os_error());
-            }
-            let sun_path = addrss.sun_path.clone();
-            let peer_path:[u8;108] = sun_path.iter().map(|&x| x as u8).collect::<Vec<u8>>().try_into().unwrap();
-            println!("Client: Connected to server at path: {}", String::from_utf8_lossy(&peer_path));
+pub fn test_seq_socket() -> Result<(), Error> {
+    // Create and bind the server socket
+    fs::remove_file(&SOCKET_PATH).ok();
 
-        }
-            
-        server_thread.join().expect("Server thread panicked");
+    let server_fd = create_seqpacket_socket()?;
+    bind_socket(server_fd)?;
+    listen_socket(server_fd)?;
+
+    // Accept connection in a separate thread
+    let server_thread = std::thread::spawn(move || {
+        let client_fd = accept_connection(server_fd).expect("Failed to accept connection");
+
+        // Receive and print message
         let received_msg = receive_message(client_fd).expect("Failed to receive message");
-        println!("Client: Received message: {}", received_msg);
+        println!("Server: Received message: {}", received_msg);
+
+        send_message(client_fd, MSG2).expect("Failed to send message");
+
         // Close client connection
         unsafe { close(client_fd) };
-        fs::remove_file(&SOCKET_PATH).ok();
-        Ok(())
-}
+    });
+
+    // Create and connect the client socket
+    let client_fd = create_seqpacket_socket()?;
+    unsafe {
+        let mut addr = sockaddr_un {
+            sun_family: AF_UNIX as u16,
+            sun_path: [0; 108],
+        };
+        let path_cstr = CString::new(SOCKET_PATH).unwrap();
+        let path_bytes = path_cstr.as_bytes();
+        // Convert u8 to i8
+        for (i, &byte) in path_bytes.iter().enumerate() {
+            addr.sun_path[i] = byte as i8;
+        }
+        if connect(
+            client_fd,
+            &addr as *const _ as *const sockaddr,
+            mem::size_of_val(&addr) as socklen_t,
+        ) == -1
+        {
+            return Err(Error::last_os_error());
+        }
+    }
+    send_message(client_fd, MSG1)?;
+    let received_msg = receive_message(client_fd).expect("Failed to receive message");
+    println!("Client: Received message: {}", received_msg);
+    // get peer_name
+    unsafe {
+        let mut addrss = sockaddr_un {
+            sun_family: AF_UNIX as u16,
+            sun_path: [0; 108],
+        };
+        let mut len = mem::size_of_val(&addrss) as socklen_t;
+        let res = getpeername(client_fd, &mut addrss as *mut _ as *mut sockaddr, &mut len);
+        if res == -1 {
+            return Err(Error::last_os_error());
+        }
+        let sun_path = addrss.sun_path.clone();
+        let peer_path: [u8; 108] = sun_path
+            .iter()
+            .map(|&x| x as u8)
+            .collect::<Vec<u8>>()
+            .try_into()
+            .unwrap();
+        println!(
+            "Client: Connected to server at path: {}",
+            String::from_utf8_lossy(&peer_path)
+        );
+    }
+
+    server_thread.join().expect("Server thread panicked");
+    let received_msg = receive_message(client_fd).expect("Failed to receive message");
+    println!("Client: Received message: {}", received_msg);
+    // Close client connection
+    unsafe { close(client_fd) };
+    fs::remove_file(&SOCKET_PATH).ok();
+    Ok(())
+}

+ 46 - 18
user/apps/test_unix_stream_socket/src/main.rs

@@ -1,19 +1,19 @@
-use std::io::Error;
-use std::os::fd::RawFd;
-use std::fs;
 use libc::*;
 use std::ffi::CString;
+use std::fs;
+use std::io::Error;
 use std::mem;
+use std::os::fd::RawFd;
 
 const SOCKET_PATH: &str = "/test.stream";
 const MSG1: &str = "Hello, unix stream socket from Client!";
 const MSG2: &str = "Hello, unix stream socket from Server!";
 
-fn create_stream_socket() -> Result<RawFd, Error>{
+fn create_stream_socket() -> Result<RawFd, Error> {
     unsafe {
         let fd = socket(AF_UNIX, SOCK_STREAM, 0);
         if fd == -1 {
-            return Err(Error::last_os_error())
+            return Err(Error::last_os_error());
         }
         Ok(fd)
     }
@@ -31,7 +31,12 @@ fn bind_socket(fd: RawFd) -> Result<(), Error> {
             addr.sun_path[i] = byte as i8;
         }
 
-        if bind(fd, &addr as *const _ as *const sockaddr, mem::size_of_val(&addr) as socklen_t) == -1 {
+        if bind(
+            fd,
+            &addr as *const _ as *const sockaddr,
+            mem::size_of_val(&addr) as socklen_t,
+        ) == -1
+        {
             return Err(Error::last_os_error());
         }
     }
@@ -61,7 +66,13 @@ fn accept_conn(fd: RawFd) -> Result<RawFd, Error> {
 fn send_message(fd: RawFd, msg: &str) -> Result<(), Error> {
     unsafe {
         let msg_bytes = msg.as_bytes();
-        if send(fd, msg_bytes.as_ptr() as *const libc::c_void, msg_bytes.len(), 0)== -1 {
+        if send(
+            fd,
+            msg_bytes.as_ptr() as *const libc::c_void,
+            msg_bytes.len(),
+            0,
+        ) == -1
+        {
             return Err(Error::last_os_error());
         }
     }
@@ -71,7 +82,12 @@ fn send_message(fd: RawFd, msg: &str) -> Result<(), Error> {
 fn recv_message(fd: RawFd) -> Result<String, Error> {
     let mut buffer = [0; 1024];
     unsafe {
-        let len = recv(fd, buffer.as_mut_ptr() as *mut libc::c_void, buffer.len(),0);
+        let len = recv(
+            fd,
+            buffer.as_mut_ptr() as *mut libc::c_void,
+            buffer.len(),
+            0,
+        );
         if len == -1 {
             return Err(Error::last_os_error());
         }
@@ -82,7 +98,7 @@ fn recv_message(fd: RawFd) -> Result<String, Error> {
 fn test_stream() -> Result<(), Error> {
     fs::remove_file(&SOCKET_PATH).ok();
 
-    let server_fd =  create_stream_socket()?;
+    let server_fd = create_stream_socket()?;
     bind_socket(server_fd)?;
     listen_socket(server_fd)?;
 
@@ -95,7 +111,7 @@ fn test_stream() -> Result<(), Error> {
         send_message(client_fd, MSG2).expect("Failed to send message");
         println!("Server send finish");
 
-        unsafe {close(client_fd)};
+        unsafe { close(client_fd) };
     });
 
     let client_fd = create_stream_socket()?;
@@ -111,9 +127,14 @@ fn test_stream() -> Result<(), Error> {
             addr.sun_path[i] = byte as i8;
         }
 
-        if connect(client_fd, &addr as *const _ as *const sockaddr, mem::size_of_val(&addr) as socklen_t) == -1 {
+        if connect(
+            client_fd,
+            &addr as *const _ as *const sockaddr,
+            mem::size_of_val(&addr) as socklen_t,
+        ) == -1
+        {
             return Err(Error::last_os_error());
-        } 
+        }
     }
 
     send_message(client_fd, MSG1)?;
@@ -129,9 +150,16 @@ fn test_stream() -> Result<(), Error> {
             return Err(Error::last_os_error());
         }
         let sun_path = addrss.sun_path.clone();
-        let peer_path:[u8;108] = sun_path.iter().map(|&x| x as u8).collect::<Vec<u8>>().try_into().unwrap();
-        println!("Client: Connected to server at path: {}", String::from_utf8_lossy(&peer_path));
-
+        let peer_path: [u8; 108] = sun_path
+            .iter()
+            .map(|&x| x as u8)
+            .collect::<Vec<u8>>()
+            .try_into()
+            .unwrap();
+        println!(
+            "Client: Connected to server at path: {}",
+            String::from_utf8_lossy(&peer_path)
+        );
     }
 
     server_thread.join().expect("Server thread panicked");
@@ -139,7 +167,7 @@ fn test_stream() -> Result<(), Error> {
     let recv_msg = recv_message(client_fd).expect("Failed to receive message from server");
     println!("Client Received message: {}", recv_msg);
 
-    unsafe {close(client_fd)};
+    unsafe { close(client_fd) };
     fs::remove_file(&SOCKET_PATH).ok();
 
     Ok(())
@@ -148,6 +176,6 @@ fn test_stream() -> Result<(), Error> {
 fn main() {
     match test_stream() {
         Ok(_) => println!("test for unix stream success"),
-        Err(_) => println!("test for unix stream failed")
+        Err(_) => println!("test for unix stream failed"),
     }
-}
+}