Browse Source

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
Samuel Dai 4 days ago
parent
commit
717bd9209a
9 changed files with 117 additions and 105 deletions
  1. 2 1
      .devcontainer/Dockerfile
  2. 34 77
      .github/workflows/makefile.yml
  3. 26 2
      .vscode/launch.json
  4. 1 0
      .vscode/tasks.json
  5. 8 1
      Makefile
  6. 0 24
      dadk-manifest.toml
  7. 1 0
      kernel/Makefile
  8. 16 0
      oscomp/ci-boot-test.sh
  9. 29 0
      oscomp/ci-testcase.sh

+ 2 - 1
.devcontainer/Dockerfile

@@ -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 \
     bison flex libssl-dev bridge-utils dnsmasq sudo iptables
 

+ 34 - 77
.github/workflows/makefile.yml

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

+ 26 - 2
.vscode/launch.json

@@ -7,18 +7,42 @@
         {
             "type": "lldb",
             "request": "launch",
-            "name": "Debug RISCV64 elf",
+            "name": "Debug RISCV64 lldb",
             "stopOnEntry": false,
-            "preLaunchTask": "DragonOS: Start riscv64",
             "targetCreateCommands": ["target create ${workspaceFolder}/bin/riscv64/kernel/kernel.elf"],
             "processCreateCommands": [
                 "gdb-remote localhost:1234",
+                "settings set target.process.follow-fork-mode child",
                 "continue" // Get over the first trap into the kernel
             ],
             "args": [],
             "cwd": "${workspaceFolder}",
             "sourceLanguages": ["c", "cpp", "rust"],
             "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 - 0
.vscode/tasks.json

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

+ 8 - 1
Makefile

@@ -44,6 +44,12 @@ all:
 	#@make ARCH=x86_64 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:
 	@echo "更新子模块"
 	@sudo chown -R $(shell whoami) .
@@ -82,6 +88,7 @@ kernel user write_diskimage write_diskimage-uefi qemu qemu-nographic qemu-uefi q
 
 .PHONY: clean
 clean:
+	@rm -rf bin
 	@list='$(SUBDIRS)'; for subdir in $$list; do \
 		echo "Clean in dir: $$subdir";\
 		cd $$subdir && $(MAKE) clean;\
@@ -106,7 +113,7 @@ else
 	gdb-multiarch -n -x tools/.gdbinit
 endif
 
-fmt: check_arch
+fmt:
 	@echo "格式化代码" 
 	FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C kernel
 	FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C user

+ 0 - 24
dadk-manifest.toml

@@ -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"

+ 1 - 0
kernel/Makefile

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

+ 16 - 0
oscomp/ci-boot-test.sh

@@ -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 - 0
oscomp/ci-testcase.sh

@@ -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