feat(ci): add CI support for building and booting riscv64 kernel in workflow, within oscomp environment (#6)

* feat(ide): add gdb-multiarch debug support for better stack tracking

* feat(test): add oscomp testcase aquirement

* feat(ci): bump to oscomp test

* feat(ci): new ci procedure

* feat(ci): update CI workflow to replace git mirror and remove unnecessary userland build condition
This commit is contained in:
Samuel Dai 2025-03-21 22:47:57 +08:00 committed by GitHub
parent 510b1c2f0f
commit 717bd9209a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 121 additions and 109 deletions

View File

@ -1,5 +1,6 @@
From docker.educg.net/cg/os-contest:20250226 FROM docker.educg.net/cg/os-contest:20250226
RUN apt update
RUN apt install -y --no-install-recommends \ RUN apt install -y --no-install-recommends \
bison flex libssl-dev bridge-utils dnsmasq sudo iptables bison flex libssl-dev bridge-utils dnsmasq sudo iptables

View File

@ -1,4 +1,4 @@
name: Build Check name: CI for DragonOS
on: on:
push: push:
@ -7,92 +7,49 @@ on:
branches: ["master", "feat-*", "fix-*"] branches: ["master", "feat-*", "fix-*"]
jobs: jobs:
format-check: ci:
name: Format check ${{ matrix.arch }}
runs-on: ubuntu-latest
continue-on-error: true
container: dragonos/dragonos-dev:v1.8
strategy: strategy:
matrix: matrix:
arch: [x86_64, riscv64] arch: [riscv64, x86_64]
runs-on: ubuntu-latest
steps:
- run: echo "Running in dragonos/dragonos-dev:v1.8"
- uses: actions/checkout@v3
- name: Format check
env: env:
ARCH: ${{ matrix.arch }} ARCH: ${{ matrix.arch }}
HOME: /root HOME: /root
container:
image: ghcr.io/samuka007/dragonos-oscomp-ci-docker:pre-2025-03-21
options: --privileged
defaults:
run:
shell: bash -ileo pipefail {0} shell: bash -ileo pipefail {0}
run: |
printf "\n" >> kernel/src/include/bindings/bindings.rs
sed -i 's/arch = ".*"/arch = "${{ matrix.arch }}"/' dadk-manifest.toml
FMT_CHECK=1 make fmt
kernel-static-test:
name: Kernel static test ${{ matrix.arch }}
runs-on: ubuntu-latest
continue-on-error: true
container: dragonos/dragonos-dev:v1.8
strategy:
matrix:
arch: [x86_64, riscv64]
steps: steps:
- run: echo "Running in dragonos/dragonos-dev:v1.8"
- uses: actions/checkout@v3
- name: Run kernel static test
shell: bash -ileo pipefail {0}
env:
ARCH: ${{ matrix.arch }}
HOME: /root
run: bash -c "source /root/.cargo/env && cd kernel && make test && make test-rbpf"
build-x86_64:
runs-on: ubuntu-latest
container: dragonos/dragonos-dev:v1.8
steps:
- run: echo "Running in dragonos/dragonos-dev:v1.8"
- uses: actions/checkout@v3
- name: build the DragonOS
env:
ARCH: x86_64
HOME: /root
shell: bash -ileo pipefail {0}
run: |
source ~/.bashrc
source ~/.cargo/env
export DragonOS_GCC=$HOME/opt/dragonos-gcc/gcc-x86_64-unknown-none/bin
sed -i 's/arch = ".*"/arch = "${{ env.ARCH }}"/' dadk-manifest.toml
make all -j $(nproc)
build-riscv64:
runs-on: ubuntu-latest
container: dragonos/dragonos-dev:v1.8
steps:
- run: echo "Running in dragonos/dragonos-dev:v1.8"
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
submodules: "recursive" submodules: "recursive"
- name: build the DragonOS - name: Change source
shell: bash -ileo pipefail {0}
env:
ARCH: riscv64
HOME: /root
run: | run: |
source ~/.bashrc && source ~/.cargo/env find . -type f \( -name "*.toml" -o -name "Makefile" \) -exec sed -i 's/git\.mirrors\.dragonos\.org\.cn/github\.com/g' {} +
sed -i 's/arch = ".*"/arch = "${{ env.ARCH }}"/' dadk-manifest.toml
make kernel -j $(nproc) - name: build kernel
run: |
make ci-kernel
- name: build userland
if: matrix.arch != 'x86_64'
run: |
make ci-user
- name: generate the disk image
if: matrix.arch != 'x86_64'
run: |
make ci-gendisk
- name: boot test
if: matrix.arch != 'x86_64'
timeout-minutes: 3
run: |
cd oscomp && bash ci-boot-test.sh
- name: Format check
run: |
FMT_CHECK=1 make fmt

28
.vscode/launch.json vendored
View File

@ -7,18 +7,42 @@
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Debug RISCV64 elf", "name": "Debug RISCV64 lldb",
"stopOnEntry": false, "stopOnEntry": false,
"preLaunchTask": "DragonOS: Start riscv64",
"targetCreateCommands": ["target create ${workspaceFolder}/bin/riscv64/kernel/kernel.elf"], "targetCreateCommands": ["target create ${workspaceFolder}/bin/riscv64/kernel/kernel.elf"],
"processCreateCommands": [ "processCreateCommands": [
"gdb-remote localhost:1234", "gdb-remote localhost:1234",
"settings set target.process.follow-fork-mode child",
"continue" // Get over the first trap into the kernel "continue" // Get over the first trap into the kernel
], ],
"args": [], "args": [],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"sourceLanguages": ["c", "cpp", "rust"], "sourceLanguages": ["c", "cpp", "rust"],
"console": "internalConsole" "console": "internalConsole"
},
{
"type": "cppdbg",
"request": "launch",
"name": "Debug RISCV64 gdb-multiarch",
"stopAtConnect": true,
"program": "${workspaceRoot}/bin/riscv64/kernel/kernel.elf",
"miDebuggerPath": "gdb-multiarch",
"miDebuggerServerAddress": "localhost:1234",
"postRemoteConnectCommands": [
{
"text": "set follow-fork-mode child"
}
],
"useExtendedRemote": true,
"args": [],
"cwd": "${workspaceRoot}",
"environment": [],
"internalConsoleOptions": "neverOpen",
"externalConsole": false,
"logging": {
"engineLogging": false
},
"MIMode": "gdb"
} }
] ]
} }

1
.vscode/tasks.json vendored
View File

@ -26,6 +26,7 @@
"options": { "options": {
"cwd": "${workspaceFolder}/oscomp" "cwd": "${workspaceFolder}/oscomp"
}, },
"problemMatcher": [],
"isBackground": true "isBackground": true
} }
] ]

View File

@ -44,6 +44,12 @@ all:
#@make ARCH=x86_64 ci-build #@make ARCH=x86_64 ci-build
@make ARCH=riscv64 ci-build @make ARCH=riscv64 ci-build
ci-get-testcase:
ifneq ($(REGET), 1)
@echo "测试用例已经获取,跳过获取步骤。如需重新获取,请设置 REGET=1"
endif
@cd oscomp && sh ci-testcase.sh
ci-update-submodules: ci-update-submodules:
@echo "更新子模块" @echo "更新子模块"
@sudo chown -R $(shell whoami) . @sudo chown -R $(shell whoami) .
@ -82,6 +88,7 @@ kernel user write_diskimage write_diskimage-uefi qemu qemu-nographic qemu-uefi q
.PHONY: clean .PHONY: clean
clean: clean:
@rm -rf bin
@list='$(SUBDIRS)'; for subdir in $$list; do \ @list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Clean in dir: $$subdir";\ echo "Clean in dir: $$subdir";\
cd $$subdir && $(MAKE) clean;\ cd $$subdir && $(MAKE) clean;\
@ -106,7 +113,7 @@ else
gdb-multiarch -n -x tools/.gdbinit gdb-multiarch -n -x tools/.gdbinit
endif endif
fmt: check_arch fmt:
@echo "格式化代码" @echo "格式化代码"
FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C kernel FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C kernel
FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C user FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C user

View File

@ -1,24 +0,0 @@
# DADK 总控文件
[metadata]
# Target architecture. Options: x86_64, riscv64
arch = "riscv64"
# Hypervisor config path
hypervisor-config = "config/hypervisor.toml"
# RootFS config path
rootfs-config = "config/rootfs.toml"
# Boot config path
boot-config = "config/boot.toml"
# System root directory folder (DADK will copy the files in this directory to the root directory of the disk image)
sysroot-dir = "bin/riscv64/sysroot"
# DADK Root Cache directory path
cache-root-dir = "bin/riscv64/dadk_cache"
# User configuration directory path
# 这个字段只是临时用于兼容旧版本v0.2版本重构完成后会删除
user-config-dir = "user/dadk/config"

View File

@ -25,6 +25,7 @@ clean:
.PHONY: fmt .PHONY: fmt
fmt: fmt:
sed -i '/^[[:space:]]*$$/d' ./src/include/bindings/bindings.rs
RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK) RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK)
ifeq ($(ARCH), x86_64) ifeq ($(ARCH), x86_64)
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 clippy --all-features RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 clippy --all-features

16
oscomp/ci-boot-test.sh Normal file
View File

@ -0,0 +1,16 @@
#!/bin/bash
# 启动qemu并在后台运行将输出重定向到文件描述符3
exec 3< <(bash ./ci-start-${ARCH}.sh 2>&1)
# 读取qemu的输出直到检测到错误字段
while read -u 3 -r line; do
# 打印输出到控制台
echo "$line"
# 检查输出中是否包含指定的错误字段
if [[ "$line" == *"Hello, World!"* ]]; then
echo "启动成功!"
kill $(ps aux | grep "qemu-system-${ARCH}" | grep -v grep | awk "{print \$2}")
exit 0
fi
done

29
oscomp/ci-testcase.sh Normal file
View File

@ -0,0 +1,29 @@
REGET=${REGET:-0}
RV_TEST="../bin/riscv64/sdcard-rv.img"
RV_TEST_URL="https://github.com/Samuka007/testsuits-for-oskernel/releases/download/pre-2025-03-21/sdcard-rv.img.gz"
RV_TEST_DIR="../bin/riscv64"
if [ ! -f "$RV_TEST" ] || [ "$REGET" -eq 1 ]; then
echo "Downloading..."
mkdir -p "$RV_TEST_DIR"
wget -O "$RV_TEST_DIR/sdcard-rv.img.gz" "$RV_TEST_URL"
gunzip "$RV_TEST_DIR/sdcard-rv.img.gz"
echo "Download and extraction complete."
else
echo "$RV_TEST already exists."
fi
LA_TEST="../bin/loongarch64/sdcard-la.img"
LA_TEST_URL="https://github.com/Samuka007/testsuits-for-oskernel/releases/download/pre-2025-03-21/sdcard-la.img.gz"
LA_TEST_DIR="../bin/loongarch64"
if [ ! -f "$LA_TEST" ] || [ "$REGET" -eq 1 ]; then
echo "$LA_TEST does not exist. Downloading..."
mkdir -p "$LA_TEST_DIR"
wget -O "$LA_TEST_DIR/sdcard-la.img.gz" "$LA_TEST_URL"
gunzip "$LA_TEST_DIR/sdcard-la.img.gz"
echo "Download and extraction complete."
else
echo "$LA_TEST already exists."
fi