瀏覽代碼

feat: 支持动态链接 (#910)

* feat: 支持动态链接

Authored-By: chiichen <chiichen@qq.com>
Co-authored-by: longjin <longjin@DragonOS.org>
Signed-off-by: longjin <longjin@DragonOS.org>

* build: 更新构建容器版本至v1.12并指定DADK安装版本

- 将BUILD_CONTAINER_VERSION从v1.11升级到v1.12
- 修改bootstrap.sh和user/Makefile中DADK的安装方式,明确指定版本v0.4.0

Signed-off-by: longjin <longjin@DragonOS.org>

---------

Signed-off-by: longjin <longjin@dragonos.org>
Co-authored-by: chiichen <chiichen@qq.com>
Co-authored-by: longjin <longjin@dragonos.org>
Co-authored-by: Jomo <xuzihao@dragonos.org>
Co-authored-by: MemoryShore <1353318529@qq.com>
chiichen 2 天之前
父節點
當前提交
fccfa6f7ff

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

@@ -11,14 +11,14 @@ jobs:
     name: Format check ${{ matrix.arch }}
     runs-on: ubuntu-latest
     continue-on-error: true
-    container: dragonos/dragonos-dev:v1.11
+    container: dragonos/dragonos-dev:v1.12
 
     strategy:
       matrix:
         arch: [x86_64, riscv64, loongarch64]
 
     steps:
-      - run: echo "Running in dragonos/dragonos-dev:v1.11"
+      - run: echo "Running in dragonos/dragonos-dev:v1.12"
       - 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.11
+    container: dragonos/dragonos-dev:v1.12
 
     strategy:
       matrix:
         arch: [x86_64, riscv64, loongarch64]
 
     steps:
-      - run: echo "Running in dragonos/dragonos-dev:v1.11"
+      - run: echo "Running in dragonos/dragonos-dev:v1.12"
 
       - uses: actions/checkout@v3
 
@@ -56,7 +56,7 @@ jobs:
   build:
     name: Build ${{ matrix.arch }}
     runs-on: ubuntu-latest
-    container: dragonos/dragonos-dev:v1.11
+    container: dragonos/dragonos-dev:v1.12
     continue-on-error: true
     strategy:
       matrix:
@@ -73,7 +73,7 @@ jobs:
             checkout_params: {}
 
     steps:
-      - run: echo "Running in dragonos/dragonos-dev:v1.11"
+      - run: echo "Running in dragonos/dragonos-dev:v1.12"
       
       - uses: actions/checkout@v3
         with: ${{ matrix.checkout_params }}

+ 4 - 0
kernel/src/arch/x86_64/mm/fault.rs

@@ -177,6 +177,10 @@ impl X86_64MMArch {
         error_code: X86PfErrorCode,
         address: VirtAddr,
     ) {
+        // log::debug!("fault at {:?}:{:?}",
+        // address,
+        // error_code,
+        // );
         let rflags = RFlags::from_bits_truncate(regs.rflags);
         let mut flags: FaultFlags = FaultFlags::FAULT_FLAG_ALLOW_RETRY
             | FaultFlags::FAULT_FLAG_KILLABLE

+ 12 - 2
kernel/src/arch/x86_64/process/syscall.rs

@@ -53,6 +53,7 @@ impl Syscall {
     }
 
     /// ## 用于控制和查询与体系结构相关的进程特定选项
+    /// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/kernel/process_64.c#913
     pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
         let pcb = ProcessManager::current_pcb();
         if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) {
@@ -109,8 +110,17 @@ impl Syscall {
     }
 
     #[allow(dead_code)]
-    pub fn do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError> {
-        todo!("do_arch_prctl_common not unimplemented");
+    pub fn do_arch_prctl_common(option: usize, arg2: usize) -> Result<usize, SystemError> {
+        // Don't use 0x3001-0x3004 because of old glibcs
+        if (0x3001..=0x3004).contains(&option) {
+            return Err(SystemError::EINVAL);
+        }
+
+        todo!(
+            "do_arch_prctl_common not unimplemented, option: {}, arg2: {}",
+            option,
+            arg2
+        );
     }
 }
 

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

@@ -90,7 +90,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
     mfence();
     let pid = ProcessManager::current_pcb().pid();
     let show = false;
-    // let show = if syscall_num != SYS_SCHED && pid.data() >= 7 {
+    // let show = if syscall_num != SYS_SCHED && pid.data() >= 9{
     //     true
     // } else {
     //     false

+ 1 - 1
kernel/src/debug/panic/mod.rs

@@ -1,4 +1,4 @@
-mod hook;
+pub mod hook;
 use alloc::boxed::Box;
 use cfg_if::cfg_if;
 

+ 1 - 0
kernel/src/driver/base/device/dd.rs

@@ -144,6 +144,7 @@ impl DeviceManager {
     /// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功
     ///
     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899
+    #[inline(never)]
     fn do_device_attach_driver(
         &self,
         driver: &Arc<dyn Driver>,

+ 0 - 1
kernel/src/filesystem/fat/fs.rs

@@ -1452,7 +1452,6 @@ impl IndexNode for LockedFATInode {
         let page_cache = self.0.lock().page_cache.clone();
         if let Some(page_cache) = page_cache {
             let r = page_cache.lock_irqsave().read(offset, &mut buf[0..len]);
-            // self.0.lock_irqsave().update_metadata();
             return r;
         } else {
             return self.read_direct(offset, len, buf, data);

+ 11 - 2
kernel/src/filesystem/page_cache.rs

@@ -113,13 +113,14 @@ impl InnerPageCache {
     /// - `Ok(usize)` 成功读取的长度
     /// - `Err(SystemError)` 失败返回错误码
     pub fn read(&mut self, offset: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
-        let inode = self
+        let inode: Arc<dyn IndexNode> = self
             .page_cache_ref
             .upgrade()
             .unwrap()
             .inode
             .upgrade()
             .unwrap();
+
         let file_size = inode.metadata().unwrap().size;
 
         let len = if offset < file_size as usize {
@@ -182,6 +183,7 @@ impl InnerPageCache {
         for (page_index, count) in not_exist {
             // TODO 这里使用buffer避免多次读取磁盘,将来引入异步IO直接写入页面,减少内存开销和拷贝
             let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count];
+
             inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?;
 
             self.create_pages(page_index, page_buf.as_mut())?;
@@ -314,7 +316,7 @@ impl InnerPageCache {
 
 impl Drop for InnerPageCache {
     fn drop(&mut self) {
-        log::debug!("page cache drop");
+        // log::debug!("page cache drop");
         let mut page_manager = page_manager_lock_irqsave();
         for page in self.pages.values() {
             page_manager.remove_page(&page.phys_address());
@@ -358,6 +360,13 @@ impl PageCache {
     }
 
     pub fn lock_irqsave(&self) -> SpinLockGuard<InnerPageCache> {
+        if self.inner.is_locked() {
+            log::error!("page cache already locked");
+        }
         self.inner.lock_irqsave()
     }
+
+    pub fn is_locked(&self) -> bool {
+        self.inner.is_locked()
+    }
 }

+ 2 - 1
kernel/src/filesystem/vfs/open.rs

@@ -42,6 +42,7 @@ pub(super) fn do_faccessat(
 
     let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
     let path = path.to_str().map_err(|_| SystemError::EINVAL)?;
+    // log::debug!("do_faccessat path: {:?}", path);
 
     let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
 
@@ -166,7 +167,7 @@ fn do_sys_openat2(
     how: OpenHow,
     follow_symlink: bool,
 ) -> Result<usize, SystemError> {
-    // debug!("open path: {}, how: {:?}", path, how);
+    // log::debug!("openat2: dirfd: {}, path: {}, how: {:?}",dirfd, path, how);
     let path = path.trim();
 
     let (inode_begin, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;

+ 2 - 65
kernel/src/filesystem/vfs/stat.rs

@@ -273,6 +273,7 @@ pub fn vfs_getattr(
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#274
 #[inline(never)]
 pub fn vfs_fstatat(dfd: i32, filename: &str, flags: AtFlags) -> Result<KStat, SystemError> {
+    // log::debug!("vfs_fstatat: dfd={}, filename={}", dfd, filename);
     let statx_flags = flags | AtFlags::AT_NO_AUTOMOUNT;
     if dfd >= 0 && flags == AtFlags::AT_EMPTY_PATH {
         return vfs_fstat(dfd);
@@ -322,7 +323,7 @@ pub(super) fn do_newfstatat(
 
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#393
 #[inline(never)]
-fn cp_new_stat(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> {
+pub(super) fn cp_new_stat(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> {
     let posix_stat = PosixStat::try_from(kstat)?;
     let mut ubuf_writer =
         UserBufferWriter::new(user_buf_ptr as *mut PosixStat, size_of::<PosixStat>(), true)?;
@@ -397,70 +398,6 @@ fn cp_statx(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> {
     Ok(())
 }
 
-// 注意!这个结构体定义的貌似不太对,需要修改!
-#[repr(C)]
-#[derive(Clone, Copy)]
-/// # 文件信息结构体
-pub struct PosixKstat {
-    /// 硬件设备ID
-    pub dev_id: u64,
-    /// inode号
-    pub inode: u64,
-    /// 硬链接数
-    pub nlink: u64,
-    /// 文件权限
-    pub mode: ModeType,
-    /// 所有者用户ID
-    pub uid: i32,
-    /// 所有者组ID
-    pub gid: i32,
-    /// 设备ID
-    pub rdev: i64,
-    /// 文件大小
-    pub size: i64,
-    /// 文件系统块大小
-    pub blcok_size: i64,
-    /// 分配的512B块数
-    pub blocks: u64,
-    /// 最后访问时间
-    pub atime: PosixTimeSpec,
-    /// 最后修改时间
-    pub mtime: PosixTimeSpec,
-    /// 最后状态变化时间
-    pub ctime: PosixTimeSpec,
-    /// 用于填充结构体大小的空白数据
-    pub _pad: [i8; 24],
-}
-impl PosixKstat {
-    pub(super) fn new() -> Self {
-        Self {
-            inode: 0,
-            dev_id: 0,
-            mode: ModeType::empty(),
-            nlink: 0,
-            uid: 0,
-            gid: 0,
-            rdev: 0,
-            size: 0,
-            atime: PosixTimeSpec {
-                tv_sec: 0,
-                tv_nsec: 0,
-            },
-            mtime: PosixTimeSpec {
-                tv_sec: 0,
-                tv_nsec: 0,
-            },
-            ctime: PosixTimeSpec {
-                tv_sec: 0,
-                tv_nsec: 0,
-            },
-            blcok_size: 0,
-            blocks: 0,
-            _pad: Default::default(),
-        }
-    }
-}
-
 /// 通用的PosixStat
 #[allow(unused)]
 #[repr(C)]

+ 18 - 56
kernel/src/filesystem/vfs/syscall/mod.rs

@@ -21,7 +21,7 @@ use crate::{
     time::{syscall::PosixTimeval, PosixTimeSpec},
 };
 
-use super::stat::{do_newfstatat, do_statx, PosixKstat};
+use super::stat::{do_newfstatat, do_statx, vfs_fstat};
 use super::vcore::do_symlinkat;
 use super::{
     fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
@@ -1211,79 +1211,31 @@ impl Syscall {
         return Err(SystemError::EBADF);
     }
 
-    fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> {
-        let binding = ProcessManager::current_pcb().fd_table();
-        let fd_table_guard = binding.read();
-        let file = fd_table_guard
-            .get_file_by_fd(fd)
-            .ok_or(SystemError::EBADF)?;
-        // drop guard 以避免无法调度的问题
-        drop(fd_table_guard);
-
-        let mut kstat = PosixKstat::new();
-        // 获取文件信息
-        let metadata = file.metadata()?;
-        kstat.size = metadata.size;
-        kstat.dev_id = metadata.dev_id as u64;
-        kstat.inode = metadata.inode_id.into() as u64;
-        kstat.blcok_size = metadata.blk_size as i64;
-        kstat.blocks = metadata.blocks as u64;
-
-        kstat.atime.tv_sec = metadata.atime.tv_sec;
-        kstat.atime.tv_nsec = metadata.atime.tv_nsec;
-        kstat.mtime.tv_sec = metadata.mtime.tv_sec;
-        kstat.mtime.tv_nsec = metadata.mtime.tv_nsec;
-        kstat.ctime.tv_sec = metadata.ctime.tv_sec;
-        kstat.ctime.tv_nsec = metadata.ctime.tv_nsec;
-
-        kstat.nlink = metadata.nlinks as u64;
-        kstat.uid = metadata.uid as i32;
-        kstat.gid = metadata.gid as i32;
-        kstat.rdev = metadata.raw_dev.data() as i64;
-        kstat.mode = metadata.mode;
-        match file.file_type() {
-            FileType::File => kstat.mode.insert(ModeType::S_IFREG),
-            FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
-            FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK),
-            FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR),
-            FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK),
-            FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK),
-            FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO),
-            FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR),
-            FileType::FramebufferDevice => kstat.mode.insert(ModeType::S_IFCHR),
-        }
-
-        return Ok(kstat);
-    }
-
-    pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
-        let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixKstat>(), true)?;
-        let kstat = Self::do_fstat(fd)?;
-
-        writer.copy_one_to_user(&kstat, 0)?;
-        return Ok(0);
+    #[inline(never)]
+    pub fn fstat(fd: i32, user_stat_ptr: usize) -> Result<usize, SystemError> {
+        Self::newfstat(fd, user_stat_ptr)
     }
 
-    pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
+    pub fn stat(path: *const u8, user_stat_ptr: usize) -> Result<usize, SystemError> {
         let fd = Self::open(
             path,
             FileMode::O_RDONLY.bits(),
             ModeType::empty().bits(),
             true,
         )?;
-        let r = Self::fstat(fd as i32, user_kstat);
+        let r = Self::fstat(fd as i32, user_stat_ptr);
         Self::close(fd).ok();
         return r;
     }
 
-    pub fn lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
+    pub fn lstat(path: *const u8, user_stat_ptr: usize) -> Result<usize, SystemError> {
         let fd = Self::open(
             path,
             FileMode::O_RDONLY.bits(),
             ModeType::empty().bits(),
             false,
         )?;
-        let r = Self::fstat(fd as i32, user_kstat);
+        let r = Self::fstat(fd as i32, user_stat_ptr);
         Self::close(fd).ok();
         return r;
     }
@@ -1356,6 +1308,16 @@ impl Syscall {
         do_newfstatat(dfd, filename_str, user_stat_buf_ptr, flags).map(|_| 0)
     }
 
+    #[inline(never)]
+    pub fn newfstat(fd: i32, user_stat_buf_ptr: usize) -> Result<usize, SystemError> {
+        if user_stat_buf_ptr == 0 {
+            return Err(SystemError::EFAULT);
+        }
+        let stat = vfs_fstat(fd)?;
+        // log::debug!("newfstat fd: {}, stat.size: {:?}",fd,stat.size);
+        super::stat::cp_new_stat(stat, user_stat_buf_ptr).map(|_| 0)
+    }
+
     pub fn mknod(
         path: *const u8,
         mode: ModeType,

+ 260 - 94
kernel/src/libs/elf.rs

@@ -7,10 +7,10 @@ use core::{
 
 use alloc::vec::Vec;
 use elf::{
-    abi::{PT_GNU_PROPERTY, PT_INTERP},
+    abi::{ET_DYN, ET_EXEC, PT_GNU_PROPERTY, PT_INTERP, PT_LOAD},
     endian::AnyEndian,
     file::FileHeader,
-    segment::ProgramHeader,
+    segment::{ProgramHeader, SegmentTable},
 };
 use log::error;
 use system_error::SystemError;
@@ -18,7 +18,6 @@ use system_error::SystemError;
 use crate::{
     arch::{CurrentElfArch, MMArch},
     driver::base::block::SeekFrom,
-    filesystem::vfs::file::File,
     libs::align::page_align_up,
     mm::{
         allocator::page_frame::{PageFrameCount, VirtPageFrame},
@@ -28,7 +27,9 @@ use crate::{
     },
     process::{
         abi::AtType,
-        exec::{BinaryLoader, BinaryLoaderResult, ExecError, ExecLoadMode, ExecParam},
+        exec::{
+            BinaryLoader, BinaryLoaderResult, ExecError, ExecLoadMode, ExecParam, ExecParamFlags,
+        },
         ProcessFlags, ProcessManager,
     },
     syscall::user_access::{clear_user, copy_to_user},
@@ -134,8 +135,8 @@ impl ElfLoader {
         end: VirtAddr,
         prot_flags: ProtFlags,
     ) -> Result<(), ExecError> {
-        let start = self.elf_page_start(start);
-        let end = self.elf_page_align_up(end);
+        let start = Self::elf_page_start(start);
+        let end = Self::elf_page_align_up(end);
         // debug!("set_elf_brk: start={:?}, end={:?}", start, end);
         if end > start {
             let r = user_vm_guard.map_anonymous(
@@ -158,15 +159,15 @@ impl ElfLoader {
     }
 
     /// 计算addr在ELF PAGE内的偏移
-    fn elf_page_offset(&self, addr: VirtAddr) -> usize {
+    fn elf_page_offset(addr: VirtAddr) -> usize {
         addr.data() & (CurrentElfArch::ELF_PAGE_SIZE - 1)
     }
 
-    fn elf_page_start(&self, addr: VirtAddr) -> VirtAddr {
+    fn elf_page_start(addr: VirtAddr) -> VirtAddr {
         VirtAddr::new(addr.data() & (!(CurrentElfArch::ELF_PAGE_SIZE - 1)))
     }
 
-    fn elf_page_align_up(&self, addr: VirtAddr) -> VirtAddr {
+    fn elf_page_align_up(addr: VirtAddr) -> VirtAddr {
         VirtAddr::new(
             (addr.data() + CurrentElfArch::ELF_PAGE_SIZE - 1)
                 & (!(CurrentElfArch::ELF_PAGE_SIZE - 1)),
@@ -174,7 +175,7 @@ impl ElfLoader {
     }
 
     /// 根据ELF的p_flags生成对应的ProtFlags
-    fn make_prot(&self, p_flags: u32, _has_interpreter: bool, _is_interpreter: bool) -> ProtFlags {
+    fn make_prot(p_flags: u32, _has_interpreter: bool, _is_interpreter: bool) -> ProtFlags {
         let mut prot = ProtFlags::empty();
         if p_flags & elf::abi::PF_R != 0 {
             prot |= ProtFlags::PROT_READ;
@@ -211,7 +212,6 @@ impl ElfLoader {
     /// - `Ok((VirtAddr, bool))`:如果成功加载,则bool值为true,否则为false. VirtAddr为加载的地址
     #[allow(clippy::too_many_arguments)]
     fn load_elf_segment(
-        &self,
         user_vm_guard: &mut RwLockWriteGuard<'_, InnerAddressSpace>,
         param: &mut ExecParam,
         phent: &ProgramHeader,
@@ -223,11 +223,11 @@ impl ElfLoader {
         // debug!("load_elf_segment: addr_to_map={:?}", addr_to_map);
 
         // 映射位置的偏移量(页内偏移)
-        let beginning_page_offset = self.elf_page_offset(addr_to_map);
-        addr_to_map = self.elf_page_start(addr_to_map);
+        let beginning_page_offset = Self::elf_page_offset(addr_to_map);
+        addr_to_map = Self::elf_page_start(addr_to_map);
         // 计算要映射的内存的大小
         let map_size = phent.p_filesz as usize + beginning_page_offset;
-        let map_size = self.elf_page_align_up(VirtAddr::new(map_size)).data();
+        let map_size = Self::elf_page_align_up(VirtAddr::new(map_size)).data();
         // 当前段在文件中的大小
         let seg_in_file_size = phent.p_filesz as usize;
         // 当前段在文件中的偏移量
@@ -266,7 +266,9 @@ impl ElfLoader {
         // So we first map the 'big' image - and unmap the remainder at
         // the end. (which unmap is needed for ELF images with holes.)
         if total_size != 0 {
-            let total_size = self.elf_page_align_up(VirtAddr::new(total_size)).data();
+            let total_size = Self::elf_page_align_up(VirtAddr::new(total_size)).data();
+
+            // log::debug!("total_size={}", total_size);
 
             map_addr = user_vm_guard
                 .map_anonymous(addr_to_map, total_size, tmp_prot, *map_flags, false, true)
@@ -282,7 +284,7 @@ impl ElfLoader {
             )?;
 
             // 加载文件到内存
-            self.do_load_file(
+            Self::do_load_file(
                 map_addr + beginning_page_offset,
                 seg_in_file_size,
                 file_offset,
@@ -307,7 +309,7 @@ impl ElfLoader {
             // );
 
             // 加载文件到内存
-            self.do_load_file(
+            Self::do_load_file(
                 map_addr + beginning_page_offset,
                 seg_in_file_size,
                 file_offset,
@@ -326,6 +328,152 @@ impl ElfLoader {
         return Ok((map_addr, true));
     }
 
+    /// 加载elf动态链接器
+    ///
+    /// ## 参数
+    ///
+    /// - `interp_elf_ex`:动态链接器
+    /// - `load_bias`偏移量
+    ///
+    /// ## TODO
+    ///
+    /// 添加一个Arch state抽象,描述架构相关的elf state(参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#592)
+    fn load_elf_interp(
+        interp_elf_ex: &mut ExecParam,
+        load_bias: usize,
+    ) -> Result<BinaryLoaderResult, ExecError> {
+        // log::debug!("loading elf interp");
+        let mut head_buf = [0u8; 512];
+        interp_elf_ex
+            .file_mut()
+            .lseek(SeekFrom::SeekSet(0))
+            .map_err(|_| ExecError::NotSupported)?;
+        let _bytes = interp_elf_ex
+            .file_mut()
+            .read(512, &mut head_buf)
+            .map_err(|_| ExecError::NotSupported)?;
+        let interp_hdr =
+            Self::parse_ehdr(head_buf.as_ref()).map_err(|_| ExecError::NotExecutable)?;
+        if interp_hdr.e_type != ET_EXEC && interp_hdr.e_type != ET_DYN {
+            return Err(ExecError::NotExecutable);
+        }
+        let mut phdr_buf = Vec::new();
+        let phdr_table = Self::parse_segments(interp_elf_ex, &interp_hdr, &mut phdr_buf)
+            .map_err(|_| ExecError::ParseError)?
+            .ok_or(ExecError::ParseError)?;
+        //TODO 架构相关检查 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#610
+        let mut total_size = Self::total_mapping_size(&phdr_table);
+
+        if total_size == 0 {
+            return Err(ExecError::InvalidParemeter);
+        }
+
+        let mut load_addr_set = false;
+        let mut load_addr: VirtAddr = VirtAddr::new(0);
+        let mut elf_bss: VirtAddr = VirtAddr::new(0);
+        let mut last_bss: VirtAddr = VirtAddr::new(0);
+        let mut bss_prot: Option<ProtFlags> = None;
+        for section in phdr_table {
+            if section.p_type == PT_LOAD {
+                // log::debug!("loading {:?}", section);
+                let mut elf_type = MapFlags::MAP_PRIVATE;
+                let elf_prot = Self::make_prot(section.p_flags, true, true);
+                let vaddr = TryInto::<usize>::try_into(section.p_vaddr).unwrap();
+                let mut addr_to_map = load_addr + vaddr;
+                if interp_hdr.e_type == ET_EXEC || load_addr_set {
+                    elf_type.insert(MapFlags::MAP_FIXED)
+                } else if load_bias != 0 && interp_hdr.e_type == ET_DYN {
+                    addr_to_map = VirtAddr::new(0);
+                }
+                let map_addr = Self::load_elf_segment(
+                    &mut interp_elf_ex.vm().clone().write(),
+                    interp_elf_ex,
+                    &section,
+                    addr_to_map,
+                    &elf_prot,
+                    &elf_type,
+                    total_size,
+                )
+                .map_err(|e| {
+                    log::error!("Failed to load elf interpreter :{:?}", e);
+                    return ExecError::InvalidParemeter;
+                })?;
+                if !map_addr.1 {
+                    return Err(ExecError::BadAddress(Some(map_addr.0)));
+                }
+                let map_addr = map_addr.0;
+                total_size = 0;
+                if !load_addr_set && interp_hdr.e_type == ET_DYN {
+                    load_addr =
+                        VirtAddr::new(map_addr - Self::elf_page_start(VirtAddr::new(vaddr)));
+                    load_addr_set = true;
+                }
+                let addr = load_addr + TryInto::<usize>::try_into(section.p_vaddr).unwrap();
+                if addr >= MMArch::USER_END_VADDR
+                    || section.p_filesz > section.p_memsz
+                    || TryInto::<usize>::try_into(section.p_memsz).unwrap()
+                        > MMArch::USER_END_VADDR.data()
+                    || MMArch::USER_END_VADDR - TryInto::<usize>::try_into(section.p_memsz).unwrap()
+                        < addr
+                {
+                    return Err(ExecError::OutOfMemory);
+                }
+
+                let addr = load_addr
+                    + TryInto::<usize>::try_into(section.p_vaddr + section.p_filesz).unwrap();
+                if addr > elf_bss {
+                    elf_bss = addr;
+                }
+
+                let addr = load_addr
+                    + TryInto::<usize>::try_into(section.p_vaddr + section.p_memsz).unwrap();
+                if addr > last_bss {
+                    last_bss = addr;
+                    bss_prot = Some(elf_prot);
+                }
+            }
+        }
+        Self::pad_zero(elf_bss).map_err(|_| return ExecError::BadAddress(Some(elf_bss)))?;
+        elf_bss = Self::elf_page_align_up(elf_bss);
+        last_bss = Self::elf_page_align_up(last_bss);
+        if last_bss > elf_bss {
+            if bss_prot.is_none() {
+                return Err(ExecError::InvalidParemeter);
+            }
+            let mut bss_prot = bss_prot.unwrap();
+            if bss_prot.contains(ProtFlags::PROT_EXEC) {
+                bss_prot = ProtFlags::PROT_EXEC;
+            } else {
+                bss_prot = ProtFlags::PROT_NONE;
+            }
+            interp_elf_ex
+                .vm()
+                .clone()
+                .write()
+                .map_anonymous(
+                    elf_bss,
+                    last_bss - elf_bss,
+                    bss_prot,
+                    MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED_NOREPLACE,
+                    false,
+                    true,
+                )
+                .map_err(|e| match e {
+                    SystemError::EINVAL => ExecError::InvalidParemeter,
+                    SystemError::ENOMEM => ExecError::OutOfMemory,
+                    _ => return ExecError::InvalidParemeter,
+                })?;
+        }
+        load_addr += TryInto::<usize>::try_into(interp_hdr.e_entry).unwrap();
+        if load_addr > MMArch::USER_END_VADDR {
+            return Err(ExecError::BadAddress(Some(
+                load_addr + TryInto::<usize>::try_into(interp_hdr.e_entry).unwrap(),
+            )));
+        }
+        // log::debug!("sucessfully load elf interp");
+        return Ok(BinaryLoaderResult::new(load_addr));
+    }
+
     /// 加载ELF文件到用户空间
     ///
     /// ## 参数
@@ -335,7 +483,6 @@ impl ElfLoader {
     /// - `offset_in_file`:在文件内的偏移量
     /// - `param`:执行参数
     fn do_load_file(
-        &self,
         mut vaddr: VirtAddr,
         size: usize,
         offset_in_file: usize,
@@ -367,8 +514,8 @@ impl ElfLoader {
     }
 
     /// 我们需要显式的把数据段之后剩余的内存页都清零。
-    fn pad_zero(&self, elf_bss: VirtAddr) -> Result<(), SystemError> {
-        let nbyte = self.elf_page_offset(elf_bss);
+    fn pad_zero(elf_bss: VirtAddr) -> Result<(), SystemError> {
+        let nbyte = Self::elf_page_offset(elf_bss);
         if nbyte > 0 {
             let nbyte = CurrentElfArch::ELF_PAGE_SIZE - nbyte;
             unsafe { clear_user(elf_bss, nbyte).map_err(|_| SystemError::EFAULT) }?;
@@ -376,6 +523,37 @@ impl ElfLoader {
         return Ok(());
     }
 
+    /// 参考https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#1158,获取要加载的total_size
+    fn total_mapping_size(ehdr_table: &SegmentTable<'_, AnyEndian>) -> usize {
+        let mut has_load = false;
+        let mut min_address = VirtAddr::new(usize::MAX);
+        let mut max_address = VirtAddr::new(0usize);
+        let loadable_sections = ehdr_table
+            .into_iter()
+            .filter(|seg| seg.p_type == elf::abi::PT_LOAD);
+        for seg_to_load in loadable_sections {
+            min_address = min(
+                min_address,
+                Self::elf_page_start(VirtAddr::new(seg_to_load.p_vaddr.try_into().unwrap())),
+            );
+            max_address = max(
+                max_address,
+                VirtAddr::new(
+                    (seg_to_load.p_vaddr + seg_to_load.p_memsz)
+                        .try_into()
+                        .unwrap(),
+                ),
+            );
+            has_load = true;
+        }
+        let total_size = if has_load {
+            max_address - min_address
+        } else {
+            0
+        };
+        return total_size;
+    }
+
     /// 创建auxv
     ///
     /// ## 参数
@@ -562,7 +740,7 @@ impl BinaryLoader for ElfLoader {
             .map_err(|_| ExecError::ParseError)?
             .ok_or(ExecError::ParseError)?;
         let mut _gnu_property_data: Option<ProgramHeader> = None;
-        let interpreter: Option<File> = None;
+        let mut interpreter: Option<ExecParam> = None;
         for seg in phdr_table {
             if seg.p_type == PT_GNU_PROPERTY {
                 _gnu_property_data = Some(seg);
@@ -594,8 +772,8 @@ impl BinaryLoader for ElfLoader {
                 log::error!("Failed to load interpreter ");
                 return Err(ExecError::NotSupported);
             }
-            let _interpreter_path = core::str::from_utf8(
-                &buffer[0..TryInto::<usize>::try_into(seg.p_filesz).unwrap() - 1], //
+            let interpreter_path = core::str::from_utf8(
+                &buffer[0..TryInto::<usize>::try_into(seg.p_filesz).unwrap() - 1],
             )
             .map_err(|e| {
                 ExecError::Other(format!(
@@ -603,9 +781,17 @@ impl BinaryLoader for ElfLoader {
                     e
                 ))
             })?;
-
-            //TODO 加入对动态链接器的加载,参照 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#890
+            // log::debug!("opening interpreter at :{}", interpreter_path);
+            interpreter = Some(
+                ExecParam::new(interpreter_path, param.vm().clone(), ExecParamFlags::EXEC)
+                    .map_err(|e| {
+                        log::error!("Failed to load interpreter {interpreter_path}: {:?}", e);
+                        return ExecError::NotSupported;
+                    })?,
+            );
         }
+        //TODO 缺少一部分逻辑 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#931
+
         if interpreter.is_some() {
             /* Some simple consistency checks for the interpreter */
             // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#950
@@ -627,39 +813,14 @@ impl BinaryLoader for ElfLoader {
         // program header的虚拟地址
         let mut phdr_vaddr: Option<VirtAddr> = None;
         let mut _reloc_func_desc = 0usize;
-        // 参考https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#1158,获取要加载的total_size
-        let mut has_load = false;
-        let mut min_address = VirtAddr::new(usize::MAX);
-        let mut max_address = VirtAddr::new(0usize);
-        let loadable_sections = phdr_table
-            .into_iter()
-            .filter(|seg| seg.p_type == elf::abi::PT_LOAD);
 
-        for seg_to_load in loadable_sections {
-            min_address = min(
-                min_address,
-                self.elf_page_start(VirtAddr::new(seg_to_load.p_vaddr.try_into().unwrap())),
-            );
-            max_address = max(
-                max_address,
-                VirtAddr::new(
-                    (seg_to_load.p_vaddr + seg_to_load.p_memsz)
-                        .try_into()
-                        .unwrap(),
-                ),
-            );
-            has_load = true;
-        }
-        let total_size = if has_load {
-            max_address - min_address
-        } else {
-            0
-        };
+        let total_size = Self::total_mapping_size(&phdr_table);
         let loadable_sections = phdr_table
             .into_iter()
             .filter(|seg| seg.p_type == elf::abi::PT_LOAD);
+
         for seg_to_load in loadable_sections {
-            // debug!("seg_to_load = {:?}", seg_to_load);
+            // log::debug!("seg_to_load = {:?}", seg_to_load);
             if unlikely(elf_brk > elf_bss) {
                 // debug!(
                 //     "to set brk, elf_brk = {:?}, elf_bss = {:?}",
@@ -672,7 +833,7 @@ impl BinaryLoader for ElfLoader {
                     elf_brk + load_bias,
                     bss_prot_flags,
                 )?;
-                let nbyte = self.elf_page_offset(elf_bss);
+                let nbyte = Self::elf_page_offset(elf_bss);
                 if nbyte > 0 {
                     let nbyte = min(CurrentElfArch::ELF_PAGE_SIZE - nbyte, elf_brk - elf_bss);
                     unsafe {
@@ -684,7 +845,7 @@ impl BinaryLoader for ElfLoader {
             }
 
             // 生成ProtFlags.
-            let elf_prot_flags = self.make_prot(seg_to_load.p_flags, interpreter.is_some(), false);
+            let elf_prot_flags = Self::make_prot(seg_to_load.p_flags, interpreter.is_some(), false);
 
             let mut elf_map_flags = MapFlags::MAP_PRIVATE;
 
@@ -713,37 +874,33 @@ impl BinaryLoader for ElfLoader {
                         load_bias = 0;
                     }
                 }
-                load_bias = self
-                    .elf_page_start(VirtAddr::new(
-                        load_bias - TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
-                    ))
-                    .data();
+                load_bias = Self::elf_page_start(VirtAddr::new(
+                    load_bias - TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
+                ))
+                .data();
                 if total_size == 0 {
                     return Err(ExecError::InvalidParemeter);
                 }
             }
 
             // 加载这个段到用户空间
-            // debug!("to load elf segment");
-            let e = self
-                .load_elf_segment(
-                    &mut user_vm,
-                    param,
-                    &seg_to_load,
-                    vaddr + load_bias,
-                    &elf_prot_flags,
-                    &elf_map_flags,
-                    total_size,
-                )
-                .map_err(|e| {
-                    error!("load_elf_segment failed: {:?}", e);
-                    match e {
-                        SystemError::EFAULT => ExecError::BadAddress(None),
-                        SystemError::ENOMEM => ExecError::OutOfMemory,
-                        _ => ExecError::Other(format!("load_elf_segment failed: {:?}", e)),
-                    }
-                })?;
 
+            // log::debug!("bias: {load_bias}");
+            let e = Self::load_elf_segment(
+                &mut user_vm,
+                param,
+                &seg_to_load,
+                vaddr + load_bias,
+                &elf_prot_flags,
+                &elf_map_flags,
+                total_size,
+            )
+            .map_err(|e| match e {
+                SystemError::EFAULT => ExecError::BadAddress(None),
+                SystemError::ENOMEM => ExecError::OutOfMemory,
+                _ => ExecError::Other(format!("load_elf_segment failed: {:?}", e)),
+            })?;
+            // log::debug!("e.0={:?}", e.0);
             // 如果地址不对,那么就报错
             if !e.1 {
                 return Err(ExecError::BadAddress(Some(e.0)));
@@ -754,12 +911,10 @@ impl BinaryLoader for ElfLoader {
                 if elf_type == ElfType::DSO {
                     // todo: 在这里增加对load_bias和reloc_func_desc的更新代码
                     load_bias += e.0.data()
-                        - self
-                            .elf_page_start(VirtAddr::new(
-                                load_bias
-                                    + TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
-                            ))
-                            .data();
+                        - Self::elf_page_start(VirtAddr::new(
+                            load_bias + TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
+                        ))
+                        .data();
                     _reloc_func_desc = load_bias;
                 }
             }
@@ -793,7 +948,7 @@ impl BinaryLoader for ElfLoader {
             // 如果程序段要加载的目标地址不在用户空间内,或者是其他不合法的情况,那么就报错
             if !p_vaddr.check_user()
                 || seg_to_load.p_filesz > seg_to_load.p_memsz
-                || self.elf_page_align_up(p_vaddr + seg_to_load.p_memsz as usize)
+                || Self::elf_page_align_up(p_vaddr + seg_to_load.p_memsz as usize)
                     >= MMArch::USER_END_VADDR
             {
                 // debug!("ERR:     p_vaddr={p_vaddr:?}");
@@ -801,7 +956,7 @@ impl BinaryLoader for ElfLoader {
             }
 
             // end vaddr of this segment(code+data+bss)
-            let seg_end_vaddr_f = self.elf_page_align_up(VirtAddr::new(
+            let seg_end_vaddr_f = Self::elf_page_align_up(VirtAddr::new(
                 (seg_to_load.p_vaddr + seg_to_load.p_filesz) as usize,
             ));
 
@@ -839,7 +994,7 @@ impl BinaryLoader for ElfLoader {
         end_code = end_code.map(|v| v + load_bias);
         start_data = start_data.map(|v| v + load_bias);
         end_data = end_data.map(|v| v + load_bias);
-
+        let mut interp_load_addr: Option<VirtAddr> = None;
         // debug!(
         //     "to set brk: elf_bss: {:?}, elf_brk: {:?}, bss_prot_flags: {:?}",
         //     elf_bss,
@@ -848,16 +1003,27 @@ impl BinaryLoader for ElfLoader {
         // );
         self.set_elf_brk(&mut user_vm, elf_bss, elf_brk, bss_prot_flags)?;
 
-        if likely(elf_bss != elf_brk) && unlikely(self.pad_zero(elf_bss).is_err()) {
+        if likely(elf_bss != elf_brk) && unlikely(Self::pad_zero(elf_bss).is_err()) {
             // debug!("elf_bss = {elf_bss:?}, elf_brk = {elf_brk:?}");
             return Err(ExecError::BadAddress(Some(elf_bss)));
         }
-        if interpreter.is_some() {
-            // TODO 添加对动态加载器的处理
+        drop(user_vm);
+        if let Some(mut interpreter) = interpreter {
             // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#1249
+            let elf_entry = Self::load_elf_interp(&mut interpreter, load_bias)?.entry_point();
+            interp_load_addr = Some(elf_entry);
+            _reloc_func_desc = elf_entry.data();
+            //参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#1269
+            //TODO allow_write_access(interpreter);
+            ProcessManager::current_pcb()
+                .fd_table()
+                .write()
+                .alloc_fd(interpreter.file(), None)
+                .map(|fd| fd as usize)
+                .map_err(|_| ExecError::InvalidParemeter)?;
         }
         // debug!("to create auxv");
-
+        let mut user_vm = binding.write();
         self.create_auxv(param, program_entrypoint, phdr_vaddr, &ehdr)?;
 
         // debug!("auxv create ok");
@@ -866,8 +1032,8 @@ impl BinaryLoader for ElfLoader {
         user_vm.start_data = start_data.unwrap_or(VirtAddr::new(0));
         user_vm.end_data = end_data.unwrap_or(VirtAddr::new(0));
 
-        let result = BinaryLoaderResult::new(program_entrypoint);
-        // debug!("elf load OK!!!");
+        let result = BinaryLoaderResult::new(interp_load_addr.unwrap_or(program_entrypoint));
+        // kdebug!("elf load OK!!!");
         return Ok(result);
     }
 }

+ 1 - 1
kernel/src/libs/futex/futex.rs

@@ -677,7 +677,7 @@ impl RobustListHead {
     /// - head_uaddr:robust list head用户空间地址
     /// - len:robust list head的长度    
     pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
-        let robust_list_head_len = mem::size_of::<&RobustListHead>();
+        let robust_list_head_len = mem::size_of::<RobustListHead>();
         if unlikely(len != robust_list_head_len) {
             return Err(SystemError::EINVAL);
         }

+ 42 - 0
kernel/src/libs/rand.rs

@@ -1,3 +1,5 @@
+use crate::arch::rand::rand;
+
 bitflags! {
     pub struct GRandFlags: u8{
         const GRND_NONBLOCK = 0x0001;
@@ -6,6 +8,46 @@ bitflags! {
     }
 }
 
+/// Generates an array of random bytes of size `N`.
+///
+/// This function fills an array of size `N` with random bytes by repeatedly
+/// generating random numbers and converting them to little-endian byte arrays.
+/// The function ensures that the entire array is filled with random bytes,
+/// even if the size of the array is not a multiple of the size of `usize`.
+///
+/// # Type Parameters
+///
+/// * `N`: The size of the array to be filled with random bytes.
+///
+/// # Returns
+///
+/// An array of size `N` filled with random bytes.
+///
+/// # Example
+///
+/// ```rust
+/// let random_bytes = rand_bytes::<16>();
+/// assert_eq!(random_bytes.len(), 16);
+/// ```
+pub fn rand_bytes<const N: usize>() -> [u8; N] {
+    let mut bytes = [0u8; N];
+    let mut remaining = N;
+    let mut index = 0;
+
+    while remaining > 0 {
+        let random_num = rand();
+        let random_bytes = random_num.to_le_bytes();
+
+        let to_copy = core::cmp::min(remaining, size_of::<usize>());
+        bytes[index..index + to_copy].copy_from_slice(&random_bytes[..to_copy]);
+
+        index += to_copy;
+        remaining -= to_copy;
+    }
+
+    bytes
+}
+
 // 软件实现的随机数生成器
 #[allow(dead_code)]
 pub fn soft_rand() -> usize {

+ 2 - 1
kernel/src/mm/fault.rs

@@ -316,7 +316,6 @@ impl PageFaultHandler {
         } else {
             return VmFaultReason::VM_FAULT_OOM;
         }
-
         ret = ret.union(Self::finish_fault(pfm));
 
         ret
@@ -635,7 +634,9 @@ impl PageFaultHandler {
             // TODO 同步预读
             //涉及磁盘IO,返回标志为VM_FAULT_MAJOR
             ret = VmFaultReason::VM_FAULT_MAJOR;
+
             let mut buffer = Box::new([0u8; MMArch::PAGE_SIZE]);
+
             file.pread(
                 file_pgoff * MMArch::PAGE_SIZE,
                 MMArch::PAGE_SIZE,

+ 2 - 2
kernel/src/mm/syscall.rs

@@ -251,7 +251,7 @@ impl From<VmFlags> for ProtFlags {
 
 impl Syscall {
     pub fn brk(new_addr: VirtAddr) -> Result<VirtAddr, SystemError> {
-        // debug!("brk: new_addr={:?}", new_addr);
+        // log::debug!("brk: new_addr={:?}", new_addr);
         let address_space = AddressSpace::current()?;
         let mut address_space = address_space.write();
 
@@ -263,6 +263,7 @@ impl Syscall {
         }
 
         unsafe {
+            // log::debug!("brk: set_brk new_addr={:?}", new_addr);
             address_space
                 .set_brk(VirtAddr::new(page_align_up(new_addr.data())))
                 .ok();
@@ -346,7 +347,6 @@ impl Syscall {
                 false,
             )?
         };
-
         return Ok(start_page.virt_address().data());
     }
 

+ 2 - 2
kernel/src/process/abi.rs

@@ -38,7 +38,7 @@ pub enum AtType {
     /// Frequency at which times() increments.
     ClkTck,
     /// Secure mode boolean.
-    Secure,
+    Secure = 23,
     /// String identifying real platform, may differ from AT_PLATFORM.
     BasePlatform,
     /// Address of 16 random bytes.
@@ -46,7 +46,7 @@ pub enum AtType {
     /// Extension of AT_HWCAP.
     HwCap2,
     /// Filename of program.
-    ExecFn,
+    ExecFn = 31,
     /// Minimal stack size for signal delivery.
     MinSigStackSize,
 }

+ 23 - 2
kernel/src/process/exec.rs

@@ -157,6 +157,11 @@ impl ExecParam {
     pub fn file_mut(&mut self) -> &mut File {
         &mut self.file
     }
+
+    /// 获取File的所有权,用于将动态链接器加入文件描述符表中
+    pub fn file(self) -> File {
+        self.file
+    }
 }
 
 /// ## 加载二进制文件
@@ -199,6 +204,7 @@ pub struct ProcInitInfo {
     pub args: Vec<CString>,
     pub envs: Vec<CString>,
     pub auxv: BTreeMap<u8, usize>,
+    pub rand_num: [u8; 16],
 }
 
 impl ProcInitInfo {
@@ -208,6 +214,7 @@ impl ProcInitInfo {
             args: Vec::new(),
             envs: Vec::new(),
             auxv: BTreeMap::new(),
+            rand_num: [0u8; 16],
         }
     }
 
@@ -218,7 +225,7 @@ impl ProcInitInfo {
     ///
     /// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址     
     pub unsafe fn push_at(
-        &self,
+        &mut self,
         ustack: &mut UserStack,
     ) -> Result<(VirtAddr, VirtAddr), SystemError> {
         // 先把程序的名称压入栈中
@@ -233,6 +240,7 @@ impl ProcInitInfo {
                 ustack.sp()
             })
             .collect::<Vec<_>>();
+
         // 然后把参数压入栈中
         let argps = self
             .args
@@ -243,6 +251,20 @@ impl ProcInitInfo {
             })
             .collect::<Vec<_>>();
 
+        // 压入随机数,把指针放入auxv
+        self.push_slice(ustack, &[self.rand_num])?;
+        self.auxv
+            .insert(super::abi::AtType::Random as u8, ustack.sp().data());
+
+        // 实现栈的16字节对齐
+        // 用当前栈顶地址减去后续要压栈的长度,得到的压栈后的栈顶地址与0xF按位与操作得到对齐要填充的字节数
+        let length_to_push = (self.auxv.len() + envps.len() + 1 + argps.len() + 1 + 1)
+            * core::mem::align_of::<usize>();
+        self.push_slice(
+            ustack,
+            &vec![0u8; (ustack.sp().data() - length_to_push) & 0xF],
+        )?;
+
         // 压入auxv
         self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?;
         for (&k, &v) in self.auxv.iter() {
@@ -256,7 +278,6 @@ impl ProcInitInfo {
         // 把参数指针压入栈中
         self.push_slice(ustack, &[null::<u8>()])?;
         self.push_slice(ustack, argps.as_slice())?;
-
         let argv_ptr = ustack.sp();
 
         // 把argc压入栈中

+ 2 - 2
kernel/src/process/mod.rs

@@ -1574,8 +1574,8 @@ pub struct KernelStack {
 }
 
 impl KernelStack {
-    pub const SIZE: usize = 0x4000;
-    pub const ALIGN: usize = 0x4000;
+    pub const SIZE: usize = 0x8000;
+    pub const ALIGN: usize = 0x8000;
 
     pub fn new() -> Result<Self, SystemError> {
         return Ok(Self {

+ 8 - 5
kernel/src/process/syscall.rs

@@ -25,6 +25,7 @@ use crate::{
         procfs::procfs_register_pid,
         vfs::{file::FileDescriptorVec, MAX_PATHLEN},
     },
+    libs::rand::rand_bytes,
     mm::{
         ucontext::{AddressSpace, UserStack},
         verify_area, MemoryManagementArch, VirtAddr,
@@ -50,10 +51,10 @@ pub struct PosixOldUtsName {
 
 impl PosixOldUtsName {
     pub fn new() -> Self {
-        const SYS_NAME: &[u8] = b"DragonOS";
+        const SYS_NAME: &[u8] = b"Linux";
         const NODENAME: &[u8] = b"DragonOS";
-        const RELEASE: &[u8] = env!("CARGO_PKG_VERSION").as_bytes();
-        const VERSION: &[u8] = env!("CARGO_PKG_VERSION").as_bytes();
+        const RELEASE: &[u8] = b"5.19.0";
+        const VERSION: &[u8] = b"5.19.0";
 
         #[cfg(target_arch = "x86_64")]
         const MACHINE: &[u8] = b"x86_64";
@@ -176,6 +177,8 @@ impl Syscall {
         // debug!("argv: {:?}, envp: {:?}", argv, envp);
         param.init_info_mut().args = argv;
         param.init_info_mut().envs = envp;
+        // // 生成16字节随机数
+        param.init_info_mut().rand_num = rand_bytes::<16>();
 
         // 把proc_init_info写到用户栈上
         let mut ustack_message = unsafe {
@@ -187,7 +190,7 @@ impl Syscall {
         };
         let (user_sp, argv_ptr) = unsafe {
             param
-                .init_info()
+                .init_info_mut()
                 .push_at(
                     // address_space
                     //     .write()
@@ -338,7 +341,7 @@ impl Syscall {
 
     /// @brief 获取当前进程的父进程id
     ///
-    /// 若为initproc则ppid设置为0   
+    /// 若为initproc则ppid设置为0
     pub fn getppid() -> Result<Pid, SystemError> {
         let current_pcb = ProcessManager::current_pcb();
         return Ok(current_pcb.basic().ppid());

+ 8 - 16
kernel/src/syscall/mod.rs

@@ -30,7 +30,6 @@ use crate::{
     filesystem::vfs::{
         fcntl::{AtFlags, FcntlCommand},
         file::FileMode,
-        stat::PosixKstat,
         syscall::{ModeType, UtimensFlags},
         MAX_PATHLEN,
     },
@@ -668,14 +667,7 @@ impl Syscall {
             #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
             SYS_FSTAT => {
                 let fd = args[0] as i32;
-                let kstat: *mut PosixKstat = args[1] as *mut PosixKstat;
-                let vaddr = VirtAddr::new(kstat as usize);
-                // FIXME 由于c中的verify_area与rust中的verify_area重名,所以在引入时加了前缀区分
-                // TODO 应该将用了c版本的verify_area都改为rust的verify_area
-                match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
-                    Ok(_) => Self::fstat(fd, kstat),
-                    Err(e) => Err(e),
-                }
+                Self::fstat(fd, args[1])
             }
 
             SYS_FCNTL => {
@@ -778,15 +770,13 @@ impl Syscall {
             #[cfg(target_arch = "x86_64")]
             SYS_LSTAT => {
                 let path = args[0] as *const u8;
-                let kstat = args[1] as *mut PosixKstat;
-                Self::lstat(path, kstat)
+                Self::lstat(path, args[1])
             }
 
             #[cfg(target_arch = "x86_64")]
             SYS_STAT => {
                 let path = args[0] as *const u8;
-                let kstat = args[1] as *mut PosixKstat;
-                Self::stat(path, kstat)
+                Self::stat(path, args[1])
             }
 
             SYS_STATFS => {
@@ -902,8 +892,10 @@ impl Syscall {
             }
 
             SYS_EXIT_GROUP => {
-                warn!("SYS_EXIT_GROUP has not yet been implemented");
-                Ok(0)
+                let exit_code = args[0];
+                Self::exit(exit_code)
+                // warn!("SYS_EXIT_GROUP has not yet been implemented");
+                // Ok(0)
             }
 
             SYS_MADVISE => {
@@ -1051,7 +1043,7 @@ impl Syscall {
 
             SYS_RSEQ => {
                 warn!("SYS_RSEQ has not yet been implemented");
-                Ok(0)
+                Err(SystemError::ENOSYS)
             }
 
             #[cfg(target_arch = "x86_64")]

+ 1 - 1
tools/BUILD_CONTAINER_VERSION

@@ -1 +1 @@
-v1.11
+v1.12

+ 1 - 1
tools/bootstrap.sh

@@ -338,7 +338,7 @@ rustInstall
 install_python_pkg
 
 # 安装dadk
-cargo install dadk || exit 1
+cargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v0.4.0 || exit 1
 
 bashpath=$(cd `dirname $0`; pwd)
 

+ 1 - 1
tools/build_in_docker.sh

@@ -1,6 +1,6 @@
 docker rm -f dragonos-build || echo "No existed container"
 cpu_count=$(cat /proc/cpuinfo |grep "processor"|wc -l)
-docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.11 bash << EOF
+docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.12 bash << EOF
 source ~/.cargo/env
 source ~/.bashrc
 cd /data

+ 9 - 1
tools/write_disk_image.sh

@@ -79,6 +79,9 @@ $DADK -w $root_folder rootfs mount || exit 1
 LOOP_DEVICE=$($DADK -w $root_folder rootfs show-loop-device || exit 1)
 echo $LOOP_DEVICE
 echo ${mount_folder}
+
+FS_TYPE=$(findmnt -n -o FSTYPE ${mount_folder} || df -T ${mount_folder} | tail -1 | awk '{print $2}')
+echo "FS_TYPE: $FS_TYPE"
 # mkdir -p ${GRUB_INSTALL_PATH}
 
 # 检测grub文件夹是否存在
@@ -99,7 +102,12 @@ mkdir -p ${mount_folder}/bin
 mkdir -p ${mount_folder}/dev
 mkdir -p ${mount_folder}/proc
 mkdir -p ${mount_folder}/usr
-cp -r ${root_folder}/bin/sysroot/* ${mount_folder}/
+
+if [ "$FS_TYPE" = "vfat" ] || [ "$FS_TYPE" = "fat32" ]; then
+    cp -rL ${root_folder}/bin/sysroot/* ${mount_folder}/
+else
+    cp -r ${root_folder}/bin/sysroot/* ${mount_folder}/
+fi
 
 # 设置 grub 相关数据
 if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then

+ 2 - 2
user/Makefile

@@ -2,7 +2,7 @@ user_sub_dirs = apps
 
 DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
 # 最小的DADK版本
-MIN_DADK_VERSION = 0.3.0
+MIN_DADK_VERSION = 0.4.0
 DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
 
 ECHO:
@@ -20,7 +20,7 @@ ifeq ("$(DADK_VERSION)", "")
 	@echo "\n\tcargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION)" --locked
 	@echo "\n"
 	@echo "Auto installing dadk..."
-	cargo install dadk
+	cargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION)" --locked
 else
 # 如果DADK版本过低,则自动更新
 	@echo "dadk version $(DADK_VERSION) installed"

+ 1 - 1
user/apps/clear/Makefile

@@ -10,7 +10,7 @@ else
 endif
 
 ifeq ($(ARCH), x86_64)
-	export RUST_TARGET=x86_64-unknown-linux-musl
+	export RUST_TARGET=x86_64-unknown-linux-gnu
 else ifeq ($(ARCH), riscv64)
 	export RUST_TARGET=riscv64gc-unknown-linux-gnu
 else 

+ 2 - 2
user/apps/test_fstat/Makefile

@@ -1,5 +1,5 @@
 ifeq ($(ARCH), x86_64)
-	CROSS_COMPILE=x86_64-linux-musl-
+	CROSS_COMPILE=x86_64-linux-gnu-
 else ifeq ($(ARCH), riscv64)
 	CROSS_COMPILE=riscv64-linux-musl-
 endif
@@ -8,7 +8,7 @@ CC=$(CROSS_COMPILE)gcc
 
 .PHONY: all
 all: main.c
-	$(CC) -static -o test_fstat main.c
+	$(CC) -o test_fstat main.c
 
 .PHONY: install clean
 install: all

+ 2 - 2
user/apps/test_newfstatat/Makefile

@@ -1,5 +1,5 @@
 ifeq ($(ARCH), x86_64)
-	CROSS_COMPILE=x86_64-linux-musl-
+	CROSS_COMPILE=x86_64-linux-gnu-
 else ifeq ($(ARCH), riscv64)
 	CROSS_COMPILE=riscv64-linux-musl-
 endif
@@ -8,7 +8,7 @@ CC=$(CROSS_COMPILE)gcc
 
 .PHONY: all
 all: main.c
-	$(CC) -static -o test_newfstatat main.c
+	$(CC) -o test_newfstatat main.c
 
 .PHONY: install clean
 install: all

+ 4 - 0
user/dadk/config/core_utils-9.4.0.toml

@@ -22,6 +22,10 @@ type = "build-from-source"
 source = "archive"
 # 路径或URL
 source-path = "https://mirrors.dragonos.org.cn/pub/third_party/gnu/coreutils/coreutils-9.4.tar.xz"
+
+# 把压缩包中的哪个目录作为根目录(可选),仅当 source = "archive" 时生效
+archive-rootdir = "coreutils-9.4"
+
 # 构建相关信息
 [build]
 # (可选)构建命令

+ 40 - 0
user/dadk/config/glibc_bin_ubuntu2404.toml

@@ -0,0 +1,40 @@
+# 用户程序名称
+name = "glibc_bin_ubuntu2404"
+# 版本号
+version = "2.39"
+# 用户程序描述信息
+description = "GNU C Library for Ubuntu 24.04"
+# (可选)默认: false 是否只构建一次,如果为true,DADK会在构建成功后,将构建结果缓存起来,下次构建时,直接使用缓存的构建结果
+build-once = false
+#  (可选) 默认: false 是否只安装一次,如果为true,DADK会在安装成功后,不再重复安装
+install-once = false
+# 目标架构
+# 可选值:"x86_64", "aarch64", "riscv64", "loongarch64"
+target-arch = ["x86_64"]
+# 任务源
+[task-source]
+# 构建类型
+# 可选值:"build-from-source", "install-from-prebuilt"
+type = "install-from-prebuilt"
+# 构建来源
+# "build_from_source" 可选值:"git", "local", "archive"
+# "install_from_prebuilt" 可选值:"local", "archive"
+source = "archive"
+# 路径或URL
+source-path = "https://mirrors.dragonos.org.cn/pub/third_party/gnu/glibc-bin/glibc-ubuntu2404-x86_64-202505111756-8f3207567bf10f4d09027b2cd84b7807.tar.xz"
+archive-rootdir = "sysroot/"
+
+[build]
+
+# 安装相关信息
+[install]
+# (可选)安装到DragonOS的路径
+in-dragonos-path = "/"
+# 清除相关信息
+[clean]
+# (可选)清除命令
+clean-command = ""
+# (可选)依赖项
+# 注意:如果没有依赖项,忽略此项,不允许只留一个[[depends]]
+# (可选)环境变量
+# 注意:如果没有环境变量,忽略此项,不允许只留一个[[envs]]

+ 4 - 1
user/dadk/config/musl_1_2_4.toml

@@ -22,10 +22,13 @@ type = "build-from-source"
 source = "archive"
 # 路径或URL
 source-path = "https://mirrors.dragonos.org.cn/pub/third_party/musl/musl-1.2.4.tar.gz"
+# 把压缩包中的哪个目录作为根目录(可选),仅当 source = "archive" 时生效
+archive-rootdir = "musl-1.2.4"
+
 # 构建相关信息
 [build]
 # (可选)构建命令
-build-command = "touch config.mak && DESTDIR=$DADK_CURRENT_BUILD_DIR make install -j $(nproc)"
+build-command = "touch config.mak && DESTDIR=$DADK_CURRENT_BUILD_DIR make install -j $(nproc) && rm -rf $DADK_CURRENT_BUILD_DIR/lib && rm -rf $DADK_CURRENT_BUILD_DIR/lib64"
 # 安装相关信息
 [install]
 # (可选)安装到DragonOS的路径

+ 2 - 1
user/sysconfig/etc/reach/system/shell.service

@@ -7,4 +7,5 @@ ExecStart=/bin/NovaShell
 Restart=always
 ExecStartPre=-/bin/about.elf
 ExecStartPre=/bin/busybox stty erase 127
-Environment=PATH=/bin:/usr/bin:/usr/local/bin
+Environment=PATH=/bin:/usr/bin:/usr/local/bin
+Environment=LD_LIBRARY_PATH=/usr/lib:/usr/lib64:/usr/local/lib