From 03015e2559f4af89a22aa3bcd9d44d017aad9e60 Mon Sep 17 00:00:00 2001 From: LoGin Date: Sun, 30 Mar 2025 01:28:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=9C=A8rv64?= =?UTF-8?q?=E4=B8=8B=EF=BC=8C=E8=BF=90=E8=A1=8Crust=E7=BC=96=E5=86=99?= =?UTF-8?q?=E7=9A=84helloworld=E7=A8=8B=E5=BA=8F=20(#1125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加 riscv_rust_init 这个helloworld程序 Signed-off-by: longjin * feat: 支持在riscv下启动rust编写的hello world程序 TODO: 支持sys ppoll Signed-off-by: longjin * chore: 更新构建容器版本至v1.9 Signed-off-by: longjin * 1 --------- Signed-off-by: longjin --- .github/workflows/makefile.yml | 16 +++--- kernel/Cargo.lock | 2 +- kernel/src/arch/riscv64/interrupt/handle.rs | 31 ++++++++--- .../src/driver/irqchip/riscv_sifive_plic.rs | 2 +- kernel/src/init/cmdline.rs | 1 + kernel/src/init/initial_kthread.rs | 1 + kernel/src/syscall/mod.rs | 5 ++ tools/BUILD_CONTAINER_VERSION | 2 +- tools/bootstrap.sh | 2 + tools/build_in_docker.sh | 2 +- tools/run-qemu.sh | 54 +++++++++++++------ user/apps/riscv_init/Makefile | 9 +++- .../riscv_rust_init/.cargo/config.toml | 2 + .../riscv_init/riscv_rust_init/.gitignore | 1 + .../riscv_init/riscv_rust_init/Cargo.toml | 6 +++ user/apps/riscv_init/riscv_rust_init/Makefile | 50 +++++++++++++++++ .../riscv_init/riscv_rust_init/src/main.rs | 4 ++ 17 files changed, 152 insertions(+), 38 deletions(-) create mode 100644 user/apps/riscv_init/riscv_rust_init/.cargo/config.toml create mode 100644 user/apps/riscv_init/riscv_rust_init/.gitignore create mode 100644 user/apps/riscv_init/riscv_rust_init/Cargo.toml create mode 100644 user/apps/riscv_init/riscv_rust_init/Makefile create mode 100644 user/apps/riscv_init/riscv_rust_init/src/main.rs diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index 88ad306a..f2696215 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -11,14 +11,14 @@ jobs: name: Format check ${{ matrix.arch }} runs-on: ubuntu-latest continue-on-error: true - container: dragonos/dragonos-dev:v1.8 + container: dragonos/dragonos-dev:v1.9 strategy: matrix: arch: [x86_64, riscv64] steps: - - run: echo "Running in dragonos/dragonos-dev:v1.8" + - run: echo "Running in dragonos/dragonos-dev:v1.9" - uses: actions/checkout@v3 - name: Format check @@ -35,14 +35,14 @@ jobs: name: Kernel static test ${{ matrix.arch }} runs-on: ubuntu-latest continue-on-error: true - container: dragonos/dragonos-dev:v1.8 + container: dragonos/dragonos-dev:v1.9 strategy: matrix: arch: [x86_64, riscv64] steps: - - run: echo "Running in dragonos/dragonos-dev:v1.8" + - run: echo "Running in dragonos/dragonos-dev:v1.9" - uses: actions/checkout@v3 @@ -55,10 +55,10 @@ jobs: build-x86_64: runs-on: ubuntu-latest - container: dragonos/dragonos-dev:v1.8 + container: dragonos/dragonos-dev:v1.9 steps: - - run: echo "Running in dragonos/dragonos-dev:v1.8" + - run: echo "Running in dragonos/dragonos-dev:v1.9" - uses: actions/checkout@v3 - name: build the DragonOS @@ -77,10 +77,10 @@ jobs: build-riscv64: runs-on: ubuntu-latest - container: dragonos/dragonos-dev:v1.8 + container: dragonos/dragonos-dev:v1.9 steps: - - run: echo "Running in dragonos/dragonos-dev:v1.8" + - run: echo "Running in dragonos/dragonos-dev:v1.9" - uses: actions/checkout@v3 with: diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 64b68517..f3ef4f38 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -1839,7 +1839,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "virtio-drivers" version = "0.7.2" -source = "git+https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers?rev=f91c807965#f91c8079658dbc7cc230bf041325b94a0ab2e301" +source = "git+https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers?rev=415ab38ff9#415ab38ff99f3c8e150269c04f65d684ba9d1365" dependencies = [ "bitflags 2.9.0", "log", diff --git a/kernel/src/arch/riscv64/interrupt/handle.rs b/kernel/src/arch/riscv64/interrupt/handle.rs index fc971679..de051d4a 100644 --- a/kernel/src/arch/riscv64/interrupt/handle.rs +++ b/kernel/src/arch/riscv64/interrupt/handle.rs @@ -151,10 +151,18 @@ fn do_trap_insn_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError let vaddr = trap_frame.badaddr; let cause = trap_frame.cause; let epc = trap_frame.epc; - error!( - "riscv64_do_irq: do_insn_page_fault vaddr: {:#x}, cause: {:?} epc: {:#x}", - vaddr, cause, epc - ); + if trap_frame.is_from_user() { + error!( + "riscv64_do_irq: do_trap_insn_page_fault(user mode): epc: {epc:#x}, vaddr={:#x}, cause={:?}", + vaddr, cause + ); + } else { + panic!( + "riscv64_do_irq: do_trap_insn_page_fault(kernel mode): epc: {epc:#x}, vaddr={:#x}, cause={:?}", + vaddr, cause + ); + } + loop { spin_loop(); } @@ -165,10 +173,17 @@ fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError let vaddr = trap_frame.badaddr; let cause = trap_frame.cause; let epc = trap_frame.epc; - error!( - "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}", - vaddr, cause - ); + if trap_frame.is_from_user() { + error!( + "riscv64_do_irq: do_trap_load_page_fault(user mode): epc: {epc:#x}, vaddr={:#x}, cause={:?}", + vaddr, cause + ); + } else { + panic!( + "riscv64_do_irq: do_trap_load_page_fault(kernel mode): epc: {epc:#x}, vaddr={:#x}, cause={:?}", + vaddr, cause + ); + } loop { spin_loop(); diff --git a/kernel/src/driver/irqchip/riscv_sifive_plic.rs b/kernel/src/driver/irqchip/riscv_sifive_plic.rs index 05bc52f0..c8639f03 100644 --- a/kernel/src/driver/irqchip/riscv_sifive_plic.rs +++ b/kernel/src/driver/irqchip/riscv_sifive_plic.rs @@ -649,7 +649,7 @@ pub(super) fn do_plic_irq(trap_frame: &mut TrapFrame) { if claim == 0 { break; } - debug!("plic: claim: {claim:?}"); + // debug!("plic: claim: {claim:?}"); let hwirq = HardwareIrqNumber::new(claim); if let Err(e) = GenericIrqHandler::handle_domain_irq(domain.clone(), hwirq, trap_frame) { diff --git a/kernel/src/init/cmdline.rs b/kernel/src/init/cmdline.rs index a313be51..0676e1df 100644 --- a/kernel/src/init/cmdline.rs +++ b/kernel/src/init/cmdline.rs @@ -321,6 +321,7 @@ impl KernelCmdlineManager { continue; } + log::debug!("cmdline: argument: {:?} ", argument); let (node, option, value) = match self.split_arg(argument) { Some(v) => v, None => continue, diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index d3ed834f..66839905 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/kernel/src/init/initial_kthread.rs @@ -128,6 +128,7 @@ fn try_to_run_init_process( ext_args: &Option<&str>, trap_frame: &mut TrapFrame, ) -> Result<(), SystemError> { + log::debug!("Trying to run init process at {:?}", path); let mut args_to_insert = alloc::vec::Vec::new(); args_to_insert.push(CString::new(path).unwrap()); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index d227836f..18faf948 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -885,6 +885,11 @@ impl Syscall { Self::poll(fds, nfds, timeout) } + SYS_PPOLL => { + log::warn!("SYS_PPOLL has not yet been implemented"); + Ok(0) + } + SYS_SETPGID => { warn!("SYS_SETPGID has not yet been implemented"); Ok(0) diff --git a/tools/BUILD_CONTAINER_VERSION b/tools/BUILD_CONTAINER_VERSION index 8a9f2d79..12068070 100644 --- a/tools/BUILD_CONTAINER_VERSION +++ b/tools/BUILD_CONTAINER_VERSION @@ -1 +1 @@ -v1.8 \ No newline at end of file +v1.9 \ No newline at end of file diff --git a/tools/bootstrap.sh b/tools/bootstrap.sh index ff6a5d96..b8847168 100644 --- a/tools/bootstrap.sh +++ b/tools/bootstrap.sh @@ -249,6 +249,8 @@ rustInstall() { rustup target add riscv64imac-unknown-none-elf --toolchain $RUST_VERSION-riscv64gc-unknown-linux-gnu rustup target add riscv64gc-unknown-none-elf --toolchain $RUST_VERSION_OLD-riscv64gc-unknown-linux-gnu rustup target add riscv64imac-unknown-none-elf --toolchain $RUST_VERSION_OLD-riscv64gc-unknown-linux-gnu + rustup target add riscv64gc-unknown-linux-musl --toolchain $RUST_VERSION-riscv64gc-unknown-linux-gnu + rustup target add riscv64gc-unknown-linux-musl --toolchain $RUST_VERSION_OLD-riscv64gc-unknown-linux-gnu rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu rustup component add rust-src diff --git a/tools/build_in_docker.sh b/tools/build_in_docker.sh index 206f1797..ecfcbbee 100644 --- a/tools/build_in_docker.sh +++ b/tools/build_in_docker.sh @@ -1,6 +1,6 @@ docker rm -f dragonos-build || echo "No existed container" cpu_count=$(cat /proc/cpuinfo |grep "processor"|wc -l) -docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.8 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.9 bash << EOF source ~/.cargo/env source ~/.bashrc cd /data diff --git a/tools/run-qemu.sh b/tools/run-qemu.sh index a82067e4..9df94cc5 100644 --- a/tools/run-qemu.sh +++ b/tools/run-qemu.sh @@ -85,7 +85,10 @@ QEMU_ACCELARATE="" QEMU_ARGUMENT=" -no-reboot " QEMU_DEVICES="" -KERNEL_CMDLINE="" +# 设置无图形界面模式 +QEMU_NOGRAPHIC=false + +KERNEL_CMDLINE=" " BIOS_TYPE="" #这个变量为true则使用virtio磁盘 @@ -116,15 +119,12 @@ fi if [ ${ARCH} == "riscv64" ]; then # 如果是riscv64架构,就不需要图形界面 - QEMU_ARGUMENT+=" --nographic " - # 从控制台显示 - QEMU_MONITOR="" - QEMU_SERIAL="" + QEMU_NOGRAPHIC=true fi while true;do case "$1" in - --bios) + --bios) case "$2" in uefi) #uefi启动新增ovmf.fd固件 BIOS_TYPE=uefi @@ -141,21 +141,43 @@ while true;do window) ;; nographic) - QEMU_SERIAL=" -serial chardev:mux -monitor chardev:mux -chardev stdio,id=mux,mux=on,signal=off,logfile=${QEMU_SERIAL_LOG_FILE} " - # 添加 virtio console 设备 - QEMU_DEVICES+=" -device virtio-serial -device virtconsole,chardev=mux " - KERNEL_CMDLINE+=" console=/dev/hvc0 " - QEMU_MONITOR="" - QEMU_ARGUMENT+=" --nographic " - QEMU_ARGUMENT+=" -kernel ../bin/kernel/kernel.elf " - QEMU_ARGUMENT+="-append ${KERNEL_CMDLINE}" + QEMU_NOGRAPHIC=true ;; esac;shift 2;; *) break - esac + esac done +if [ ${QEMU_NOGRAPHIC} == true ]; then + QEMU_SERIAL=" -serial chardev:mux -monitor chardev:mux -chardev stdio,id=mux,mux=on,signal=off,logfile=${QEMU_SERIAL_LOG_FILE} " + + # 添加 virtio console 设备 + if [${ARCH} == "x86_64" ]; then + QEMU_DEVICES+=" -device virtio-serial -device virtconsole,chardev=mux " + elif [ ${ARCH} == "riscv64" ]; then + QEMU_DEVICES+=" -device virtio-serial-device -device virtconsole,chardev=mux " + fi + + KERNEL_CMDLINE+=" console=/dev/hvc0 " + QEMU_MONITOR="" + QEMU_ARGUMENT+=" --nographic " + + if [ ${ARCH} == "x86_64" ]; then + QEMU_ARGUMENT+=" -kernel ../bin/kernel/kernel.elf " + fi +fi + +setup_kernel_init_program() { + if [ ${ARCH} == "x86_64" ]; then + KERNEL_CMDLINE+=" init=/bin/dragonreach " + elif [ ${ARCH} == "riscv64" ]; then + KERNEL_CMDLINE+=" init=/bin/riscv_rust_init " + fi +} + +# 设置内核init程序 +setup_kernel_init_program # ps: 下面这条使用tap的方式,无法dhcp获取到ip,暂时不知道为什么 # QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 " @@ -222,7 +244,7 @@ else elif [ ${ARCH} == riscv64 ] ;then # 如果是riscv64架构,就与efi启动一样 install_riscv_uboot - sudo ${QEMU} -kernel ${RISCV64_UBOOT_PATH}/u-boot.bin ${QEMU_ARGUMENT} + sudo ${QEMU} -kernel ${RISCV64_UBOOT_PATH}/u-boot.bin ${QEMU_ARGUMENT} -append "${KERNEL_CMDLINE}" else echo "不支持的架构: ${ARCH}" fi diff --git a/user/apps/riscv_init/Makefile b/user/apps/riscv_init/Makefile index a75ff55d..87f86453 100644 --- a/user/apps/riscv_init/Makefile +++ b/user/apps/riscv_init/Makefile @@ -6,15 +6,20 @@ endif CC=$(CROSS_COMPILE)gcc + .PHONY: all all: main.c - $(CC) -static -o init main.c +# $(CC) -static -o init main.c + $(MAKE) -C riscv_rust_init ARCH=$(ARCH) install .PHONY: install clean install: all - mv init $(DADK_CURRENT_BUILD_DIR)/init + $(MAKE) -C riscv_rust_init ARCH=$(ARCH) install +# mv init $(DADK_CURRENT_BUILD_DIR)/init + clean: rm init *.o + $(MAKE) -C riscv_rust_init ARCH=$(ARCH) clean fmt: diff --git a/user/apps/riscv_init/riscv_rust_init/.cargo/config.toml b/user/apps/riscv_init/riscv_rust_init/.cargo/config.toml new file mode 100644 index 00000000..d5865724 --- /dev/null +++ b/user/apps/riscv_init/riscv_rust_init/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.riscv64gc-unknown-linux-musl] +linker = "riscv64-linux-gnu-gcc" diff --git a/user/apps/riscv_init/riscv_rust_init/.gitignore b/user/apps/riscv_init/riscv_rust_init/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/user/apps/riscv_init/riscv_rust_init/.gitignore @@ -0,0 +1 @@ +/target diff --git a/user/apps/riscv_init/riscv_rust_init/Cargo.toml b/user/apps/riscv_init/riscv_rust_init/Cargo.toml new file mode 100644 index 00000000..ab9f2534 --- /dev/null +++ b/user/apps/riscv_init/riscv_rust_init/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "riscv_rust_init" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/user/apps/riscv_init/riscv_rust_init/Makefile b/user/apps/riscv_init/riscv_rust_init/Makefile new file mode 100644 index 00000000..7efb0f91 --- /dev/null +++ b/user/apps/riscv_init/riscv_rust_init/Makefile @@ -0,0 +1,50 @@ +# The toolchain we use. +# You can get it by running DragonOS' `tools/bootstrap.sh` +TOOLCHAIN="+nightly-2024-11-05-x86_64-unknown-linux-gnu" + +ifeq ($(ARCH), riscv64) +RUSTFLAGS+="-C target-feature=+crt-static" +endif + +ifdef DADK_CURRENT_BUILD_DIR +# 如果是在dadk中编译,那么安装到dadk的安装目录中 + INSTALL_DIR = $(DADK_CURRENT_BUILD_DIR) +else +# 如果是在本地编译,那么安装到当前目录下的install目录中 + INSTALL_DIR = ./install +endif + + +ifeq ($(ARCH), x86_64) + export RUST_TARGET=x86_64-unknown-linux-musl +else ifeq ($(ARCH), riscv64) + export RUST_TARGET=riscv64gc-unknown-linux-musl +else +# 默认为x86_64,用于本地编译 + export RUST_TARGET=x86_64-unknown-linux-musl +endif + +build: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) + +run-dragonreach: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET) --bin DragonReach + +clean: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean + +build-release: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) --release + +clean-release: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET) --release + +fmt: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt + +fmt-check: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt --check + +.PHONY: install +install: + RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path . --no-track --root $(INSTALL_DIR) --force \ No newline at end of file diff --git a/user/apps/riscv_init/riscv_rust_init/src/main.rs b/user/apps/riscv_init/riscv_rust_init/src/main.rs new file mode 100644 index 00000000..c6ed5c4e --- /dev/null +++ b/user/apps/riscv_init/riscv_rust_init/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + println!("rs: Hello, world!"); + loop {} +}