diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 757da706..d6b363ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,22 +9,24 @@ jobs: fail-fast: false matrix: rust-toolchain: [nightly] + targets: [x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none-softfloat] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.rust-toolchain }} components: rust-src, clippy, rustfmt + targets: ${{ matrix.targets }} - name: Setup ArceOS run: ./scripts/get_deps.sh - name: Check rust version run: rustc --version --verbose - name: Check code format continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }} - run: cargo fmt -- --check + run: cargo fmt --all -- --check - name: Clippy continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }} - run: cargo clippy + run: cargo clippy --target ${{ matrix.targets }} --all-features -- -D warnings -A clippy::new_without_default build: runs-on: ${{ matrix.os }} @@ -32,7 +34,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - arch: [x86_64] + arch: [x86_64, riscv64, aarch64] rust-toolchain: [nightly] steps: - uses: actions/checkout@v4 @@ -40,7 +42,7 @@ jobs: with: toolchain: ${{ matrix.rust-toolchain }} components: rust-src, llvm-tools - targets: x86_64-unknown-none + targets: x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none, aarch64-unknown-none-softfloat - uses: Swatinem/rust-cache@v2 - run: cargo install cargo-binutils - run: ./scripts/get_deps.sh @@ -48,12 +50,13 @@ jobs: run: make ARCH=${{ matrix.arch }} test-musl: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: + os: [ubuntu-latest] + arch: [x86_64, riscv64, aarch64] rust-toolchain: [nightly] - arch: [x86_64] env: qemu-version: 8.2.0 steps: @@ -72,6 +75,7 @@ jobs: with: qemu-version: ${{ env.qemu-version }} - name: Build rustup target + if: ${{ matrix.arch != 'riscv64' }} run: rustup target add ${{ matrix.arch }}-unknown-linux-musl - name: Run tests for musl applications run: make test ARCH=${{ matrix.arch }} \ No newline at end of file diff --git a/apps/libc/Makefile b/apps/libc/Makefile index 7e66f3f7..4b347cf5 100644 --- a/apps/libc/Makefile +++ b/apps/libc/Makefile @@ -12,11 +12,14 @@ ifeq ($(TARGET),musl) CFLAGS := -static -no-pie ifeq ($(ARCH),x86_64) RUST_TARGET := x86_64-unknown-linux-musl + RUSTFLAGS := "" else ifeq ($(ARCH),aarch64) RUST_TARGET := aarch64-unknown-linux-musl + RUSTFLAGS := "-C linker=aarch64-linux-musl-ld" else ifeq ($(ARCH),riscv64) $(warning "Warn: Rust musl target not supported for riscv64") - RUST_TARGET := + RUST_TARGET := "" + RUSTFLAGS := "" else $(error "Unknown ARCH") endif @@ -51,15 +54,17 @@ build_c: done build_rust: - @for app in $(shell find rust -name Cargo.toml); do \ - echo "Building $$(dirname $${app})"; \ - app_name=$$(basename $$(dirname $${app})); \ - cargo build --release --target $(RUST_TARGET) --manifest-path $${app} ; \ - cp $$(dirname $${app})/target/$(RUST_TARGET)/release/$${app_name} build/$(ARCH)/$${app_name}_rust ; \ - done + if [ -n $(RUST_TARGET) ]; then \ + for app in $(shell find rust -name Cargo.toml); do \ + echo "Building $$(dirname $${app})"; \ + app_name=$$(basename $$(dirname $${app})); \ + RUSTFLAGS=$(RUSTFLAGS) cargo build --release --target $(RUST_TARGET) --manifest-path $${app} ; \ + cp $$(dirname $${app})/target/$(RUST_TARGET)/release/$${app_name} build/$(ARCH)/$${app_name}_rust ; \ + done \ + fi clean: - @rm -rf build/$(ARCH) + @rm -rf build @for app in $(shell find rust -name Cargo.toml); do \ app_name=$$(basename $$(dirname $${app})); \ cargo clean --manifest-path $${app} ; \ diff --git a/apps/nimbos/c/CMakeLists.txt b/apps/nimbos/c/CMakeLists.txt index b581ab7e..0557bd27 100644 --- a/apps/nimbos/c/CMakeLists.txt +++ b/apps/nimbos/c/CMakeLists.txt @@ -60,9 +60,19 @@ foreach(PATH ${SRCS}) ) endforeach() -add_custom_command( - OUTPUT syscall_ids.h - COMMAND sed ARGS -n -e s/__NR_/SYS_/p - < ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h.in - > ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h -) +# If arch is not x86_64, we need to use different syscall ids +if (NOT ${ARCH} STREQUAL x86_64) + add_custom_command( + OUTPUT syscall_ids.h + COMMAND sed ARGS -n -e s/__NR_/SYS_/p + < ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h.no_x86.in + > ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h + ) +else() + add_custom_command( + OUTPUT syscall_ids.h + COMMAND sed ARGS -n -e s/__NR_/SYS_/p + < ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h.in + > ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h + ) +endif() \ No newline at end of file diff --git a/apps/nimbos/c/lib/syscall_ids.h.no_x86.in b/apps/nimbos/c/lib/syscall_ids.h.no_x86.in new file mode 100644 index 00000000..e1c9c7c5 --- /dev/null +++ b/apps/nimbos/c/lib/syscall_ids.h.no_x86.in @@ -0,0 +1,11 @@ +#define __NR_read 63 +#define __NR_write 64 +#define __NR_exit 93 +#define __NR_yield 124 +#define __NR_getpid 172 +#define __NR_clone 220 +#define __NR_fork 220 +#define __NR_exec 221 +#define __NR_waitpid 260 +#define __NR_clock_gettime 403 +#define __NR_clock_nanosleep 407 diff --git a/apps/nimbos/rust/Cargo.toml b/apps/nimbos/rust/Cargo.toml index 57f99b2d..2a6d1dfb 100644 --- a/apps/nimbos/rust/Cargo.toml +++ b/apps/nimbos/rust/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cfg-if = "1.0" \ No newline at end of file diff --git a/apps/nimbos/rust/src/syscall.rs b/apps/nimbos/rust/src/syscall.rs index c0f22134..25d32c55 100644 --- a/apps/nimbos/rust/src/syscall.rs +++ b/apps/nimbos/rust/src/syscall.rs @@ -3,17 +3,34 @@ use crate::arch::syscall; pub use crate::arch::sys_clone; -pub const SYSCALL_READ: usize = 0; -pub const SYSCALL_WRITE: usize = 1; -pub const SYSCALL_YIELD: usize = 24; -pub const SYSCALL_GETPID: usize = 39; -pub const SYSCALL_CLONE: usize = 56; -pub const SYSCALL_FORK: usize = 57; -pub const SYSCALL_EXEC: usize = 59; -pub const SYSCALL_EXIT: usize = 60; -pub const SYSCALL_WAITPID: usize = 61; -pub const SYSCALL_CLOCK_GETTIME: usize = 228; -pub const SYSCALL_CLOCK_NANOSLEEP: usize = 230; +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + pub const SYSCALL_READ: usize = 0; + pub const SYSCALL_WRITE: usize = 1; + pub const SYSCALL_YIELD: usize = 24; + pub const SYSCALL_GETPID: usize = 39; + pub const SYSCALL_CLONE: usize = 56; + pub const SYSCALL_FORK: usize = 57; + pub const SYSCALL_EXEC: usize = 59; + pub const SYSCALL_EXIT: usize = 60; + pub const SYSCALL_WAITPID: usize = 61; + pub const SYSCALL_CLOCK_GETTIME: usize = 228; + pub const SYSCALL_CLOCK_NANOSLEEP: usize = 230; + } + else { + pub const SYSCALL_READ: usize = 63; + pub const SYSCALL_WRITE: usize = 64; + pub const SYSCALL_YIELD: usize = 124; + pub const SYSCALL_GETPID: usize = 172; + pub const SYSCALL_CLONE: usize = 220; + pub const SYSCALL_FORK: usize = 220; + pub const SYSCALL_EXEC: usize = 221; + pub const SYSCALL_EXIT: usize = 93; + pub const SYSCALL_WAITPID: usize = 260; + pub const SYSCALL_CLOCK_GETTIME: usize = 403; + pub const SYSCALL_CLOCK_NANOSLEEP: usize = 407; + } +} pub fn sys_read(fd: usize, buffer: &mut [u8]) -> isize { syscall( diff --git a/build.rs b/build.rs index 64a49f64..40a278e5 100644 --- a/build.rs +++ b/build.rs @@ -102,10 +102,10 @@ fn gen_kernel_config(arch: &str) -> Result<()> { let key_name = key.to_uppercase().replace('-', "_"); match value { toml_edit::Value::Integer(i) => { - writeln!(f, "pub(crate) const {}: usize = {};", key_name, i)?; + writeln!(f, "pub const {}: usize = {};", key_name, i)?; } toml_edit::Value::String(s) => { - writeln!(f, "pub(crate) const {}: &str = \"{}\";", key_name, s)?; + writeln!(f, "pub const {}: &str = \"{}\";", key_name, s)?; } _ => { panic!("Unsupported value type"); diff --git a/configs/aarch64.toml b/configs/aarch64.toml index 68555928..5409d457 100644 --- a/configs/aarch64.toml +++ b/configs/aarch64.toml @@ -1,7 +1,17 @@ +# The base address of the user space. +user_space_base = 0x1000 +# The size of the user space. +user_space_size = 0x7fff_ffff_f000 + # The base address of the user heap. -user-heap-base = 0x3fc0_0000 +user_heap_base = 0x3fc0_0000 # The size of the user heap. -user-heap-size = 0x40_0000 +user_heap_size = 0x40_0000 + +# The highest address of the user stack. +user_stack_top = 0x7fff_0000_0000 +# The size of the user stack. +user_stack_size = 0x1_0000 # The size of the kernel stack. -kernel-stack-size = 0x40000 \ No newline at end of file +kernel_stack_size = 0x40000 \ No newline at end of file diff --git a/configs/riscv64.toml b/configs/riscv64.toml index c0a2f8b8..f1f46bcf 100644 --- a/configs/riscv64.toml +++ b/configs/riscv64.toml @@ -1,7 +1,17 @@ +# The base address of the user space. +user_space_base = 0x1000 +# The size of the user space. +user_space_size = 0x3f_ffff_f000 + +# The base address of the user heap. +user_heap_base = 0x3fc0_0000 +# The size of the user heap. +user_heap_size = 0x40_0000 + # The highest address of the user stack. -user-stack-top = 0x4_0000_0000 +user_stack_top = 0x4_0000_0000 # The size of the user stack. -user-stack-size = 0x1_0000 +user_stack_size = 0x1_0000 # The size of the kernel stack. -kernel-stack-size = 0x40000 \ No newline at end of file +kernel_stack_size = 0x40000 \ No newline at end of file diff --git a/configs/x86_64.toml b/configs/x86_64.toml index 18426a62..5409d457 100644 --- a/configs/x86_64.toml +++ b/configs/x86_64.toml @@ -1,7 +1,17 @@ +# The base address of the user space. +user_space_base = 0x1000 +# The size of the user space. +user_space_size = 0x7fff_ffff_f000 + +# The base address of the user heap. +user_heap_base = 0x3fc0_0000 +# The size of the user heap. +user_heap_size = 0x40_0000 + # The highest address of the user stack. -user-stack-top = 0x7fff_0000_0000 +user_stack_top = 0x7fff_0000_0000 # The size of the user stack. -user-stack-size = 0x1_0000 +user_stack_size = 0x1_0000 # The size of the kernel stack. -kernel-stack-size = 0x40000 \ No newline at end of file +kernel_stack_size = 0x40000 \ No newline at end of file diff --git a/src/mm.rs b/src/mm.rs index 92e9f7a1..bbdac681 100644 --- a/src/mm.rs +++ b/src/mm.rs @@ -19,8 +19,11 @@ use crate::{config, loader}; /// - The second return value is the top of the user stack. /// - The third return value is the address space of the user app. pub fn load_user_app(app_name: &str) -> AxResult<(VirtAddr, VirtAddr, AddrSpace)> { - let mut uspace = axmm::new_user_aspace()?; - let elf_info = loader::load_elf(app_name, VirtAddr::from_usize(0)); + let mut uspace = axmm::new_user_aspace( + VirtAddr::from_usize(config::USER_SPACE_BASE), + config::USER_SPACE_SIZE, + )?; + let elf_info = loader::load_elf(app_name, uspace.base()); for segement in elf_info.segments { debug!( "Mapping ELF segment: [{:#x?}, {:#x?}) flags: {:#x?}",