mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 10:15:03 +00:00
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>
This commit is contained in:
parent
b322121dd9
commit
fccfa6f7ff
12
.github/workflows/makefile.yml
vendored
12
.github/workflows/makefile.yml
vendored
@ -11,14 +11,14 @@ jobs:
|
|||||||
name: Format check ${{ matrix.arch }}
|
name: Format check ${{ matrix.arch }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
container: dragonos/dragonos-dev:v1.11
|
container: dragonos/dragonos-dev:v1.12
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
arch: [x86_64, riscv64, loongarch64]
|
arch: [x86_64, riscv64, loongarch64]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- run: echo "Running in dragonos/dragonos-dev:v1.11"
|
- run: echo "Running in dragonos/dragonos-dev:v1.12"
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Format check
|
- name: Format check
|
||||||
@ -35,14 +35,14 @@ jobs:
|
|||||||
name: Kernel static test ${{ matrix.arch }}
|
name: Kernel static test ${{ matrix.arch }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
container: dragonos/dragonos-dev:v1.11
|
container: dragonos/dragonos-dev:v1.12
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
arch: [x86_64, riscv64, loongarch64]
|
arch: [x86_64, riscv64, loongarch64]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- run: echo "Running in dragonos/dragonos-dev:v1.11"
|
- run: echo "Running in dragonos/dragonos-dev:v1.12"
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
name: Build ${{ matrix.arch }}
|
name: Build ${{ matrix.arch }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: dragonos/dragonos-dev:v1.11
|
container: dragonos/dragonos-dev:v1.12
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -73,7 +73,7 @@ jobs:
|
|||||||
checkout_params: {}
|
checkout_params: {}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- run: echo "Running in dragonos/dragonos-dev:v1.11"
|
- run: echo "Running in dragonos/dragonos-dev:v1.12"
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with: ${{ matrix.checkout_params }}
|
with: ${{ matrix.checkout_params }}
|
||||||
|
@ -177,6 +177,10 @@ impl X86_64MMArch {
|
|||||||
error_code: X86PfErrorCode,
|
error_code: X86PfErrorCode,
|
||||||
address: VirtAddr,
|
address: VirtAddr,
|
||||||
) {
|
) {
|
||||||
|
// log::debug!("fault at {:?}:{:?}",
|
||||||
|
// address,
|
||||||
|
// error_code,
|
||||||
|
// );
|
||||||
let rflags = RFlags::from_bits_truncate(regs.rflags);
|
let rflags = RFlags::from_bits_truncate(regs.rflags);
|
||||||
let mut flags: FaultFlags = FaultFlags::FAULT_FLAG_ALLOW_RETRY
|
let mut flags: FaultFlags = FaultFlags::FAULT_FLAG_ALLOW_RETRY
|
||||||
| FaultFlags::FAULT_FLAG_KILLABLE
|
| FaultFlags::FAULT_FLAG_KILLABLE
|
||||||
|
@ -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> {
|
pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) {
|
if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) {
|
||||||
@ -109,8 +110,17 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError> {
|
pub fn do_arch_prctl_common(option: usize, arg2: usize) -> Result<usize, SystemError> {
|
||||||
todo!("do_arch_prctl_common not unimplemented");
|
// 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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
|
|||||||
mfence();
|
mfence();
|
||||||
let pid = ProcessManager::current_pcb().pid();
|
let pid = ProcessManager::current_pcb().pid();
|
||||||
let show = false;
|
let show = false;
|
||||||
// let show = if syscall_num != SYS_SCHED && pid.data() >= 7 {
|
// let show = if syscall_num != SYS_SCHED && pid.data() >= 9{
|
||||||
// true
|
// true
|
||||||
// } else {
|
// } else {
|
||||||
// false
|
// false
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
mod hook;
|
pub mod hook;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ impl DeviceManager {
|
|||||||
/// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功
|
/// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功
|
||||||
///
|
///
|
||||||
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899
|
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899
|
||||||
|
#[inline(never)]
|
||||||
fn do_device_attach_driver(
|
fn do_device_attach_driver(
|
||||||
&self,
|
&self,
|
||||||
driver: &Arc<dyn Driver>,
|
driver: &Arc<dyn Driver>,
|
||||||
|
@ -1452,7 +1452,6 @@ impl IndexNode for LockedFATInode {
|
|||||||
let page_cache = self.0.lock().page_cache.clone();
|
let page_cache = self.0.lock().page_cache.clone();
|
||||||
if let Some(page_cache) = page_cache {
|
if let Some(page_cache) = page_cache {
|
||||||
let r = page_cache.lock_irqsave().read(offset, &mut buf[0..len]);
|
let r = page_cache.lock_irqsave().read(offset, &mut buf[0..len]);
|
||||||
// self.0.lock_irqsave().update_metadata();
|
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
return self.read_direct(offset, len, buf, data);
|
return self.read_direct(offset, len, buf, data);
|
||||||
|
@ -113,13 +113,14 @@ impl InnerPageCache {
|
|||||||
/// - `Ok(usize)` 成功读取的长度
|
/// - `Ok(usize)` 成功读取的长度
|
||||||
/// - `Err(SystemError)` 失败返回错误码
|
/// - `Err(SystemError)` 失败返回错误码
|
||||||
pub fn read(&mut self, offset: usize, buf: &mut [u8]) -> Result<usize, 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
|
.page_cache_ref
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.inode
|
.inode
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let file_size = inode.metadata().unwrap().size;
|
let file_size = inode.metadata().unwrap().size;
|
||||||
|
|
||||||
let len = if offset < file_size as usize {
|
let len = if offset < file_size as usize {
|
||||||
@ -182,6 +183,7 @@ impl InnerPageCache {
|
|||||||
for (page_index, count) in not_exist {
|
for (page_index, count) in not_exist {
|
||||||
// TODO 这里使用buffer避免多次读取磁盘,将来引入异步IO直接写入页面,减少内存开销和拷贝
|
// TODO 这里使用buffer避免多次读取磁盘,将来引入异步IO直接写入页面,减少内存开销和拷贝
|
||||||
let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count];
|
let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count];
|
||||||
|
|
||||||
inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?;
|
inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?;
|
||||||
|
|
||||||
self.create_pages(page_index, page_buf.as_mut())?;
|
self.create_pages(page_index, page_buf.as_mut())?;
|
||||||
@ -314,7 +316,7 @@ impl InnerPageCache {
|
|||||||
|
|
||||||
impl Drop for InnerPageCache {
|
impl Drop for InnerPageCache {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
log::debug!("page cache drop");
|
// log::debug!("page cache drop");
|
||||||
let mut page_manager = page_manager_lock_irqsave();
|
let mut page_manager = page_manager_lock_irqsave();
|
||||||
for page in self.pages.values() {
|
for page in self.pages.values() {
|
||||||
page_manager.remove_page(&page.phys_address());
|
page_manager.remove_page(&page.phys_address());
|
||||||
@ -358,6 +360,13 @@ impl PageCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn lock_irqsave(&self) -> SpinLockGuard<InnerPageCache> {
|
pub fn lock_irqsave(&self) -> SpinLockGuard<InnerPageCache> {
|
||||||
|
if self.inner.is_locked() {
|
||||||
|
log::error!("page cache already locked");
|
||||||
|
}
|
||||||
self.inner.lock_irqsave()
|
self.inner.lock_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_locked(&self) -> bool {
|
||||||
|
self.inner.is_locked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ pub(super) fn do_faccessat(
|
|||||||
|
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||||
let path = path.to_str().map_err(|_| SystemError::EINVAL)?;
|
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)?;
|
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ fn do_sys_openat2(
|
|||||||
how: OpenHow,
|
how: OpenHow,
|
||||||
follow_symlink: bool,
|
follow_symlink: bool,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
// debug!("open path: {}, how: {:?}", path, how);
|
// log::debug!("openat2: dirfd: {}, path: {}, how: {:?}",dirfd, path, how);
|
||||||
let path = path.trim();
|
let path = path.trim();
|
||||||
|
|
||||||
let (inode_begin, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
let (inode_begin, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||||
|
@ -273,6 +273,7 @@ pub fn vfs_getattr(
|
|||||||
/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#274
|
/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#274
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn vfs_fstatat(dfd: i32, filename: &str, flags: AtFlags) -> Result<KStat, SystemError> {
|
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;
|
let statx_flags = flags | AtFlags::AT_NO_AUTOMOUNT;
|
||||||
if dfd >= 0 && flags == AtFlags::AT_EMPTY_PATH {
|
if dfd >= 0 && flags == AtFlags::AT_EMPTY_PATH {
|
||||||
return vfs_fstat(dfd);
|
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
|
/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#393
|
||||||
#[inline(never)]
|
#[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 posix_stat = PosixStat::try_from(kstat)?;
|
||||||
let mut ubuf_writer =
|
let mut ubuf_writer =
|
||||||
UserBufferWriter::new(user_buf_ptr as *mut PosixStat, size_of::<PosixStat>(), true)?;
|
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(())
|
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
|
/// 通用的PosixStat
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -21,7 +21,7 @@ use crate::{
|
|||||||
time::{syscall::PosixTimeval, PosixTimeSpec},
|
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::vcore::do_symlinkat;
|
||||||
use super::{
|
use super::{
|
||||||
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
||||||
@ -1211,79 +1211,31 @@ impl Syscall {
|
|||||||
return Err(SystemError::EBADF);
|
return Err(SystemError::EBADF);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> {
|
#[inline(never)]
|
||||||
let binding = ProcessManager::current_pcb().fd_table();
|
pub fn fstat(fd: i32, user_stat_ptr: usize) -> Result<usize, SystemError> {
|
||||||
let fd_table_guard = binding.read();
|
Self::newfstat(fd, user_stat_ptr)
|
||||||
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> {
|
pub fn stat(path: *const u8, user_stat_ptr: usize) -> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
|
||||||
let fd = Self::open(
|
let fd = Self::open(
|
||||||
path,
|
path,
|
||||||
FileMode::O_RDONLY.bits(),
|
FileMode::O_RDONLY.bits(),
|
||||||
ModeType::empty().bits(),
|
ModeType::empty().bits(),
|
||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
let r = Self::fstat(fd as i32, user_kstat);
|
let r = Self::fstat(fd as i32, user_stat_ptr);
|
||||||
Self::close(fd).ok();
|
Self::close(fd).ok();
|
||||||
return r;
|
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(
|
let fd = Self::open(
|
||||||
path,
|
path,
|
||||||
FileMode::O_RDONLY.bits(),
|
FileMode::O_RDONLY.bits(),
|
||||||
ModeType::empty().bits(),
|
ModeType::empty().bits(),
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
let r = Self::fstat(fd as i32, user_kstat);
|
let r = Self::fstat(fd as i32, user_stat_ptr);
|
||||||
Self::close(fd).ok();
|
Self::close(fd).ok();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -1356,6 +1308,16 @@ impl Syscall {
|
|||||||
do_newfstatat(dfd, filename_str, user_stat_buf_ptr, flags).map(|_| 0)
|
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(
|
pub fn mknod(
|
||||||
path: *const u8,
|
path: *const u8,
|
||||||
mode: ModeType,
|
mode: ModeType,
|
||||||
|
@ -7,10 +7,10 @@ use core::{
|
|||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use elf::{
|
use elf::{
|
||||||
abi::{PT_GNU_PROPERTY, PT_INTERP},
|
abi::{ET_DYN, ET_EXEC, PT_GNU_PROPERTY, PT_INTERP, PT_LOAD},
|
||||||
endian::AnyEndian,
|
endian::AnyEndian,
|
||||||
file::FileHeader,
|
file::FileHeader,
|
||||||
segment::ProgramHeader,
|
segment::{ProgramHeader, SegmentTable},
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
@ -18,7 +18,6 @@ use system_error::SystemError;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::{CurrentElfArch, MMArch},
|
arch::{CurrentElfArch, MMArch},
|
||||||
driver::base::block::SeekFrom,
|
driver::base::block::SeekFrom,
|
||||||
filesystem::vfs::file::File,
|
|
||||||
libs::align::page_align_up,
|
libs::align::page_align_up,
|
||||||
mm::{
|
mm::{
|
||||||
allocator::page_frame::{PageFrameCount, VirtPageFrame},
|
allocator::page_frame::{PageFrameCount, VirtPageFrame},
|
||||||
@ -28,7 +27,9 @@ use crate::{
|
|||||||
},
|
},
|
||||||
process::{
|
process::{
|
||||||
abi::AtType,
|
abi::AtType,
|
||||||
exec::{BinaryLoader, BinaryLoaderResult, ExecError, ExecLoadMode, ExecParam},
|
exec::{
|
||||||
|
BinaryLoader, BinaryLoaderResult, ExecError, ExecLoadMode, ExecParam, ExecParamFlags,
|
||||||
|
},
|
||||||
ProcessFlags, ProcessManager,
|
ProcessFlags, ProcessManager,
|
||||||
},
|
},
|
||||||
syscall::user_access::{clear_user, copy_to_user},
|
syscall::user_access::{clear_user, copy_to_user},
|
||||||
@ -134,8 +135,8 @@ impl ElfLoader {
|
|||||||
end: VirtAddr,
|
end: VirtAddr,
|
||||||
prot_flags: ProtFlags,
|
prot_flags: ProtFlags,
|
||||||
) -> Result<(), ExecError> {
|
) -> Result<(), ExecError> {
|
||||||
let start = self.elf_page_start(start);
|
let start = Self::elf_page_start(start);
|
||||||
let end = self.elf_page_align_up(end);
|
let end = Self::elf_page_align_up(end);
|
||||||
// debug!("set_elf_brk: start={:?}, end={:?}", start, end);
|
// debug!("set_elf_brk: start={:?}, end={:?}", start, end);
|
||||||
if end > start {
|
if end > start {
|
||||||
let r = user_vm_guard.map_anonymous(
|
let r = user_vm_guard.map_anonymous(
|
||||||
@ -158,15 +159,15 @@ impl ElfLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 计算addr在ELF PAGE内的偏移
|
/// 计算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)
|
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)))
|
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(
|
VirtAddr::new(
|
||||||
(addr.data() + CurrentElfArch::ELF_PAGE_SIZE - 1)
|
(addr.data() + CurrentElfArch::ELF_PAGE_SIZE - 1)
|
||||||
& (!(CurrentElfArch::ELF_PAGE_SIZE - 1)),
|
& (!(CurrentElfArch::ELF_PAGE_SIZE - 1)),
|
||||||
@ -174,7 +175,7 @@ impl ElfLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 根据ELF的p_flags生成对应的ProtFlags
|
/// 根据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();
|
let mut prot = ProtFlags::empty();
|
||||||
if p_flags & elf::abi::PF_R != 0 {
|
if p_flags & elf::abi::PF_R != 0 {
|
||||||
prot |= ProtFlags::PROT_READ;
|
prot |= ProtFlags::PROT_READ;
|
||||||
@ -211,7 +212,6 @@ impl ElfLoader {
|
|||||||
/// - `Ok((VirtAddr, bool))`:如果成功加载,则bool值为true,否则为false. VirtAddr为加载的地址
|
/// - `Ok((VirtAddr, bool))`:如果成功加载,则bool值为true,否则为false. VirtAddr为加载的地址
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn load_elf_segment(
|
fn load_elf_segment(
|
||||||
&self,
|
|
||||||
user_vm_guard: &mut RwLockWriteGuard<'_, InnerAddressSpace>,
|
user_vm_guard: &mut RwLockWriteGuard<'_, InnerAddressSpace>,
|
||||||
param: &mut ExecParam,
|
param: &mut ExecParam,
|
||||||
phent: &ProgramHeader,
|
phent: &ProgramHeader,
|
||||||
@ -223,11 +223,11 @@ impl ElfLoader {
|
|||||||
// debug!("load_elf_segment: addr_to_map={:?}", addr_to_map);
|
// debug!("load_elf_segment: addr_to_map={:?}", addr_to_map);
|
||||||
|
|
||||||
// 映射位置的偏移量(页内偏移)
|
// 映射位置的偏移量(页内偏移)
|
||||||
let beginning_page_offset = self.elf_page_offset(addr_to_map);
|
let beginning_page_offset = Self::elf_page_offset(addr_to_map);
|
||||||
addr_to_map = self.elf_page_start(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 = 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;
|
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
|
// So we first map the 'big' image - and unmap the remainder at
|
||||||
// the end. (which unmap is needed for ELF images with holes.)
|
// the end. (which unmap is needed for ELF images with holes.)
|
||||||
if total_size != 0 {
|
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_addr = user_vm_guard
|
||||||
.map_anonymous(addr_to_map, total_size, tmp_prot, *map_flags, false, true)
|
.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,
|
map_addr + beginning_page_offset,
|
||||||
seg_in_file_size,
|
seg_in_file_size,
|
||||||
file_offset,
|
file_offset,
|
||||||
@ -307,7 +309,7 @@ impl ElfLoader {
|
|||||||
// );
|
// );
|
||||||
|
|
||||||
// 加载文件到内存
|
// 加载文件到内存
|
||||||
self.do_load_file(
|
Self::do_load_file(
|
||||||
map_addr + beginning_page_offset,
|
map_addr + beginning_page_offset,
|
||||||
seg_in_file_size,
|
seg_in_file_size,
|
||||||
file_offset,
|
file_offset,
|
||||||
@ -326,6 +328,152 @@ impl ElfLoader {
|
|||||||
return Ok((map_addr, true));
|
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,
|
||||||
|
§ion,
|
||||||
|
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文件到用户空间
|
/// 加载ELF文件到用户空间
|
||||||
///
|
///
|
||||||
/// ## 参数
|
/// ## 参数
|
||||||
@ -335,7 +483,6 @@ impl ElfLoader {
|
|||||||
/// - `offset_in_file`:在文件内的偏移量
|
/// - `offset_in_file`:在文件内的偏移量
|
||||||
/// - `param`:执行参数
|
/// - `param`:执行参数
|
||||||
fn do_load_file(
|
fn do_load_file(
|
||||||
&self,
|
|
||||||
mut vaddr: VirtAddr,
|
mut vaddr: VirtAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
offset_in_file: usize,
|
offset_in_file: usize,
|
||||||
@ -367,8 +514,8 @@ impl ElfLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 我们需要显式的把数据段之后剩余的内存页都清零。
|
/// 我们需要显式的把数据段之后剩余的内存页都清零。
|
||||||
fn pad_zero(&self, elf_bss: VirtAddr) -> Result<(), SystemError> {
|
fn pad_zero(elf_bss: VirtAddr) -> Result<(), SystemError> {
|
||||||
let nbyte = self.elf_page_offset(elf_bss);
|
let nbyte = Self::elf_page_offset(elf_bss);
|
||||||
if nbyte > 0 {
|
if nbyte > 0 {
|
||||||
let nbyte = CurrentElfArch::ELF_PAGE_SIZE - nbyte;
|
let nbyte = CurrentElfArch::ELF_PAGE_SIZE - nbyte;
|
||||||
unsafe { clear_user(elf_bss, nbyte).map_err(|_| SystemError::EFAULT) }?;
|
unsafe { clear_user(elf_bss, nbyte).map_err(|_| SystemError::EFAULT) }?;
|
||||||
@ -376,6 +523,37 @@ impl ElfLoader {
|
|||||||
return Ok(());
|
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
|
/// 创建auxv
|
||||||
///
|
///
|
||||||
/// ## 参数
|
/// ## 参数
|
||||||
@ -562,7 +740,7 @@ impl BinaryLoader for ElfLoader {
|
|||||||
.map_err(|_| ExecError::ParseError)?
|
.map_err(|_| ExecError::ParseError)?
|
||||||
.ok_or(ExecError::ParseError)?;
|
.ok_or(ExecError::ParseError)?;
|
||||||
let mut _gnu_property_data: Option<ProgramHeader> = None;
|
let mut _gnu_property_data: Option<ProgramHeader> = None;
|
||||||
let interpreter: Option<File> = None;
|
let mut interpreter: Option<ExecParam> = None;
|
||||||
for seg in phdr_table {
|
for seg in phdr_table {
|
||||||
if seg.p_type == PT_GNU_PROPERTY {
|
if seg.p_type == PT_GNU_PROPERTY {
|
||||||
_gnu_property_data = Some(seg);
|
_gnu_property_data = Some(seg);
|
||||||
@ -594,8 +772,8 @@ impl BinaryLoader for ElfLoader {
|
|||||||
log::error!("Failed to load interpreter ");
|
log::error!("Failed to load interpreter ");
|
||||||
return Err(ExecError::NotSupported);
|
return Err(ExecError::NotSupported);
|
||||||
}
|
}
|
||||||
let _interpreter_path = core::str::from_utf8(
|
let interpreter_path = core::str::from_utf8(
|
||||||
&buffer[0..TryInto::<usize>::try_into(seg.p_filesz).unwrap() - 1], //
|
&buffer[0..TryInto::<usize>::try_into(seg.p_filesz).unwrap() - 1],
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
ExecError::Other(format!(
|
ExecError::Other(format!(
|
||||||
@ -603,9 +781,17 @@ impl BinaryLoader for ElfLoader {
|
|||||||
e
|
e
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
// log::debug!("opening interpreter at :{}", interpreter_path);
|
||||||
//TODO 加入对动态链接器的加载,参照 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#890
|
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() {
|
if interpreter.is_some() {
|
||||||
/* Some simple consistency checks for the interpreter */
|
/* Some simple consistency checks for the interpreter */
|
||||||
// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#950
|
// 参考 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的虚拟地址
|
// program header的虚拟地址
|
||||||
let mut phdr_vaddr: Option<VirtAddr> = None;
|
let mut phdr_vaddr: Option<VirtAddr> = None;
|
||||||
let mut _reloc_func_desc = 0usize;
|
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 total_size = Self::total_mapping_size(&phdr_table);
|
||||||
let mut min_address = VirtAddr::new(usize::MAX);
|
|
||||||
let mut max_address = VirtAddr::new(0usize);
|
|
||||||
let loadable_sections = phdr_table
|
let loadable_sections = phdr_table
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|seg| seg.p_type == elf::abi::PT_LOAD);
|
.filter(|seg| seg.p_type == elf::abi::PT_LOAD);
|
||||||
|
|
||||||
for seg_to_load in loadable_sections {
|
for seg_to_load in loadable_sections {
|
||||||
min_address = min(
|
// log::debug!("seg_to_load = {:?}", seg_to_load);
|
||||||
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 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);
|
|
||||||
if unlikely(elf_brk > elf_bss) {
|
if unlikely(elf_brk > elf_bss) {
|
||||||
// debug!(
|
// debug!(
|
||||||
// "to set brk, elf_brk = {:?}, elf_bss = {:?}",
|
// "to set brk, elf_brk = {:?}, elf_bss = {:?}",
|
||||||
@ -672,7 +833,7 @@ impl BinaryLoader for ElfLoader {
|
|||||||
elf_brk + load_bias,
|
elf_brk + load_bias,
|
||||||
bss_prot_flags,
|
bss_prot_flags,
|
||||||
)?;
|
)?;
|
||||||
let nbyte = self.elf_page_offset(elf_bss);
|
let nbyte = Self::elf_page_offset(elf_bss);
|
||||||
if nbyte > 0 {
|
if nbyte > 0 {
|
||||||
let nbyte = min(CurrentElfArch::ELF_PAGE_SIZE - nbyte, elf_brk - elf_bss);
|
let nbyte = min(CurrentElfArch::ELF_PAGE_SIZE - nbyte, elf_brk - elf_bss);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -684,7 +845,7 @@ impl BinaryLoader for ElfLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 生成ProtFlags.
|
// 生成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;
|
let mut elf_map_flags = MapFlags::MAP_PRIVATE;
|
||||||
|
|
||||||
@ -713,37 +874,33 @@ impl BinaryLoader for ElfLoader {
|
|||||||
load_bias = 0;
|
load_bias = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
load_bias = self
|
load_bias = Self::elf_page_start(VirtAddr::new(
|
||||||
.elf_page_start(VirtAddr::new(
|
load_bias - TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
|
||||||
load_bias - TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
|
))
|
||||||
))
|
.data();
|
||||||
.data();
|
|
||||||
if total_size == 0 {
|
if total_size == 0 {
|
||||||
return Err(ExecError::InvalidParemeter);
|
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 {
|
if !e.1 {
|
||||||
return Err(ExecError::BadAddress(Some(e.0)));
|
return Err(ExecError::BadAddress(Some(e.0)));
|
||||||
@ -754,12 +911,10 @@ impl BinaryLoader for ElfLoader {
|
|||||||
if elf_type == ElfType::DSO {
|
if elf_type == ElfType::DSO {
|
||||||
// todo: 在这里增加对load_bias和reloc_func_desc的更新代码
|
// todo: 在这里增加对load_bias和reloc_func_desc的更新代码
|
||||||
load_bias += e.0.data()
|
load_bias += e.0.data()
|
||||||
- self
|
- Self::elf_page_start(VirtAddr::new(
|
||||||
.elf_page_start(VirtAddr::new(
|
load_bias + TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
|
||||||
load_bias
|
))
|
||||||
+ TryInto::<usize>::try_into(seg_to_load.p_vaddr).unwrap(),
|
.data();
|
||||||
))
|
|
||||||
.data();
|
|
||||||
_reloc_func_desc = load_bias;
|
_reloc_func_desc = load_bias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -793,7 +948,7 @@ impl BinaryLoader for ElfLoader {
|
|||||||
// 如果程序段要加载的目标地址不在用户空间内,或者是其他不合法的情况,那么就报错
|
// 如果程序段要加载的目标地址不在用户空间内,或者是其他不合法的情况,那么就报错
|
||||||
if !p_vaddr.check_user()
|
if !p_vaddr.check_user()
|
||||||
|| seg_to_load.p_filesz > seg_to_load.p_memsz
|
|| 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
|
>= MMArch::USER_END_VADDR
|
||||||
{
|
{
|
||||||
// debug!("ERR: p_vaddr={p_vaddr:?}");
|
// debug!("ERR: p_vaddr={p_vaddr:?}");
|
||||||
@ -801,7 +956,7 @@ impl BinaryLoader for ElfLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// end vaddr of this segment(code+data+bss)
|
// 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,
|
(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);
|
end_code = end_code.map(|v| v + load_bias);
|
||||||
start_data = start_data.map(|v| v + load_bias);
|
start_data = start_data.map(|v| v + load_bias);
|
||||||
end_data = end_data.map(|v| v + load_bias);
|
end_data = end_data.map(|v| v + load_bias);
|
||||||
|
let mut interp_load_addr: Option<VirtAddr> = None;
|
||||||
// debug!(
|
// debug!(
|
||||||
// "to set brk: elf_bss: {:?}, elf_brk: {:?}, bss_prot_flags: {:?}",
|
// "to set brk: elf_bss: {:?}, elf_brk: {:?}, bss_prot_flags: {:?}",
|
||||||
// elf_bss,
|
// elf_bss,
|
||||||
@ -848,16 +1003,27 @@ impl BinaryLoader for ElfLoader {
|
|||||||
// );
|
// );
|
||||||
self.set_elf_brk(&mut user_vm, elf_bss, elf_brk, bss_prot_flags)?;
|
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:?}");
|
// debug!("elf_bss = {elf_bss:?}, elf_brk = {elf_brk:?}");
|
||||||
return Err(ExecError::BadAddress(Some(elf_bss)));
|
return Err(ExecError::BadAddress(Some(elf_bss)));
|
||||||
}
|
}
|
||||||
if interpreter.is_some() {
|
drop(user_vm);
|
||||||
// TODO 添加对动态加载器的处理
|
if let Some(mut interpreter) = interpreter {
|
||||||
// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#1249
|
// 参考 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");
|
// debug!("to create auxv");
|
||||||
|
let mut user_vm = binding.write();
|
||||||
self.create_auxv(param, program_entrypoint, phdr_vaddr, &ehdr)?;
|
self.create_auxv(param, program_entrypoint, phdr_vaddr, &ehdr)?;
|
||||||
|
|
||||||
// debug!("auxv create ok");
|
// 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.start_data = start_data.unwrap_or(VirtAddr::new(0));
|
||||||
user_vm.end_data = end_data.unwrap_or(VirtAddr::new(0));
|
user_vm.end_data = end_data.unwrap_or(VirtAddr::new(0));
|
||||||
|
|
||||||
let result = BinaryLoaderResult::new(program_entrypoint);
|
let result = BinaryLoaderResult::new(interp_load_addr.unwrap_or(program_entrypoint));
|
||||||
// debug!("elf load OK!!!");
|
// kdebug!("elf load OK!!!");
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,7 +677,7 @@ impl RobustListHead {
|
|||||||
/// - head_uaddr:robust list head用户空间地址
|
/// - head_uaddr:robust list head用户空间地址
|
||||||
/// - len:robust list head的长度
|
/// - len:robust list head的长度
|
||||||
pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
|
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) {
|
if unlikely(len != robust_list_head_len) {
|
||||||
return Err(SystemError::EINVAL);
|
return Err(SystemError::EINVAL);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::arch::rand::rand;
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct GRandFlags: u8{
|
pub struct GRandFlags: u8{
|
||||||
const GRND_NONBLOCK = 0x0001;
|
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)]
|
#[allow(dead_code)]
|
||||||
pub fn soft_rand() -> usize {
|
pub fn soft_rand() -> usize {
|
||||||
|
@ -316,7 +316,6 @@ impl PageFaultHandler {
|
|||||||
} else {
|
} else {
|
||||||
return VmFaultReason::VM_FAULT_OOM;
|
return VmFaultReason::VM_FAULT_OOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ret.union(Self::finish_fault(pfm));
|
ret = ret.union(Self::finish_fault(pfm));
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@ -635,7 +634,9 @@ impl PageFaultHandler {
|
|||||||
// TODO 同步预读
|
// TODO 同步预读
|
||||||
//涉及磁盘IO,返回标志为VM_FAULT_MAJOR
|
//涉及磁盘IO,返回标志为VM_FAULT_MAJOR
|
||||||
ret = VmFaultReason::VM_FAULT_MAJOR;
|
ret = VmFaultReason::VM_FAULT_MAJOR;
|
||||||
|
|
||||||
let mut buffer = Box::new([0u8; MMArch::PAGE_SIZE]);
|
let mut buffer = Box::new([0u8; MMArch::PAGE_SIZE]);
|
||||||
|
|
||||||
file.pread(
|
file.pread(
|
||||||
file_pgoff * MMArch::PAGE_SIZE,
|
file_pgoff * MMArch::PAGE_SIZE,
|
||||||
MMArch::PAGE_SIZE,
|
MMArch::PAGE_SIZE,
|
||||||
|
@ -251,7 +251,7 @@ impl From<VmFlags> for ProtFlags {
|
|||||||
|
|
||||||
impl Syscall {
|
impl Syscall {
|
||||||
pub fn brk(new_addr: VirtAddr) -> Result<VirtAddr, SystemError> {
|
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 address_space = AddressSpace::current()?;
|
||||||
let mut address_space = address_space.write();
|
let mut address_space = address_space.write();
|
||||||
|
|
||||||
@ -263,6 +263,7 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// log::debug!("brk: set_brk new_addr={:?}", new_addr);
|
||||||
address_space
|
address_space
|
||||||
.set_brk(VirtAddr::new(page_align_up(new_addr.data())))
|
.set_brk(VirtAddr::new(page_align_up(new_addr.data())))
|
||||||
.ok();
|
.ok();
|
||||||
@ -346,7 +347,6 @@ impl Syscall {
|
|||||||
false,
|
false,
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(start_page.virt_address().data());
|
return Ok(start_page.virt_address().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ pub enum AtType {
|
|||||||
/// Frequency at which times() increments.
|
/// Frequency at which times() increments.
|
||||||
ClkTck,
|
ClkTck,
|
||||||
/// Secure mode boolean.
|
/// Secure mode boolean.
|
||||||
Secure,
|
Secure = 23,
|
||||||
/// String identifying real platform, may differ from AT_PLATFORM.
|
/// String identifying real platform, may differ from AT_PLATFORM.
|
||||||
BasePlatform,
|
BasePlatform,
|
||||||
/// Address of 16 random bytes.
|
/// Address of 16 random bytes.
|
||||||
@ -46,7 +46,7 @@ pub enum AtType {
|
|||||||
/// Extension of AT_HWCAP.
|
/// Extension of AT_HWCAP.
|
||||||
HwCap2,
|
HwCap2,
|
||||||
/// Filename of program.
|
/// Filename of program.
|
||||||
ExecFn,
|
ExecFn = 31,
|
||||||
/// Minimal stack size for signal delivery.
|
/// Minimal stack size for signal delivery.
|
||||||
MinSigStackSize,
|
MinSigStackSize,
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,11 @@ impl ExecParam {
|
|||||||
pub fn file_mut(&mut self) -> &mut File {
|
pub fn file_mut(&mut self) -> &mut File {
|
||||||
&mut self.file
|
&mut self.file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 获取File的所有权,用于将动态链接器加入文件描述符表中
|
||||||
|
pub fn file(self) -> File {
|
||||||
|
self.file
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ## 加载二进制文件
|
/// ## 加载二进制文件
|
||||||
@ -199,6 +204,7 @@ pub struct ProcInitInfo {
|
|||||||
pub args: Vec<CString>,
|
pub args: Vec<CString>,
|
||||||
pub envs: Vec<CString>,
|
pub envs: Vec<CString>,
|
||||||
pub auxv: BTreeMap<u8, usize>,
|
pub auxv: BTreeMap<u8, usize>,
|
||||||
|
pub rand_num: [u8; 16],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcInitInfo {
|
impl ProcInitInfo {
|
||||||
@ -208,6 +214,7 @@ impl ProcInitInfo {
|
|||||||
args: Vec::new(),
|
args: Vec::new(),
|
||||||
envs: Vec::new(),
|
envs: Vec::new(),
|
||||||
auxv: BTreeMap::new(),
|
auxv: BTreeMap::new(),
|
||||||
|
rand_num: [0u8; 16],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +225,7 @@ impl ProcInitInfo {
|
|||||||
///
|
///
|
||||||
/// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址
|
/// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址
|
||||||
pub unsafe fn push_at(
|
pub unsafe fn push_at(
|
||||||
&self,
|
&mut self,
|
||||||
ustack: &mut UserStack,
|
ustack: &mut UserStack,
|
||||||
) -> Result<(VirtAddr, VirtAddr), SystemError> {
|
) -> Result<(VirtAddr, VirtAddr), SystemError> {
|
||||||
// 先把程序的名称压入栈中
|
// 先把程序的名称压入栈中
|
||||||
@ -233,6 +240,7 @@ impl ProcInitInfo {
|
|||||||
ustack.sp()
|
ustack.sp()
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// 然后把参数压入栈中
|
// 然后把参数压入栈中
|
||||||
let argps = self
|
let argps = self
|
||||||
.args
|
.args
|
||||||
@ -243,6 +251,20 @@ impl ProcInitInfo {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.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
|
// 压入auxv
|
||||||
self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?;
|
self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?;
|
||||||
for (&k, &v) in self.auxv.iter() {
|
for (&k, &v) in self.auxv.iter() {
|
||||||
@ -256,7 +278,6 @@ impl ProcInitInfo {
|
|||||||
// 把参数指针压入栈中
|
// 把参数指针压入栈中
|
||||||
self.push_slice(ustack, &[null::<u8>()])?;
|
self.push_slice(ustack, &[null::<u8>()])?;
|
||||||
self.push_slice(ustack, argps.as_slice())?;
|
self.push_slice(ustack, argps.as_slice())?;
|
||||||
|
|
||||||
let argv_ptr = ustack.sp();
|
let argv_ptr = ustack.sp();
|
||||||
|
|
||||||
// 把argc压入栈中
|
// 把argc压入栈中
|
||||||
|
@ -1574,8 +1574,8 @@ pub struct KernelStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KernelStack {
|
impl KernelStack {
|
||||||
pub const SIZE: usize = 0x4000;
|
pub const SIZE: usize = 0x8000;
|
||||||
pub const ALIGN: usize = 0x4000;
|
pub const ALIGN: usize = 0x8000;
|
||||||
|
|
||||||
pub fn new() -> Result<Self, SystemError> {
|
pub fn new() -> Result<Self, SystemError> {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
|
@ -25,6 +25,7 @@ use crate::{
|
|||||||
procfs::procfs_register_pid,
|
procfs::procfs_register_pid,
|
||||||
vfs::{file::FileDescriptorVec, MAX_PATHLEN},
|
vfs::{file::FileDescriptorVec, MAX_PATHLEN},
|
||||||
},
|
},
|
||||||
|
libs::rand::rand_bytes,
|
||||||
mm::{
|
mm::{
|
||||||
ucontext::{AddressSpace, UserStack},
|
ucontext::{AddressSpace, UserStack},
|
||||||
verify_area, MemoryManagementArch, VirtAddr,
|
verify_area, MemoryManagementArch, VirtAddr,
|
||||||
@ -50,10 +51,10 @@ pub struct PosixOldUtsName {
|
|||||||
|
|
||||||
impl PosixOldUtsName {
|
impl PosixOldUtsName {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
const SYS_NAME: &[u8] = b"DragonOS";
|
const SYS_NAME: &[u8] = b"Linux";
|
||||||
const NODENAME: &[u8] = b"DragonOS";
|
const NODENAME: &[u8] = b"DragonOS";
|
||||||
const RELEASE: &[u8] = env!("CARGO_PKG_VERSION").as_bytes();
|
const RELEASE: &[u8] = b"5.19.0";
|
||||||
const VERSION: &[u8] = env!("CARGO_PKG_VERSION").as_bytes();
|
const VERSION: &[u8] = b"5.19.0";
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
const MACHINE: &[u8] = b"x86_64";
|
const MACHINE: &[u8] = b"x86_64";
|
||||||
@ -176,6 +177,8 @@ impl Syscall {
|
|||||||
// debug!("argv: {:?}, envp: {:?}", argv, envp);
|
// debug!("argv: {:?}, envp: {:?}", argv, envp);
|
||||||
param.init_info_mut().args = argv;
|
param.init_info_mut().args = argv;
|
||||||
param.init_info_mut().envs = envp;
|
param.init_info_mut().envs = envp;
|
||||||
|
// // 生成16字节随机数
|
||||||
|
param.init_info_mut().rand_num = rand_bytes::<16>();
|
||||||
|
|
||||||
// 把proc_init_info写到用户栈上
|
// 把proc_init_info写到用户栈上
|
||||||
let mut ustack_message = unsafe {
|
let mut ustack_message = unsafe {
|
||||||
@ -187,7 +190,7 @@ impl Syscall {
|
|||||||
};
|
};
|
||||||
let (user_sp, argv_ptr) = unsafe {
|
let (user_sp, argv_ptr) = unsafe {
|
||||||
param
|
param
|
||||||
.init_info()
|
.init_info_mut()
|
||||||
.push_at(
|
.push_at(
|
||||||
// address_space
|
// address_space
|
||||||
// .write()
|
// .write()
|
||||||
@ -338,7 +341,7 @@ impl Syscall {
|
|||||||
|
|
||||||
/// @brief 获取当前进程的父进程id
|
/// @brief 获取当前进程的父进程id
|
||||||
///
|
///
|
||||||
/// 若为initproc则ppid设置为0
|
/// 若为initproc则ppid设置为0
|
||||||
pub fn getppid() -> Result<Pid, SystemError> {
|
pub fn getppid() -> Result<Pid, SystemError> {
|
||||||
let current_pcb = ProcessManager::current_pcb();
|
let current_pcb = ProcessManager::current_pcb();
|
||||||
return Ok(current_pcb.basic().ppid());
|
return Ok(current_pcb.basic().ppid());
|
||||||
|
@ -30,7 +30,6 @@ use crate::{
|
|||||||
filesystem::vfs::{
|
filesystem::vfs::{
|
||||||
fcntl::{AtFlags, FcntlCommand},
|
fcntl::{AtFlags, FcntlCommand},
|
||||||
file::FileMode,
|
file::FileMode,
|
||||||
stat::PosixKstat,
|
|
||||||
syscall::{ModeType, UtimensFlags},
|
syscall::{ModeType, UtimensFlags},
|
||||||
MAX_PATHLEN,
|
MAX_PATHLEN,
|
||||||
},
|
},
|
||||||
@ -668,14 +667,7 @@ impl Syscall {
|
|||||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||||
SYS_FSTAT => {
|
SYS_FSTAT => {
|
||||||
let fd = args[0] as i32;
|
let fd = args[0] as i32;
|
||||||
let kstat: *mut PosixKstat = args[1] as *mut PosixKstat;
|
Self::fstat(fd, args[1])
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_FCNTL => {
|
SYS_FCNTL => {
|
||||||
@ -778,15 +770,13 @@ impl Syscall {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
SYS_LSTAT => {
|
SYS_LSTAT => {
|
||||||
let path = args[0] as *const u8;
|
let path = args[0] as *const u8;
|
||||||
let kstat = args[1] as *mut PosixKstat;
|
Self::lstat(path, args[1])
|
||||||
Self::lstat(path, kstat)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
SYS_STAT => {
|
SYS_STAT => {
|
||||||
let path = args[0] as *const u8;
|
let path = args[0] as *const u8;
|
||||||
let kstat = args[1] as *mut PosixKstat;
|
Self::stat(path, args[1])
|
||||||
Self::stat(path, kstat)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_STATFS => {
|
SYS_STATFS => {
|
||||||
@ -902,8 +892,10 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SYS_EXIT_GROUP => {
|
SYS_EXIT_GROUP => {
|
||||||
warn!("SYS_EXIT_GROUP has not yet been implemented");
|
let exit_code = args[0];
|
||||||
Ok(0)
|
Self::exit(exit_code)
|
||||||
|
// warn!("SYS_EXIT_GROUP has not yet been implemented");
|
||||||
|
// Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_MADVISE => {
|
SYS_MADVISE => {
|
||||||
@ -1051,7 +1043,7 @@ impl Syscall {
|
|||||||
|
|
||||||
SYS_RSEQ => {
|
SYS_RSEQ => {
|
||||||
warn!("SYS_RSEQ has not yet been implemented");
|
warn!("SYS_RSEQ has not yet been implemented");
|
||||||
Ok(0)
|
Err(SystemError::ENOSYS)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
@ -1 +1 @@
|
|||||||
v1.11
|
v1.12
|
@ -338,7 +338,7 @@ rustInstall
|
|||||||
install_python_pkg
|
install_python_pkg
|
||||||
|
|
||||||
# 安装dadk
|
# 安装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)
|
bashpath=$(cd `dirname $0`; pwd)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
docker rm -f dragonos-build || echo "No existed container"
|
docker rm -f dragonos-build || echo "No existed container"
|
||||||
cpu_count=$(cat /proc/cpuinfo |grep "processor"|wc -l)
|
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 ~/.cargo/env
|
||||||
source ~/.bashrc
|
source ~/.bashrc
|
||||||
cd /data
|
cd /data
|
||||||
|
@ -79,6 +79,9 @@ $DADK -w $root_folder rootfs mount || exit 1
|
|||||||
LOOP_DEVICE=$($DADK -w $root_folder rootfs show-loop-device || exit 1)
|
LOOP_DEVICE=$($DADK -w $root_folder rootfs show-loop-device || exit 1)
|
||||||
echo $LOOP_DEVICE
|
echo $LOOP_DEVICE
|
||||||
echo ${mount_folder}
|
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}
|
# mkdir -p ${GRUB_INSTALL_PATH}
|
||||||
|
|
||||||
# 检测grub文件夹是否存在
|
# 检测grub文件夹是否存在
|
||||||
@ -99,7 +102,12 @@ mkdir -p ${mount_folder}/bin
|
|||||||
mkdir -p ${mount_folder}/dev
|
mkdir -p ${mount_folder}/dev
|
||||||
mkdir -p ${mount_folder}/proc
|
mkdir -p ${mount_folder}/proc
|
||||||
mkdir -p ${mount_folder}/usr
|
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 相关数据
|
# 设置 grub 相关数据
|
||||||
if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
|
if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
|
||||||
|
@ -2,7 +2,7 @@ user_sub_dirs = apps
|
|||||||
|
|
||||||
DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
|
DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
|
||||||
# 最小的DADK版本
|
# 最小的DADK版本
|
||||||
MIN_DADK_VERSION = 0.3.0
|
MIN_DADK_VERSION = 0.4.0
|
||||||
DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
|
DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
|
||||||
|
|
||||||
ECHO:
|
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\tcargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION)" --locked
|
||||||
@echo "\n"
|
@echo "\n"
|
||||||
@echo "Auto installing dadk..."
|
@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
|
else
|
||||||
# 如果DADK版本过低,则自动更新
|
# 如果DADK版本过低,则自动更新
|
||||||
@echo "dadk version $(DADK_VERSION) installed"
|
@echo "dadk version $(DADK_VERSION) installed"
|
||||||
|
@ -10,7 +10,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
export RUST_TARGET=x86_64-unknown-linux-musl
|
export RUST_TARGET=x86_64-unknown-linux-gnu
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
export RUST_TARGET=riscv64gc-unknown-linux-gnu
|
export RUST_TARGET=riscv64gc-unknown-linux-gnu
|
||||||
else
|
else
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
CROSS_COMPILE=x86_64-linux-musl-
|
CROSS_COMPILE=x86_64-linux-gnu-
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
CROSS_COMPILE=riscv64-linux-musl-
|
CROSS_COMPILE=riscv64-linux-musl-
|
||||||
endif
|
endif
|
||||||
@ -8,7 +8,7 @@ CC=$(CROSS_COMPILE)gcc
|
|||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: main.c
|
all: main.c
|
||||||
$(CC) -static -o test_fstat main.c
|
$(CC) -o test_fstat main.c
|
||||||
|
|
||||||
.PHONY: install clean
|
.PHONY: install clean
|
||||||
install: all
|
install: all
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
CROSS_COMPILE=x86_64-linux-musl-
|
CROSS_COMPILE=x86_64-linux-gnu-
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
CROSS_COMPILE=riscv64-linux-musl-
|
CROSS_COMPILE=riscv64-linux-musl-
|
||||||
endif
|
endif
|
||||||
@ -8,7 +8,7 @@ CC=$(CROSS_COMPILE)gcc
|
|||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: main.c
|
all: main.c
|
||||||
$(CC) -static -o test_newfstatat main.c
|
$(CC) -o test_newfstatat main.c
|
||||||
|
|
||||||
.PHONY: install clean
|
.PHONY: install clean
|
||||||
install: all
|
install: all
|
||||||
|
@ -22,6 +22,10 @@ type = "build-from-source"
|
|||||||
source = "archive"
|
source = "archive"
|
||||||
# 路径或URL
|
# 路径或URL
|
||||||
source-path = "https://mirrors.dragonos.org.cn/pub/third_party/gnu/coreutils/coreutils-9.4.tar.xz"
|
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]
|
[build]
|
||||||
# (可选)构建命令
|
# (可选)构建命令
|
||||||
|
40
user/dadk/config/glibc_bin_ubuntu2404.toml
Normal file
40
user/dadk/config/glibc_bin_ubuntu2404.toml
Normal file
@ -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]]
|
@ -22,10 +22,13 @@ type = "build-from-source"
|
|||||||
source = "archive"
|
source = "archive"
|
||||||
# 路径或URL
|
# 路径或URL
|
||||||
source-path = "https://mirrors.dragonos.org.cn/pub/third_party/musl/musl-1.2.4.tar.gz"
|
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]
|
||||||
# (可选)构建命令
|
# (可选)构建命令
|
||||||
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]
|
[install]
|
||||||
# (可选)安装到DragonOS的路径
|
# (可选)安装到DragonOS的路径
|
||||||
|
@ -7,4 +7,5 @@ ExecStart=/bin/NovaShell
|
|||||||
Restart=always
|
Restart=always
|
||||||
ExecStartPre=-/bin/about.elf
|
ExecStartPre=-/bin/about.elf
|
||||||
ExecStartPre=/bin/busybox stty erase 127
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user