Skip to content

Commit

Permalink
support musl, fit framework
Browse files Browse the repository at this point in the history
add readme for musl
  • Loading branch information
coolyjg committed Nov 20, 2023
1 parent 4a61969 commit 44b46ec
Show file tree
Hide file tree
Showing 67 changed files with 2,268 additions and 115 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ members = [

"ulib/axstd",
"ulib/axlibc",
"ulib/axmusl",

"apps/display/basic_painting",
"apps/display/draw_map",
Expand Down
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
# * Network options:
# - `IP`: ArceOS IPv4 address (default is 10.0.2.15 for QEMU user netdev)
# - `GW`: Gateway IPv4 address (default is 10.0.2.2 for QEMU user netdev)
# * Libc options:
# - `MUSL`: Link C app with musl libc

# General options
ARCH ?= x86_64
Expand Down Expand Up @@ -71,6 +73,9 @@ GW ?= 10.0.2.2
ARGS ?=
ENVS ?=

# Libc options
MUSL ?= n

# App type
ifeq ($(wildcard $(APP)),)
$(error Application path "$(APP)" is not valid)
Expand Down Expand Up @@ -136,6 +141,7 @@ export AX_GW=$(GW)
export AX_9P_ADDR = $(NET_9P_ADDR)
export AX_ANAME_9P = $(ANAME_9P)
export AX_PROTOCOL_9P = $(PROTOCOL_9P)
export AX_MUSL=$(MUSL)

# Binutils
CROSS_COMPILE ?= $(ARCH)-linux-musl-
Expand Down Expand Up @@ -222,12 +228,16 @@ else
$(call make_disk_image,fat32,$(DISK_IMG))
endif

clean: clean_c
clean: clean_c clean_musl
rm -rf $(APP)/*.bin $(APP)/*.elf
cargo clean

clean_c::
rm -rf ulib/axlibc/build_*
rm -rf $(app-objs)

.PHONY: all build disasm run justrun debug clippy fmt fmt_c test test_no_fail_fast clean clean_c doc disk_image
clean_musl:
rm -rf ulib/axmusl/build_*
rm -rf ulib/axmusl/install

.PHONY: all build disasm run justrun debug clippy fmt fmt_c test test_no_fail_fast clean clean_c clean_musl doc disk_image
4 changes: 4 additions & 0 deletions api/arceos_posix_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ pipe = ["fd"]
select = ["fd"]
epoll = ["fd"]
poll = ["fd"]
tls = ["axfeat/tls"]
irq = ["axfeat/irq"]

musl = ["axfeat/musl"]

[dependencies]
# ArceOS modules
Expand Down
6 changes: 6 additions & 0 deletions api/arceos_posix_api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ typedef struct {{
"sysinfo",
"sigaction",
"k_sigaction",
"pid_t",
"sigset_t",
"sigaction",
"kstat",
];
let allow_vars = [
"O_.*",
Expand All @@ -116,6 +120,8 @@ typedef struct {{
"ITIMER_.*",
"SIG.*",
"EINVAL",
"CLONE_.*",
"AT_.*",
];

#[derive(Debug)]
Expand Down
6 changes: 4 additions & 2 deletions api/arceos_posix_api/ctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A
* PARTICULAR PURPOSE. See the Mulan PSL v2 for more details.
*/

#include <errno.h>
Expand All @@ -14,6 +15,7 @@
#include <netinet/in.h>
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stddef.h>
#include <sys/epoll.h>
Expand Down
23 changes: 23 additions & 0 deletions api/arceos_posix_api/src/imp/fd_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,29 @@ pub fn sys_dup2(old_fd: c_int, new_fd: c_int) -> c_int {
})
}

/// `dup3` used by A64 for MUSL
#[cfg(feature = "musl")]
pub fn sys_dup3(old_fd: c_int, new_fd: c_int, flags: c_int) -> c_int {
debug!(
"sys_dup3 <= old_fd: {}, new_fd: {}, flags: {:x}",
old_fd, new_fd, flags
);
syscall_body!(sys_dup3, {
if old_fd == new_fd {
return Err(LinuxError::EINVAL);
}
sys_dup2(old_fd, new_fd);
if flags as u32 & ctypes::O_CLOEXEC != 0 {
sys_fcntl(
new_fd,
ctypes::F_SETFD as c_int,
ctypes::FD_CLOEXEC as usize,
);
}
Ok(new_fd)
})
}

/// Manipulate file descriptor.
///
/// TODO: `SET/GET` command is ignored, hard-code stdin/stdout
Expand Down
124 changes: 112 additions & 12 deletions api/arceos_posix_api/src/imp/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ pub fn sys_open(filename: *const c_char, flags: c_int, mode: ctypes::mode_t) ->
})
}

/// Open a file under a specific dir
///
/// TODO: Currently only support openat root directory
pub fn sys_openat(_fd: usize, path: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int {
let path = char_ptr_to_str(path);
debug!("sys_openat <= {:?}, {:#o} {:#o}", path, flags, mode);
syscall_body!(sys_openat, {
let options = flags_to_options(flags, mode);
let file = axfs::fops::File::open(path?, &options)?;
File::new(file).add_to_fd_table()
})
}

/// Set the position of the file indicated by `fd`.
///
/// Return its position after seek.
Expand All @@ -142,6 +155,12 @@ pub fn sys_lseek(fd: c_int, offset: ctypes::off_t, whence: c_int) -> ctypes::off
})
}

/// `fsync`
pub unsafe fn sys_fsync(fd: c_int) -> c_int {
debug!("sys_fsync <= fd: {}", fd);
syscall_body!(sys_fsync, Ok(0))
}

/// Get the file metadata by `path` and write into `buf`.
///
/// Return 0 if success.
Expand All @@ -161,18 +180,36 @@ pub unsafe fn sys_stat(path: *const c_char, buf: *mut ctypes::stat) -> c_int {
})
}

/// Get file metadata by `fd` and write into `buf`.
///
/// Return 0 if success.
pub unsafe fn sys_fstat(fd: c_int, buf: *mut ctypes::stat) -> c_int {
debug!("sys_fstat <= {} {:#x}", fd, buf as usize);
/// retrieve information about the file pointed by `fd`
pub unsafe fn sys_fstat(fd: c_int, kst: *mut core::ffi::c_void) -> c_int {
debug!("sys_fstat <= {} {:#x}", fd, kst as usize);
syscall_body!(sys_fstat, {
if buf.is_null() {
if kst.is_null() {
return Err(LinuxError::EFAULT);
}

unsafe { *buf = get_file_like(fd)?.stat()? };
Ok(0)
#[cfg(not(feature = "musl"))]
{
let buf = kst as *mut ctypes::stat;
unsafe { *buf = get_file_like(fd)?.stat()? };
Ok(0)
}
#[cfg(feature = "musl")]
{
let st = get_file_like(fd)?.stat()?;
let kst = kst as *mut ctypes::kstat;
unsafe {
(*kst).st_dev = st.st_dev;
(*kst).st_ino = st.st_dev;
(*kst).st_mode = st.st_mode;
(*kst).st_nlink = st.st_nlink;
(*kst).st_uid = st.st_uid;
(*kst).st_gid = st.st_gid;
(*kst).st_size = st.st_size;
(*kst).st_blocks = st.st_blocks;
(*kst).st_blksize = st.st_blksize;
}
Ok(0)
}
})
}

Expand All @@ -191,20 +228,56 @@ pub unsafe fn sys_lstat(path: *const c_char, buf: *mut ctypes::stat) -> ctypes::
})
}

/// `newfstatat` used by A64
pub unsafe fn sys_newfstatat(
_fd: c_int,
path: *const c_char,
kst: *mut ctypes::kstat,
flag: c_int,
) -> c_int {
let path = char_ptr_to_str(path);
debug!(
"sys_newfstatat <= fd: {}, path: {:?}, flag: {:x}",
_fd, path, flag
);
assert_eq!(_fd, ctypes::AT_FDCWD as c_int);
syscall_body!(sys_newfstatat, {
if kst.is_null() {
return Err(LinuxError::EFAULT);
}
let mut options = OpenOptions::new();
options.read(true);
let file = axfs::fops::File::open(path?, &options)?;
let st = File::new(file).stat()?;
unsafe {
(*kst).st_dev = st.st_dev;
(*kst).st_ino = st.st_dev;
(*kst).st_mode = st.st_mode;
(*kst).st_nlink = st.st_nlink;
(*kst).st_uid = st.st_uid;
(*kst).st_gid = st.st_gid;
(*kst).st_size = st.st_size;
(*kst).st_blocks = st.st_blocks;
(*kst).st_blksize = st.st_blksize;
}
Ok(0)
})
}

/// Get the path of the current directory.
pub fn sys_getcwd(buf: *mut c_char, size: usize) -> *mut c_char {
pub fn sys_getcwd(buf: *mut c_char, size: usize) -> c_int {
debug!("sys_getcwd <= {:#x} {}", buf as usize, size);
syscall_body!(sys_getcwd, {
if buf.is_null() {
return Ok(core::ptr::null::<c_char>() as _);
return Err(LinuxError::EINVAL);
}
let dst = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, size as _) };
let cwd = axfs::api::current_dir()?;
let cwd = cwd.as_bytes();
if cwd.len() < size {
dst[..cwd.len()].copy_from_slice(cwd);
dst[cwd.len()] = 0;
Ok(buf)
Ok(cwd.len() + 1)
} else {
Err(LinuxError::ERANGE)
}
Expand Down Expand Up @@ -245,6 +318,20 @@ pub fn sys_unlink(pathname: *const c_char) -> c_int {
})
}

/// deletes a name from the filesystem
pub fn sys_unlinkat(fd: c_int, pathname: *const c_char, flags: c_int) -> c_int {
debug!(
"sys_unlinkat <= fd: {}, pathname: {:?}, flags: {}",
fd,
char_ptr_to_str(pathname),
flags
);
if flags as u32 & ctypes::AT_REMOVEDIR != 0 {
return sys_rmdir(pathname);
}
sys_unlink(pathname)
}

/// Creates a new, empty directory at the provided path.
pub fn sys_mkdir(pathname: *const c_char, mode: ctypes::mode_t) -> c_int {
// TODO: implement mode
Expand All @@ -255,3 +342,16 @@ pub fn sys_mkdir(pathname: *const c_char, mode: ctypes::mode_t) -> c_int {
Ok(0)
})
}

/// attempts to create a directory named pathname under directory pointed by `fd`
///
/// TODO: currently fd is not used
pub fn sys_mkdirat(fd: c_int, pathname: *const c_char, mode: ctypes::mode_t) -> c_int {
debug!(
"sys_mkdirat <= fd: {}, pathname: {:?}, mode: {:x?}",
fd,
char_ptr_to_str(pathname),
mode
);
sys_mkdir(pathname, mode)
}
5 changes: 4 additions & 1 deletion api/arceos_posix_api/src/imp/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub fn sys_write(fd: c_int, buf: *const c_void, count: usize) -> ctypes::ssize_t

/// Write a vector.
pub unsafe fn sys_writev(fd: c_int, iov: *const ctypes::iovec, iocnt: c_int) -> ctypes::ssize_t {
debug!("sys_writev <= fd: {}", fd);
debug!("sys_writev <= fd: {}, iocnt: {}", fd, iocnt);
syscall_body!(sys_writev, {
if !(0..=1024).contains(&iocnt) {
return Err(LinuxError::EINVAL);
Expand All @@ -73,6 +73,9 @@ pub unsafe fn sys_writev(fd: c_int, iov: *const ctypes::iovec, iocnt: c_int) ->
let iovs = unsafe { core::slice::from_raw_parts(iov, iocnt as usize) };
let mut ret = 0;
for iov in iovs.iter() {
if iov.iov_base.is_null() {
continue;
}
ret += sys_write(fd, iov.iov_base, iov.iov_len);
}

Expand Down
Loading

0 comments on commit 44b46ec

Please sign in to comment.