Browse Source

feat(CI): Build both platform image without edit configs (#3)

* feat(ci): additional dadk manifest for CI, add container capable rv64 run arg and gendisk cmd

* feat(build): kernel compiling(linking) from diff-arch nolonger needs to make clean

* breaking: use ci-command to run targets, enable both arch to build together

* fix: specify toolchains and the dadk menifest for user program, and add nessesary toolchain. Now riscv64 ver of DragonOS can run into user mode.

* fix(env): cleanup dirty configs, add make clean back

* fix(build): update permission with whoami, and nolonger compile grub in rv64 building.

* feat(ide): support for vscode debuging, using lldb plugin

* feat(ci): automate u-boot download and installation for riscv64
Samuel Dai 1 week ago
parent
commit
153b7a6cb8

+ 9 - 1
.devcontainer/Dockerfile

@@ -3,6 +3,14 @@ From docker.educg.net/cg/os-contest:20250226
 RUN apt install -y --no-install-recommends \
     bison flex libssl-dev bridge-utils dnsmasq sudo iptables
 
-RUN cargo install --git https://github.com/Samuka007/DADK.git --branch kpartx-docker-support
+RUN rustup install nightly-2024-11-05
+RUN rustup default nightly-2024-11-05
+RUN rustup target add riscv64gc-unknown-none-elf --toolchain nightly-2024-11-05
+RUN rustup component add rust-src --toolchain nightly-2024-11-05
+RUN rustup component add clippy --toolchain nightly-2024-11-05
+RUN rustup component add rustfmt --toolchain nightly-2024-11-05
+RUN cargo +nightly-2024-11-05 install cargo-binutils
+
+RUN cargo install --git https://github.com/Samuka007/DADK.git --branch 007/breaking-output-path
 
 ENTRYPOINT ["tini", "--"]

+ 2 - 1
.devcontainer/devcontainer.json

@@ -12,7 +12,8 @@
             "extensions": [
                 "rust-lang.rust-analyzer",
                 "ms-vscode.cpptools",
-                "tamasfe.even-better-toml"
+                "tamasfe.even-better-toml",
+                "vadimcn.vscode-lldb"
             ]
         }
     }

+ 0 - 23
.vscode/c_cpp_properties.json

@@ -1,23 +0,0 @@
-{
-    "configurations": [
-        {
-            "name": "DragonOS",
-            "includePath": [
-                "${workspaceFolder}/**",
-                "${workspaceFolder}/bin/sysroot/usr/include",
-                "${workspaceFolder}/user/libs/libc/src/include",
-                "${workspaceFolder}/user/libs/libc/src/include/export"
-            ],
-            "defines": [
-                "__x86_64__",
-                "DEBUG"
-            ],
-            "compilerPath": "~/opt/dragonos-gcc/gcc-x86_64-unknown-none/bin/x86_64-elf-gcc",
-            "cStandard": "gnu17",
-            "cppStandard": "gnu++14",
-            "intelliSenseMode": "linux-gcc-x64",
-            "configurationProvider": "ms-vscode.makefile-tools"
-        }
-    ],
-    "version": 4
-}

+ 22 - 0
.vscode/launch.json

@@ -0,0 +1,22 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "type": "lldb",
+            "request": "launch",
+            "name": "Debug RISCV64 elf",
+            "stopOnEntry": false,
+            "preLaunchTask": "DragonOS: Start riscv64",
+            "targetCreateCommands": ["target create ${workspaceFolder}/bin/riscv64/kernel/kernel.elf"],
+            "processCreateCommands": [
+                "gdb-remote localhost:1234",
+                "continue" // Get over the first trap into the kernel
+            ],
+            "args": [],
+            "cwd": "${workspaceFolder}",
+        }
+    ]
+}

+ 32 - 0
.vscode/tasks.json

@@ -0,0 +1,32 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "type": "shell",
+            "label": "DragonOS: Build riscv64",
+            "command": "make",
+            "group": { "kind": "build", "isDefault": true },
+            "args": [
+                "ci-build",
+                "ARCH=riscv64"
+            ],
+            "options": {
+                "cwd": "${workspaceFolder}"
+            }
+        },
+        {
+            "type": "process",
+            "label": "DragonOS: Start riscv64",
+            "command": "bash",
+            "args": [
+                "ci-start-riscv64.sh"
+            ],
+            "options": {
+                "cwd": "${workspaceFolder}/oscomp"
+            },
+            "isBackground": true
+        }
+    ]
+}

+ 55 - 98
Makefile

@@ -38,19 +38,47 @@ endif
 check_arch:
 	@bash tools/check_arch.sh
 
+# ===> Following are oscomp specific
 .PHONY: all 
-all: kernel user
+all:
+	#@make ARCH=x86_64 ci-build
+	@make ARCH=riscv64 ci-build
 
+ci-update-submodules:
+	@echo "更新子模块"
+	@sudo chown -R $(shell whoami) .
+	@git submodule update --recursive --init
+
+ci-build: ci-kernel ci-user ci-gendisk
+
+ci-run: ci-build ci-start
+
+ci-kernel: ci-update-submodules
+	@echo "Compile $(ARCH) Kernel..."
+	@$(MAKE) -C ./kernel all ARCH=$(ARCH) || (echo "Kernel compilation failed" && exit 1)
+
+ci-user:
+	@echo "Compile $(ARCH) User..."
+	@$(MAKE) -C ./user all ARCH=$(ARCH) FORCE_UNSAFE_CONFIGURE=1 || (echo "User compilation failed" && exit 1)
 
-.PHONY: kernel
-kernel: check_arch update-submodules
-	mkdir -p bin/kernel/
-	
-	$(MAKE) -C ./kernel all ARCH=$(ARCH) || (sh -c "echo 内核编译失败" && exit 1)
-	
-.PHONY: user
-user: check_arch
-	$(MAKE) -C ./user all ARCH=$(ARCH) || (sh -c "echo 用户程序编译失败" && exit 1)
+ci-gendisk:
+	@echo "Generate disk image"
+ifeq ($(ARCH),x86_64)
+	@bash -c "cd tools && bash grub_auto_install.sh"
+endif
+	@bash -c "cd oscomp && sudo DADK=$(DADK) ARCH=$(ARCH) bash write_disk_image.sh --bios=legacy"
+
+ci-start:
+	@echo "Booting $(ARCH)"
+	@cd oscomp && bash ci-start-$(ARCH).sh
+
+.PHONY: kernel user write_diskimage write_diskimage-uefi qemu qemu-nographic qemu-uefi qemu-vnc qemu-uefi-vnc
+kernel user write_diskimage write_diskimage-uefi qemu qemu-nographic qemu-uefi qemu-vnc qemu-uefi-vnc:
+	@echo "The target \"$@\" is deprecated in this branch. Please use ci-* target instead."
+	@echo "To see the available targets, run \"make help\"."
+	@false
+
+# <===
 
 .PHONY: clean
 clean:
@@ -78,74 +106,6 @@ else
 	gdb-multiarch -n -x tools/.gdbinit
 endif
 
-# 写入磁盘镜像
-write_diskimage: check_arch
-	@echo "write_diskimage arch=$(ARCH)"
-	bash -c "export ARCH=$(ARCH); cd tools && bash grub_auto_install.sh && sudo DADK=$(DADK) ARCH=$(ARCH) bash $(ROOT_PATH)/tools/write_disk_image.sh --bios=legacy && cd .."
-
-# 写入磁盘镜像(uefi)
-write_diskimage-uefi: check_arch
-	bash -c "export ARCH=$(ARCH); cd tools && bash grub_auto_install.sh && sudo DADK=$(DADK) ARCH=$(ARCH) bash $(ROOT_PATH)/tools/write_disk_image.sh --bios=uefi && cd .."
-# 不编译,直接启动QEMU
-qemu: check_arch
-	sh -c "cd oscomp && bash run-qemu.sh --bios=legacy --display=window && cd .."
-
-# 不编译,直接启动QEMU,不显示图像
-qemu-nographic: check_arch
-	sh -c "cd oscomp && bash run-qemu.sh --bios=legacy --display=nographic && cd .."
-
-# 不编译,直接启动QEMU(UEFI)
-qemu-uefi: check_arch
-	sh -c "cd oscomp && bash run-qemu.sh --bios=uefi --display=window && cd .."
-# 不编译,直接启动QEMU,使用VNC Display作为图像输出
-qemu-vnc: check_arch
-	sh -c "cd oscomp && bash run-qemu.sh --bios=legacy --display=vnc && cd .."
-# 不编译,直接启动QEMU(UEFI),使用VNC Display作为图像输出
-qemu-uefi-vnc: check_arch
-	sh -c "cd oscomp && bash run-qemu.sh --bios=uefi --display=vnc && cd .."
-	
-# 编译并写入磁盘镜像
-build: check_arch
-	$(MAKE) all -j $(NPROCS)
-	$(MAKE) write_diskimage || exit 1
-
-# 在docker中编译,并写入磁盘镜像
-docker: check_arch
-	@echo "使用docker构建"
-	sudo bash tools/build_in_docker.sh || exit 1
-	$(MAKE) write_diskimage || exit 1
-	
-# uefi方式启动
-run-uefi: check_arch
-	$(MAKE) all -j $(NPROCS)
-	$(MAKE) write_diskimage-uefi || exit 1
-	$(MAKE) qemu-uefi
-	
-# 编译并启动QEMU
-run: check_arch
-	$(MAKE) all -j $(NPROCS)
-	$(MAKE) write_diskimage || exit 1
-	$(MAKE) qemu
-
-# uefi方式启动,使用VNC Display作为图像输出
-run-uefi-vnc: check_arch
-	$(MAKE) all -j $(NPROCS)
-	$(MAKE) write_diskimage-uefi || exit 1
-	$(MAKE) qemu-uefi-vnc
-	
-# 编译并启动QEMU,使用VNC Display作为图像输出
-run-vnc: check_arch
-	$(MAKE) all -j $(NPROCS)
-	$(MAKE) write_diskimage || exit 1
-	$(MAKE) qemu-vnc
-
-# 在docker中编译,并启动QEMU
-run-docker: check_arch
-	@echo "使用docker构建并运行"
-	sudo bash tools/build_in_docker.sh || exit 1
-	$(MAKE) write_diskimage || exit 1
-	$(MAKE) qemu
-
 fmt: check_arch
 	@echo "格式化代码" 
 	FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C kernel
@@ -159,9 +119,7 @@ log-monitor:
 .PHONY: update-submodules
 update-submodules:
 	@echo "更新子模块"
-	@sudo chown -R $(USER):$(USER) .
 	@git submodule update --recursive --init
-	# @git submodule foreach git pull origin master
 
 .PHONY: update-submodules-by-mirror
 update-submodules-by-mirror:
@@ -171,29 +129,28 @@ update-submodules-by-mirror:
 	@git config --global --unset url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf
 
 help:
-	@echo "编译:"
-	@echo "  make all -j <n>       - 本地编译,不运行,n为要用于编译的CPU核心数"
-	@echo "  make build            - 本地编译,并写入磁盘镜像"
-	@echo "  make docker           - Docker编译,并写入磁盘镜像"
-	@echo ""
-	@echo "编译并运行:"
-	@echo "  make run-docker       - Docker编译,写入磁盘镜像,并在QEMU中运行"
-	@echo "  make run              - 本地编译,写入磁盘镜像,并在QEMU中运行"
-	@echo "  make run-uefi         - 以uefi方式启动运行"
+	@echo "用法:"
+	@echo "  make <target> ARCH=<arch>"
 	@echo ""
-	@echo "运行:"
-	@echo "  make qemu             - 不编译,直接从已有的磁盘镜像启动运行"	
-	@echo "  make qemu-uefi        - 不编译,直接从已有的磁盘镜像以UEFI启动运行"	
+	@echo "Example:"
+	@echo "  make ci-run ARCH=riscv64"
 	@echo ""
+	@echo "When <arch> is not specified, the default value in env.mk will be used."
 	@echo ""
-	@echo "注: 对于上述的run, run-uefi, qemu, qemu-uefi命令可以在命令后加上-vnc后缀,来通过vnc连接到DragonOS, 默认会在5900端口运行vnc服务器。如:make run-vnc "
+	@echo "Targets:"
+	@echo "  make ci-run            - 本地编译,写入磁盘镜像,并在QEMU中运行"
+	@echo "  make ci-kernel         - 编译内核"
+	@echo "  make ci-gendisk        - 写入磁盘镜像"
+	@echo "  make ci-build          - 编译并写入磁盘镜像"
+	@echo "  make ci-start          - 不编译,直接启动运行"
 	@echo ""
 	@echo "其他:"
-	@echo "  make clean            - 清理编译产生的文件"
-	@echo "  make fmt              - 格式化代码"
-	@echo "  make log-monitor      - 启动日志监控"
-	@echo "  make docs             - 生成文档"
-	@echo "  make clean-docs       - 清理文档"
+	@echo "  make all               - 用于 CI 编译"
+	@echo "  make clean             - 清理编译产生的文件"
+	@echo "  make fmt               - 格式化代码"
+	@echo "  make log-monitor       - 启动日志监控"
+	@echo "  make docs              - 生成文档"
+	@echo "  make clean-docs        - 清理文档"
 	@echo ""
 	@echo "  make update-submodules - 更新子模块"
 	@echo "  make update-submodules-by-mirror - 从镜像更新子模块"

+ 3 - 1
README.md

@@ -19,9 +19,11 @@
 
 打开 VS Code ,安装 devcontainer 插件并进入 devcontainer 环境
 ```sh
-make kernel && make write_diskimage && make qemu
+make ci-run # or specify "ARCH=x86_64" to run x86 target
 ```
 
+更多选项请运行 `make help`
+
 > [!TIP]
 > 如果没有看到提示进入 devcontainer 环境,可以 `ctrl+shift+p` 找到 `Dev Containers: Reopen in Container`。
 > 第一次构建可能时间会有些久,尤其是拉取 CI 镜像时,请耐心一些~

+ 2 - 2
dadk-manifest.toml

@@ -14,10 +14,10 @@ rootfs-config = "config/rootfs.toml"
 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/sysroot"
+sysroot-dir = "bin/riscv64/sysroot"
 
 # DADK Root Cache directory path
-cache-root-dir = "bin/dadk_cache"
+cache-root-dir = "bin/riscv64/dadk_cache"
 
 # User configuration directory path
 # 这个字段只是临时用于兼容旧版本,v0.2版本重构完成后会删除

+ 1 - 1
docs/kernel/debug/profiling-kernel-with-dadk.md

@@ -62,7 +62,7 @@ make build && make qemu-nographic
 在DragonOS项目目录下,运行以下命令:
 
 ```shell
-dadk profile sample --format flamegraph  --output flame.svg --interval 200ms --duration 20s  --cpu-mask 0x1
+dadk profile sample --format flamegraph  --output flame.svg --interval 200ms --duration 20s  --cpu-mask 0x1 --kernel bin/x86_64/kernel/kernel.elf
 ```
 
 上面的命令,将会对DragonOS内核进行性能分析,并生成一个火焰图。

+ 22 - 9
kernel/src/Makefile

@@ -56,13 +56,19 @@ ECHO:
 	@echo "$@"
 
 $(kernel_subdirs): ECHO
+	$(MAKE) -C $@ clean
 	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)"  kernel_root_path="$(shell pwd)"
 
 kernel: $(kernel_subdirs) kernel_rust
 
+BINARY_PATH = $(ROOT_PATH)/bin/$(ARCH)
+SYSROOT_PATH = $(BINARY_PATH)/sysroot
+KERNEL_PATH = $(BINARY_PATH)/kernel
+MNT_PATH = $(BINARY_PATH)/mnt
+
 __link_riscv64_kernel:
 	@echo "Linking kernel..."
-	$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
+	$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(filter-out ./debug/kallsyms.o, $(shell find . -name "*.o")) ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
 	# 生成kallsyms
 	current_dir=$(pwd)
 
@@ -77,20 +83,21 @@ __link_riscv64_kernel:
 	@echo $(shell find . -name "*.o")
 	$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a ./debug/kallsyms.o  -T arch/riscv64/link.ld --no-relax
 	@echo "Generating kernel ELF file..."
+	@mkdir -p $(KERNEL_PATH)
 
 ifeq ($(UNWIND_ENABLE), yes)
-	$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv kernel ../../bin/kernel/kernel.elf
+	$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv kernel $(KERNEL_PATH)/kernel.elf
 else
-	$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
+	$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel $(KERNEL_PATH)/kernel.elf
 endif
 	@rm kernel
-	$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"
+	$(MAKE) __dragon_stub PAYLOAD_ELF="$(KERNEL_PATH)/kernel.elf"
 
 
 
 __link_x86_64_kernel:
 	@echo "Linking kernel..."
-	$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T arch/x86_64/link.lds --no-relax
+	$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(filter-out ./debug/kallsyms.o, $(shell find . -name "*.o")) ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T arch/x86_64/link.lds --no-relax
 # 生成kallsyms
 	current_dir=$(pwd)
 	
@@ -105,18 +112,24 @@ __link_x86_64_kernel:
 	@echo $(shell find . -name "*.o")
 	$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o  -T arch/x86_64/link.lds --no-relax
 	@echo "Generating kernel ELF file..."
+	@mkdir -p $(KERNEL_PATH)
 # 生成内核文件
 ifeq ($(UNWIND_ENABLE), yes)
-	$(OBJCOPY) -I elf64-x86-64 -O elf64-x86-64 kernel ../../bin/kernel/kernel.elf
+	$(OBJCOPY) -I elf64-x86-64 -O elf64-x86-64 kernel $(KERNEL_PATH)/kernel.elf
 else
-	$(OBJCOPY) -I elf64-x86-64 -O elf64-x86-64 -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
+	$(OBJCOPY) -I elf64-x86-64 -O elf64-x86-64 -R ".eh_frame" kernel $(KERNEL_PATH)/kernel.elf
 endif
 	rm kernel
 
 __dragon_stub:
+	# check if DragonStub submodule is initialized
+	@if [ ! -d "$(ROOT_PATH)/kernel/submodules/DragonStub/.git" ]; then \
+		echo "Initializing DragonStub submodule..."; \
+		git submodule update --init --recursive; \
+	fi
 	@echo "Linking dragon_stub..."
-	@mkdir -p $(ROOT_PATH)/bin/sysroot
-	PAYLOAD_ELF=$(PAYLOAD_ELF) TARGET_SYSROOT=$(ROOT_PATH)/bin/sysroot $(MAKE) -C $(ROOT_PATH)/kernel/submodules/DragonStub install -j $(NPROCS)
+	@mkdir -p $(SYSROOT_PATH)
+	PAYLOAD_ELF=$(PAYLOAD_ELF) TARGET_SYSROOT=$(SYSROOT_PATH) $(MAKE) -C $(ROOT_PATH)/kernel/submodules/DragonStub install -j $(NPROCS)
 
 	
 clean: 

+ 3 - 2
kernel/src/debug/Makefile

@@ -15,7 +15,7 @@ traceback.o: traceback/traceback.c
 
 # 生成内核栈符号表的汇编文件
 generate_kallsyms: kallsyms.o 
-	echo "Generating kallsyms..."
+	@echo "Generating kallsyms..."
 # 请注意,这个不能使用raw的nm来处理
 	nm -n -C $(kernel_root_path)/kernel | ./kallsyms > kallsyms.S
 	$(CC) -c kallsyms.S -o kallsyms.o
@@ -23,4 +23,5 @@ generate_kallsyms: kallsyms.o
 
 
 clean:
-	rm -rf kallsyms
+	rm -rf kallsyms kallsyms.o kallsyms.S
+	rm -rf traceback/traceback.o

+ 28 - 0
oscomp/ci-start-riscv64.sh

@@ -0,0 +1,28 @@
+# uboot版本
+UBOOT_VERSION="v2023.10"
+RISCV64_UBOOT_PATH="../tools/arch/riscv64/u-boot-${UBOOT_VERSION}-riscv64"
+
+if [ ! -d ${RISCV64_UBOOT_PATH} ]; then
+    echo "正在下载u-boot..."
+    uboot_tar_name="u-boot-${UBOOT_VERSION}-riscv64.tar.xz"
+    
+    uboot_parent_path=$(dirname ${RISCV64_UBOOT_PATH}) || (echo "获取riscv u-boot 版本 ${UBOOT_VERSION} 的父目录失败" && exit 1)
+
+    if [ ! -f ${uboot_tar_name} ]; then
+        wget https://mirrors.dragonos.org.cn/pub/third_party/u-boot/${uboot_tar_name} || (echo "下载riscv u-boot 版本 ${UBOOT_VERSION} 失败" && exit 1)
+    fi
+    echo "下载完成"
+    echo "正在解压u-boot到 '$uboot_parent_path'..."
+    mkdir -p $uboot_parent_path
+    tar xvf u-boot-${UBOOT_VERSION}-riscv64.tar.xz -C ${uboot_parent_path} || (echo "解压riscv u-boot 版本 ${UBOOT_VERSION} 失败" && exit 1)
+    echo "解压完成"
+    rm -rf u-boot-${UBOOT_VERSION}-riscv64.tar.xz
+fi
+echo "riscv u-boot 版本 ${UBOOT_VERSION} 已经安装"
+
+qemu-system-riscv64 -machine virt -kernel ../tools/arch/riscv64/u-boot-v2023.10-riscv64/u-boot.bin \
+                    -m 512M -nographic -smp 2,cores=2,threads=1,sockets=1 -bios default \
+                    -no-reboot -device virtio-net-device,netdev=net -netdev user,id=net \
+                    -rtc base=utc \
+                    -drive file=../bin/riscv64/disk.img,if=none,format=raw,id=x1 \
+                    -device virtio-blk-device,drive=x1,bus=virtio-mmio-bus.1 -s

+ 30 - 0
oscomp/ci-start-x86_64.sh

@@ -0,0 +1,30 @@
+BINARY_PATH="../bin/x86_64"
+MEMORY="512M"
+MEMORY_BACKEND="dragonos-qemu-shm.ram"
+MEMORY_PREFIX="/dev/shm"
+LOG_FILE="../serial_opt.txt"
+SHM_OBJECT_PARAM="memory-backend-file,size=${MEMORY},id=${MEMORY_BACKEND},mem-path=${MEMORY_PREFIX}/${MEMORY_BACKEND},share=on "
+DISK_IMAGE="${BINARY_PATH}/disk.img"
+DRIVE="id=disk,file=${DISK_IMAGE},if=none"
+
+qemu-system-x86_64  --nographic \
+                    -kernel ${BINARY_PATH}/kernel/kernel.elf \
+                    -d ${DISK_IMAGE} \
+                    -m 512M \
+                    -smp 2,cores=2,threads=1,sockets=1 \
+                    -boot order=d \
+                    -d cpu_reset,guest_errors,trace:virtio*,trace:e1000e_rx*,trace:e1000e_tx*,trace:e1000e_irq* \
+                    -s -machine q35 \
+                    -cpu IvyBridge,apic,x2apic,+fpu,check,+vmx, \
+                    -rtc clock=host,base=localtime \
+                    -serial chardev:mux \
+                    -monitor chardev:mux \
+                    -chardev stdio,id=mux,mux=on,signal=off,logfile=${LOG_FILE} \
+                    -drive ${DRIVE} \
+                    -device ahci,id=ahci \
+                    -device ide-hd,drive=disk,bus=ahci.0 \
+                    -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 \
+                    -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 \
+                    -usb -device qemu-xhci,id=xhci,p2=8,p3=4 \
+                    -machine accel=kvm \
+                    -enable-kvm

+ 6 - 0
oscomp/install-dep-x86_64.sh

@@ -0,0 +1,6 @@
+# Script to install dependencies for building the x86_64 version of the user packages in DragonOS
+
+apt install unzip
+bash install_musl_gcc.sh
+rustup install nightly-2024-11-05-x86_64-unknown-linux-gnu
+rustup target add x86_64-unknown-linux-musl --toolchain nightly-2024-11-05-x86_64-unknown-linux-gnu

+ 98 - 0
oscomp/install_musl_gcc.sh

@@ -0,0 +1,98 @@
+#########################################################################
+# 这个脚本用于安装musl交叉编译工具链
+# 该脚本会自动下载musl交叉编译工具链,并将其添加到PATH中
+#########################################################################
+
+export USE_GITHUB=${USE_GITHUB:=0}
+
+
+
+MUSL_GCC_DATE="231114"
+MUSL_GCC_VERSION="9.4.0"
+MUSL_GCC_X86_64_TAR=
+MUSL_GCC_RISCV64_TAR=
+
+MUSL_GCC_X86_64_DOWNLOAD_URL=""
+MUSL_GCC_RISCV64_DOWNLOAD_URL=""
+if [ $USE_GITHUB -eq 1 ]; then
+    echo "Download from github"
+
+    MUSL_GCC_X86_64_TAR=x86_64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}.tar.xz
+    MUSL_GCC_RISCV64_TAR=riscv64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}.tar.xz
+    MUSL_GCC_X86_64_DOWNLOAD_URL="https://github.com/DragonOS-Community/musl-cross-make/releases/download/${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}/${MUSL_GCC_X86_64_TAR}"
+    MUSL_GCC_RISCV64_DOWNLOAD_URL="https://github.com/DragonOS-Community/musl-cross-make/releases/download/${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}/${MUSL_GCC_RISCV64_TAR}"
+    https://github.com/DragonOS-Community/musl-cross-make/releases/download/9.4.0-231114/riscv64-linux-musl-cross-gcc-9.4.0.tar.xz
+else
+    echo "Download from mirrors.dragonos.org.cn"
+    MUSL_GCC_X86_64_TAR="x86_64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}.tar.xz"
+    MUSL_GCC_RISCV64_TAR="riscv64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}.tar.xz"
+    MUSL_GCC_X86_64_DOWNLOAD_URL="https://mirrors.dragonos.org.cn/pub/third_party/toolchain/gcc/${MUSL_GCC_X86_64_TAR}"
+    MUSL_GCC_RISCV64_DOWNLOAD_URL="https://mirrors.dragonos.org.cn/pub/third_party/toolchain/gcc/${MUSL_GCC_RISCV64_TAR}"
+fi
+
+
+INSTALL_POS="/opt"
+
+mkdir -p $INSTALL_POS
+
+get_shell_rc_file()
+{
+    if [ -n "$ZSH_VERSION" ]; then
+        echo "$HOME/.zshrc"
+    elif [ -n "$BASH_VERSION" ]; then
+        echo "$HOME/.bashrc"
+    else
+        echo "$HOME/.profile"
+    fi
+}
+
+# 信号退出时清理下载的文件
+trap_handler(){
+    rm -f $MUSL_GCC_X86_64_TAR
+    rm -f $MUSL_GCC_RISCV64_TAR
+}
+
+trap trap_handler EXIT
+trap trap_handler SIGINT
+
+
+SHELL_RC=$(get_shell_rc_file)
+source $SHELL_RC
+
+# 下载musl交叉编译工具链
+
+# 如果x86_64-linux-musl-gcc或x86_64-linux-musl-g++不存在,则下载
+if [ ! -n "$(which x86_64-linux-musl-gcc)" ] || [ ! -n "$(which x86_64-linux-musl-g++)" ]; then
+    echo "开始下载x86_64-linux-musl-gcc"
+    wget ${MUSL_GCC_X86_64_DOWNLOAD_URL} || exit 1
+    echo "下载完成"
+    echo "开始解压x86_64-linux-musl-gcc"
+    tar xvf $MUSL_GCC_X86_64_TAR -C $INSTALL_POS || exit 1
+    echo "PATH=\$PATH:$INSTALL_POS/x86_64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}/bin" >> $SHELL_RC
+    echo "安装完成"
+    echo "开始清理x86_64-linux-musl-gcc的下载缓存"
+    rm -rf $MUSL_GCC_X86_64_TAR || exit 1
+    echo "清理完成"
+else
+    echo "x86_64-linux-musl-gcc已经安装"
+fi
+
+# 如果riscv64-linux-musl-gcc或riscv64-linux-musl-g++不存在,则下载
+if [ ! -n "$(which riscv64-linux-musl-gcc)" ] || [ ! -n "$(which riscv64-linux-musl-g++)" ]; then
+    echo "开始下载riscv64-linux-musl-gcc"
+    wget ${MUSL_GCC_RISCV64_DOWNLOAD_URL} || exit 1
+    echo "下载完成"
+    echo "开始解压riscv64-linux-musl-gcc"
+    tar xvf $MUSL_GCC_RISCV64_TAR -C $INSTALL_POS || exit 1
+    echo "export PATH=\"\$PATH:$INSTALL_POS/riscv64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}/bin\"" >> $SHELL_RC
+    echo "安装完成"
+    echo "开始清理riscv64-linux-musl-gcc的下载缓存"
+    rm -rf $MUSL_GCC_RISCV64_TAR || exit 1
+    echo "清理完成"
+else
+    echo "riscv64-linux-musl-gcc已经安装"
+fi
+
+source $SHELL_RC
+
+echo "musl交叉编译工具链安装完成,请运行 source $SHELL_RC 以使musl交叉编译工具链在当前窗口生效!"

+ 24 - 0
oscomp/manifest-riscv64.toml

@@ -0,0 +1,24 @@
+# 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"

+ 24 - 0
oscomp/manifest-x86_64.toml

@@ -0,0 +1,24 @@
+# DADK 总控文件
+
+[metadata]
+# Target architecture. Options: x86_64, riscv64
+arch = "x86_64"
+
+# 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/x86_64/sysroot"
+
+# DADK Root Cache directory path
+cache-root-dir = "bin/x86_64/dadk_cache"
+
+# User configuration directory path
+# 这个字段只是临时用于兼容旧版本,v0.2版本重构完成后会删除
+user-config-dir = "user/dadk/config"

+ 4 - 6
oscomp/run-qemu.sh

@@ -1,7 +1,7 @@
 # From tools/run-qemu.sh, mainly remove the sudo for container environment
 # 
 # REFERENCE:
-# qemu-system-riscv64 -machine virt -kernel ../bin/kernel/kernel -m {mem} -nographic -smp {smp} -bios default -drive file={fs},if=none,format=raw,id=x0 \
+# qemu-system-riscv64 -machine virt -kernel ../bin/${ARCH}/kernel/kernel.elf -m {mem} -nographic -smp {smp} -bios default -drive file={fs},if=none,format=raw,id=x0 \
 #                     -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 -no-reboot -device virtio-net-device,netdev=net -netdev user,id=net \
 #                     -rtc base=utc \
 #                     -drive file=disk.img,if=none,format=raw,id=x1 -device virtio-blk-device,drive=x1,bus=virtio-mmio-bus.1
@@ -73,10 +73,8 @@ UBOOT_VERSION="v2023.10"
 RISCV64_UBOOT_PATH="../tools/arch/riscv64/u-boot-${UBOOT_VERSION}-riscv64"
 
 
-DISK_NAME="disk-image-${ARCH}.img"
-
 QEMU=qemu-system-${ARCH}
-QEMU_DISK_IMAGE="../bin/${DISK_NAME}"
+QEMU_DISK_IMAGE="../bin/${ARCH}/disk.img"
 QEMU_MEMORY="512M"
 QEMU_MEMORY_BACKEND="dragonos-qemu-shm.ram"
 QEMU_MEMORY_BACKEND_PATH_PREFIX="/dev/shm"
@@ -149,7 +147,7 @@ while true;do
               QEMU_SERIAL=" -serial chardev:mux -monitor chardev:mux -chardev stdio,id=mux,mux=on,signal=off,logfile=${QEMU_SERIAL_LOG_FILE} "
               QEMU_MONITOR=""
               QEMU_ARGUMENT+=" --nographic "
-              QEMU_ARGUMENT+=" -kernel ../bin/kernel/kernel.elf "
+              QEMU_ARGUMENT+=" -kernel ../bin/${ARCH}/kernel/kernel.elf "
 
               ;;
         esac;shift 2;;
@@ -216,7 +214,7 @@ if [ ${BIOS_TYPE} == uefi ] ;then
 else
   # 如果是i386架构或者x86_64架构,就直接启动
   if [ ${ARCH} == x86_64 ] || [ ${ARCH} == i386 ] ;then
-    ${QEMU} ${QEMU_ARGUMENT}
+    echo "${QEMU} ${QEMU_ARGUMENT}"
   elif [ ${ARCH} == riscv64 ] ;then
     # 如果是riscv64架构,就与efi启动一样
     install_riscv_uboot

+ 160 - 0
oscomp/write_disk_image.sh

@@ -0,0 +1,160 @@
+###############################################
+# 该脚本用于将文件拷贝到磁盘镜像中,
+#       并在磁盘镜像中安装grub引导程序
+#
+# 用法:bash write_disk_image.sh --bios legacy/uefi
+# 如果之前创建的 ${ARCH}/disk.img 是MBR分区表,那么请这样运行它:bash write_disk_image.sh --bios legacy
+# 如果之前创建的 ${ARCH}/disk.img 是GPT分区表,那么请这样运行它:bash write_disk_image.sh --bios uefi
+# 通过设置ARCH为x86_64/i386/riscv64,进行64/32位uefi的install,但是请记住该处的ARCH应与run-qemu.sh中的一致
+###############################################
+
+echo "ARCH=${ARCH}"
+# 给ARCH变量赋默认值
+export ARCH=${ARCH:=x86_64}
+export DADK=${DADK:=dadk}
+
+
+# 内核映像
+root_folder=$(dirname $(pwd))
+kernel="${root_folder}/bin/${ARCH}/kernel/kernel.elf"
+sysroot_folder="${root_folder}/bin/${ARCH}/sysroot"
+mount_folder=$($DADK -f $root_folder/oscomp/manifest-$ARCH.toml -w $root_folder rootfs show-mountpoint || exit 1)
+boot_folder="${mount_folder}/boot"
+GRUB_INSTALL_PATH="${boot_folder}/grub"
+
+ARGS=`getopt -o p -l bios: -- "$@"`
+eval set -- "${ARGS}"
+#echo formatted parameters=[$@]
+echo "开始写入磁盘镜像..."
+
+if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
+
+INSTALL_GRUB_TO_IMAGE="1"
+
+else
+INSTALL_GRUB_TO_IMAGE="0"
+fi
+
+
+# toolchain
+GRUB_ABS_PREFIX=/opt/dragonos-grub
+GRUB_PATH_I386_LEGACY_INSTALL=${GRUB_ABS_PREFIX}/arch/i386/legacy/grub/sbin/grub-install
+GRUB_PATH_I386_EFI_INSTALL=${GRUB_ABS_PREFIX}/arch/i386/efi/grub/sbin/grub-install
+GRUB_PATH_X86_64_EFI_INSTALL=${GRUB_ABS_PREFIX}/arch/x86_64/efi/grub/sbin/grub-install
+GRUB_PATH_RISCV64_EFI_INSTALL=${GRUB_ABS_PREFIX}/arch/riscv64/efi/grub/sbin/grub-install
+
+GRUB_PATH_I386_LEGACY_FILE=${GRUB_ABS_PREFIX}/arch/i386/legacy/grub/bin/grub-file
+
+
+# ==============检查文件是否齐全================
+
+bins[0]=${kernel}
+
+for file in ${bins[*]};do
+if [ ! -x $file ]; then
+echo "$file 不存在!"
+exit 
+fi
+done
+
+# ===============文件检查完毕===================
+
+# 如果是 i386/x86_64,需要判断是否符合 multiboot2 标准
+if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
+    if ${GRUB_PATH_I386_LEGACY_FILE} --is-x86-multiboot2 ${kernel}; then
+        echo Multiboot2 Confirmed!
+    else
+        echo NOT Multiboot2!
+        exit
+    fi
+fi
+
+# 判断是否存在硬盘镜像文件,如果不存在,就创建一个
+echo "创建硬盘镜像文件..."
+$DADK -f $root_folder/oscomp/manifest-$ARCH.toml -w $root_folder rootfs create --skip-if-exists || exit 1
+
+$DADK -f $root_folder/oscomp/manifest-$ARCH.toml -w $root_folder rootfs mount || exit 1
+
+
+
+LOOP_DEVICE=$($DADK -f $root_folder/oscomp/manifest-$ARCH.toml -w $root_folder rootfs show-loop-device || exit 1)
+echo $LOOP_DEVICE
+echo ${mount_folder}
+# mkdir -p ${GRUB_INSTALL_PATH}
+
+# 检测grub文件夹是否存在
+if [ -d "${GRUB_INSTALL_PATH}" ] || [ "${INSTALL_GRUB_TO_IMAGE}" = "0" ]; then
+   echo "无需安装grub"
+   INSTALL_GRUB_TO_IMAGE="0"
+else
+    mkdir -p ${GRUB_INSTALL_PATH}
+fi
+
+
+if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
+    cp ${kernel} ${boot_folder}/
+fi
+
+# 拷贝用户程序到磁盘镜像
+mkdir -p ${mount_folder}/bin
+mkdir -p ${mount_folder}/dev
+mkdir -p ${mount_folder}/proc
+mkdir -p ${mount_folder}/usr
+cp -r ${sysroot_folder}/* ${mount_folder}/
+
+# 设置 grub 相关数据
+if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
+    
+    touch ${GRUB_INSTALL_PATH}/grub.cfg
+cfg_content='set timeout=15
+    set default=0
+    insmod efi_gop
+    menuentry "DragonOS" {
+    multiboot2 /boot/kernel.elf init=/bin/dragonreach
+}'
+# 增加insmod efi_gop防止32位uefi启动报错
+echo "echo '${cfg_content}' >  ${GRUB_INSTALL_PATH}/grub.cfg" | sh
+fi
+
+install_riscv64_efi(){
+    ${GRUB_PATH_RISCV64_EFI_INSTALL} --target=riscv64-efi --efi-directory=${mount_folder}  --boot-directory=${boot_folder}  --removable
+}
+
+if [ "${INSTALL_GRUB_TO_IMAGE}" = "1" ];then
+
+    case "$1" in
+        --bios) 
+            case "$2" in
+                    uefi) #uefi
+                    if [ ${ARCH} == "i386" ];then
+                        ${GRUB_PATH_I386_EFI_INSTALL} --target=i386-efi  --efi-directory=${mount_folder}  --boot-directory=${boot_folder}  --removable
+                    elif [ ${ARCH} == "x86_64" ];then
+                        ${GRUB_PATH_X86_64_EFI_INSTALL} --target=x86_64-efi --efi-directory=${mount_folder}  --boot-directory=${boot_folder}   --removable
+                    elif [ ${ARCH} == "riscv64" ];then
+                        install_riscv64_efi
+                    else
+                        echo "grub install: 不支持的架构"
+                    fi
+                ;;
+                    legacy) #传统bios
+                    if [ ${ARCH} == "x86_64" ];then
+                        ${GRUB_PATH_I386_LEGACY_INSTALL} --target=i386-pc --boot-directory=${boot_folder} $LOOP_DEVICE
+                    elif [ ${ARCH} == "riscv64" ];then
+                        install_riscv64_efi
+                    else
+                        echo "grub install: 不支持的架构"
+                    fi      
+                ;;
+            esac
+            ;;
+        *)
+        #传统bios
+        ${GRUB_PATH_I386_LEGACY_INSTALL} --target=i386-pc --boot-directory=${boot_folder} $LOOP_DEVICE
+        ;;
+
+    esac
+fi
+
+sync
+
+$DADK -f $root_folder/oscomp/manifest-$ARCH.toml -w $root_folder rootfs umount || exit 1

+ 7 - 3
user/Makefile

@@ -3,7 +3,9 @@ user_sub_dirs = apps
 DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
 # 最小的DADK版本
 MIN_DADK_VERSION = 0.2.0
-DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
+DADK_CACHE_DIR = $(ROOT_PATH)/bin/$(ARCH)/dadk_cache
+SYSROOT_DIR = $(ROOT_PATH)/bin/$(ARCH)/sysroot
+DADK_MANIFEST_PATH = $(ROOT_PATH)/oscomp/manifest-${ARCH}.toml
 
 ECHO:
 	@echo "$@"
@@ -33,6 +35,8 @@ ifneq ($(shell printf '%s\n%s' "$(DADK_VERSION)" "$(MIN_DADK_VERSION)" | sort -V
 endif
 endif
 
+DADK = $(shell which dadk) --manifest $(DADK_MANIFEST_PATH)
+
 .PHONY: dadk_run
 dadk_run: install_dadk
 	mkdir -p $(DADK_CACHE_DIR)
@@ -44,7 +48,7 @@ dadk_clean: install_dadk
 	@echo dadk_clean
 
 all:
-	mkdir -p $(ROOT_PATH)/bin/sysroot
+	mkdir -p $(SYSROOT_DIR)
 	
 	$(MAKE) dadk_run
 	$(MAKE) copy_sysconfig
@@ -53,7 +57,7 @@ all:
 
 .PHONY: copy_sysconfig
 copy_sysconfig:
-	cp -r sysconfig/* $(ROOT_PATH)/bin/sysroot/
+	cp -r sysconfig/* $(SYSROOT_DIR)
 
 
 .PHONY: clean

+ 1 - 0
user/apps/syscall_ebpf/Makefile

@@ -54,4 +54,5 @@ test-release:
 
 .PHONY: install
 install:
+	cargo install bpf-linker
 	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path ./syscall_ebpf --no-track --root $(INSTALL_DIR) --force

+ 2 - 2
user/apps/test-chown/Makefile

@@ -1,5 +1,5 @@
-TOOLCHAIN=
-RUSTFLAGS=
+TOOLCHAIN="+nightly-2024-11-05-x86_64-unknown-linux-gnu"
+RUSTFLAGS+=""
 
 ifdef DADK_CURRENT_BUILD_DIR
 # 如果是在dadk中编译,那么安装到dadk的安装目录中

+ 2 - 2
user/apps/test_lo/Makefile

@@ -1,5 +1,5 @@
-TOOLCHAIN=
-RUSTFLAGS=
+TOOLCHAIN="+nightly-2024-11-05-x86_64-unknown-linux-gnu"
+RUSTFLAGS+=""
 
 ifdef DADK_CURRENT_BUILD_DIR
 # 如果是在dadk中编译,那么安装到dadk的安装目录中