mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
feat: 支持在rv64下,运行rust编写的helloworld程序 (#1125)
* 添加 riscv_rust_init 这个helloworld程序 Signed-off-by: longjin <longjin@DragonOS.org> * feat: 支持在riscv下启动rust编写的hello world程序 TODO: 支持sys ppoll Signed-off-by: longjin <longjin@DragonOS.org> * chore: 更新构建容器版本至v1.9 Signed-off-by: longjin <longjin@DragonOS.org> * 1 --------- Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
55833537f1
commit
03015e2559
16
.github/workflows/makefile.yml
vendored
16
.github/workflows/makefile.yml
vendored
@ -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:
|
||||
|
2
kernel/Cargo.lock
generated
2
kernel/Cargo.lock
generated
@ -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",
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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)
|
||||
|
@ -1 +1 @@
|
||||
v1.8
|
||||
v1.9
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -85,7 +85,10 @@ QEMU_ACCELARATE=""
|
||||
QEMU_ARGUMENT=" -no-reboot "
|
||||
QEMU_DEVICES=""
|
||||
|
||||
KERNEL_CMDLINE=""
|
||||
# 设置无图形界面模式
|
||||
QEMU_NOGRAPHIC=false
|
||||
|
||||
KERNEL_CMDLINE=" "
|
||||
|
||||
BIOS_TYPE=""
|
||||
#这个变量为true则使用virtio磁盘
|
||||
@ -116,10 +119,7 @@ fi
|
||||
|
||||
if [ ${ARCH} == "riscv64" ]; then
|
||||
# 如果是riscv64架构,就不需要图形界面
|
||||
QEMU_ARGUMENT+=" --nographic "
|
||||
# 从控制台显示
|
||||
QEMU_MONITOR=""
|
||||
QEMU_SERIAL=""
|
||||
QEMU_NOGRAPHIC=true
|
||||
fi
|
||||
|
||||
while true;do
|
||||
@ -141,14 +141,7 @@ 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;;
|
||||
@ -156,6 +149,35 @@ while true;do
|
||||
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
|
||||
|
@ -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:
|
||||
|
2
user/apps/riscv_init/riscv_rust_init/.cargo/config.toml
Normal file
2
user/apps/riscv_init/riscv_rust_init/.cargo/config.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[target.riscv64gc-unknown-linux-musl]
|
||||
linker = "riscv64-linux-gnu-gcc"
|
1
user/apps/riscv_init/riscv_rust_init/.gitignore
vendored
Normal file
1
user/apps/riscv_init/riscv_rust_init/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
6
user/apps/riscv_init/riscv_rust_init/Cargo.toml
Normal file
6
user/apps/riscv_init/riscv_rust_init/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "riscv_rust_init"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
50
user/apps/riscv_init/riscv_rust_init/Makefile
Normal file
50
user/apps/riscv_init/riscv_rust_init/Makefile
Normal file
@ -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
|
4
user/apps/riscv_init/riscv_rust_init/src/main.rs
Normal file
4
user/apps/riscv_init/riscv_rust_init/src/main.rs
Normal file
@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
println!("rs: Hello, world!");
|
||||
loop {}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user