From f674874e9104649a23174c7316a494232fdb72ad Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Tue, 1 Aug 2023 15:36:45 +0800 Subject: [PATCH] Rename eval to syscall test and fix return value --- .cargo/config.toml | 2 +- Makefile | 11 ++-- README.md | 11 ++-- build/src/main.rs | 4 +- framework/jinux-frame/src/lib.rs | 9 ++- regression/Makefile | 88 +++++++++++++++++++++--------- services/libs/jinux-std/src/lib.rs | 12 ++-- 7 files changed, 93 insertions(+), 44 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 74e3b891e..c67d7be2e 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,7 +6,7 @@ runner = "cargo run --package jinux-build --" kcheck = "check --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" kbuild = "build --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" krun = "run --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" -keval = "run --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem -- --eval" +ksctest = "run --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem -- --syscall-test" ktest = "test --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" component-check = "component check --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" diff --git a/Makefile b/Makefile index 97753c49e..25b6d5de7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all build clean docs fmt run setup test tools eval +.PHONY: all build clean docs fmt run setup test tools syscall_test syscall_bin all: build @@ -16,11 +16,14 @@ tools: @cd services/libs/comp-sys && cargo install --path cargo-component run: build - @cargo krun + @cargo krun || exit $$(($$? >> 1)) # FIXME: Exit code manipulation is not needed using non-x86 QEMU + +syscall_bin: + @make --no-print-directory -C regression/syscall_test # Test Jinux in a QEMU guest VM and run a series of evaluations. -eval: build - @cargo keval +syscall_test: syscall_bin build + @cargo ksctest || exit $$(($$? >> 1)) # FIXME: Exit code manipulation is not needed using non-x86 QEMU # The usermode cargo test of Jinux frame and Jinux standard library. test: build diff --git a/README.md b/README.md index e9a89b452..94f3a5c54 100644 --- a/README.md +++ b/README.md @@ -75,14 +75,15 @@ cargo component-check ### Syscall Test -If we have already built the project for normal use, please clean the project before running syscall test. +This command will build the syscall test binary and run Jinux with it in QEMU. ```bash -make clean +make syscall_test ``` -For running syscall tests, we can run following command to build test binaries and run the OS for testing purpose. -```bash -ENABLE_SYSCALL_TEST=1 make run +If you wish to test it interactively inside a shell in Jinux. +``` +make syscall_bin +make run ``` Then, we can run the following script inside the OS to run all syscall test cases. diff --git a/build/src/main.rs b/build/src/main.rs index 6915c915e..6308a0734 100644 --- a/build/src/main.rs +++ b/build/src/main.rs @@ -21,7 +21,7 @@ struct Args { // Options. /// Automatically run integration tests and exit. #[arg(short, long, default_value_t = false)] - eval: bool, + syscall_test: bool, /// Emulate Intel IOMMU by QEMU. #[arg(short, long, default_value_t = false)] @@ -90,7 +90,7 @@ fn main() { qemu_args.push("-drive"); qemu_args.push(fs_image.as_str()); - let bootdev_image = create_bootdev_image(args.path, args.eval); + let bootdev_image = create_bootdev_image(args.path, args.syscall_test); qemu_cmd.arg("-cdrom"); qemu_cmd.arg(bootdev_image.as_str()); diff --git a/framework/jinux-frame/src/lib.rs b/framework/jinux-frame/src/lib.rs index 2cdfdf7bb..a93a90bc3 100644 --- a/framework/jinux-frame/src/lib.rs +++ b/framework/jinux-frame/src/lib.rs @@ -146,11 +146,16 @@ pub fn panic_handler() { // println!("---END BACKTRACE---"); // } } + +/// The exit code of x86 QEMU. In `qemu-system-x86_64` the exit code will be +/// `(code << 1) | 1`. So you could never let QEMU invoke `exit(0)`. Check +/// if the result is `0b01` instead. +#[cfg(target_arch = "x86_64")] #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u32)] pub enum QemuExitCode { - Success = 0x10, - Failed = 0x11, + Success = 0b0, + Failed = 0b1, } pub fn exit_qemu(exit_code: QemuExitCode) -> ! { diff --git a/regression/Makefile b/regression/Makefile index a84c4ca18..966f690e0 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -5,37 +5,73 @@ INITRAMFS := $(BUILD_DIR)/initramfs RAMDISK := $(BUILD_DIR)/ramdisk.cpio.gz SHELL := /bin/bash -ifneq (, $(wildcard $(INITRAMFS)/. )) - INITRAMFS_DIRS := $(shell find $(INITRAMFS) -type d 2>/dev/null | sed 's/ /\\ /g' | sed 's/:/\\:/g' || true) - INITRAMFS_FILES := $(shell find $(INITRAMFS) -type f 2>/dev/null | sed 's/ /\\ /g' | sed 's/:/\\:/g' || true) -endif - .PHONY: all clean all: build -$(INITRAMFS): - @rm -rf $@ && mkdir -p $@ - @# Mkdir necessary folders - @mkdir -p $@/bin $@/etc $@/sbin $@/usr/bin $@/root $@/tmp $@/opt $@/proc $@/dev $@/lib64 $@/lib/x86_64-linux-gnu - @# Install busybox - @/bin/busybox --install -s $@/bin - @cp /usr/bin/busybox $@/usr/bin - @# Copy necessary libs - @cp -L /lib64/ld-linux-x86-64.so.2 $@/lib64 - @cp -L /lib/x86_64-linux-gnu/libc.so.6 $@/lib/x86_64-linux-gnu - @cp -L /lib/x86_64-linux-gnu/libstdc++.so.6 $@/lib/x86_64-linux-gnu - @cp -L /lib/x86_64-linux-gnu/libm.so.6 $@/lib/x86_64-linux-gnu - @cp -L /lib/x86_64-linux-gnu/libgcc_s.so.1 $@/lib/x86_64-linux-gnu - @cp -L /lib/x86_64-linux-gnu/libpthread.so.0 $@/lib/x86_64-linux-gnu - @# Copy from apps - @make --no-print-directory -C apps -ifeq ($(ENABLE_SYSCALL_TEST), 1) - @# Copy syscall test suite - @make --no-print-directory -C syscall_test -endif +TARGETS=\ + $(INITRAMFS)/lib/x86_64-linux-gnu \ + $(INITRAMFS)/lib64 \ + $(INITRAMFS)/bin \ + $(INITRAMFS)/usr/bin \ + $(INITRAMFS)/regression \ + $(INITRAMFS)/etc \ + $(INITRAMFS)/sbin \ + $(INITRAMFS)/root \ + $(INITRAMFS)/tmp \ + $(INITRAMFS)/opt \ + $(INITRAMFS)/proc \ + $(INITRAMFS)/dev -$(RAMDISK): $(INITRAMFS) $(INITRAMFS_DIRS) $(INITRAMFS_FILES) +# Copy necessary libs +$(INITRAMFS)/lib/x86_64-linux-gnu: + @mkdir -p $@ + @cp -L /lib/x86_64-linux-gnu/libc.so.6 $@ + @cp -L /lib/x86_64-linux-gnu/libstdc++.so.6 $@ + @cp -L /lib/x86_64-linux-gnu/libm.so.6 $@ + @cp -L /lib/x86_64-linux-gnu/libgcc_s.so.1 $@ + @cp -L /lib/x86_64-linux-gnu/libpthread.so.0 $@ + +$(INITRAMFS)/lib64: + @mkdir -p $@ + @cp -L /lib64/ld-linux-x86-64.so.2 $@ + +# Install busybox +$(INITRAMFS)/bin: + @mkdir -p $@ + @/bin/busybox --install -s $@ + +$(INITRAMFS)/usr/bin: $(INITRAMFS)/bin + @mkdir -p $@ + @cp /usr/bin/busybox $@ + +# Copy from apps +$(INITRAMFS)/regression: + @make --no-print-directory -C apps + +# Make necessary directories +$(INITRAMFS)/etc: + @mkdir -p $@ + +$(INITRAMFS)/sbin: + @mkdir -p $@ + +$(INITRAMFS)/root: + @mkdir -p $@ + +$(INITRAMFS)/tmp: + @mkdir -p $@ + +$(INITRAMFS)/opt: + @mkdir -p $@ + +$(INITRAMFS)/proc: + @mkdir -p $@ + +$(INITRAMFS)/dev: + @mkdir -p $@ + +$(RAMDISK): $(TARGETS) @echo "Generating the ramdisk image..." @(cd $(INITRAMFS); find . | cpio -o -H newc | gzip) > $@ diff --git a/services/libs/jinux-std/src/lib.rs b/services/libs/jinux-std/src/lib.rs index 19b7f6ff3..be860eea7 100644 --- a/services/libs/jinux-std/src/lib.rs +++ b/services/libs/jinux-std/src/lib.rs @@ -25,8 +25,8 @@ use crate::{ process::status::ProcessStatus, thread::{kernel_thread::KernelThreadExt, Thread}, }; -use alloc::sync::Arc; -use jinux_frame::{boot, exit_qemu}; +use core::sync::atomic::Ordering; +use jinux_frame::{boot, exit_qemu, QemuExitCode}; use process::Process; extern crate alloc; @@ -89,8 +89,12 @@ fn init_thread() { loop { // If initproc becomes zombie, then exit qemu. if *initproc.status().lock() == ProcessStatus::Zombie { - println!("Exit jinux."); - exit_qemu(jinux_frame::QemuExitCode::Success); + let exit_code = if initproc.exit_code().load(Ordering::Relaxed) == 0 { + QemuExitCode::Success + } else { + QemuExitCode::Failed + }; + exit_qemu(exit_code); } // We don't have preemptive scheduler now. // The long running init thread should yield its own execution to allow other tasks to go on.