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
This commit is contained in:
Samuel Dai 2025-03-18 15:20:54 +08:00 committed by GitHub
parent fbb0d1f4a5
commit 153b7a6cb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 537 additions and 151 deletions

View File

@ -3,6 +3,14 @@ From docker.educg.net/cg/os-contest:20250226
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
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", "--"] ENTRYPOINT ["tini", "--"]

View File

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

View File

@ -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
.vscode/launch.json vendored Normal file
View File

@ -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
.vscode/tasks.json vendored Normal file
View File

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

153
Makefile
View File

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

View File

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

View File

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

View File

@ -62,7 +62,7 @@ make build && make qemu-nographic
在DragonOS项目目录下运行以下命令 在DragonOS项目目录下运行以下命令
```shell ```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内核进行性能分析并生成一个火焰图。 上面的命令将会对DragonOS内核进行性能分析并生成一个火焰图。

View File

@ -56,13 +56,19 @@ ECHO:
@echo "$@" @echo "$@"
$(kernel_subdirs): ECHO $(kernel_subdirs): ECHO
$(MAKE) -C $@ clean
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" kernel_root_path="$(shell pwd)" $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" kernel_root_path="$(shell pwd)"
kernel: $(kernel_subdirs) kernel_rust 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: __link_riscv64_kernel:
@echo "Linking 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 # 生成kallsyms
current_dir=$(pwd) current_dir=$(pwd)
@ -77,20 +83,21 @@ __link_riscv64_kernel:
@echo $(shell find . -name "*.o") @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 $(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..." @echo "Generating kernel ELF file..."
@mkdir -p $(KERNEL_PATH)
ifeq ($(UNWIND_ENABLE), yes) 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 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 endif
@rm kernel @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: __link_x86_64_kernel:
@echo "Linking 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 # 生成kallsyms
current_dir=$(pwd) current_dir=$(pwd)
@ -105,18 +112,24 @@ __link_x86_64_kernel:
@echo $(shell find . -name "*.o") @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 $(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..." @echo "Generating kernel ELF file..."
@mkdir -p $(KERNEL_PATH)
# 生成内核文件 # 生成内核文件
ifeq ($(UNWIND_ENABLE), yes) 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 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 endif
rm kernel rm kernel
__dragon_stub: __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..." @echo "Linking dragon_stub..."
@mkdir -p $(ROOT_PATH)/bin/sysroot @mkdir -p $(SYSROOT_PATH)
PAYLOAD_ELF=$(PAYLOAD_ELF) TARGET_SYSROOT=$(ROOT_PATH)/bin/sysroot $(MAKE) -C $(ROOT_PATH)/kernel/submodules/DragonStub install -j $(NPROCS) PAYLOAD_ELF=$(PAYLOAD_ELF) TARGET_SYSROOT=$(SYSROOT_PATH) $(MAKE) -C $(ROOT_PATH)/kernel/submodules/DragonStub install -j $(NPROCS)
clean: clean:

View File

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

View File

@ -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
oscomp/ci-start-x86_64.sh Normal file
View File

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

View File

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

View File

@ -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交叉编译工具链在当前窗口生效"

View File

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

View File

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

View File

@ -1,7 +1,7 @@
# From tools/run-qemu.sh, mainly remove the sudo for container environment # From tools/run-qemu.sh, mainly remove the sudo for container environment
# #
# REFERENCE: # 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 \ # -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 \ # -rtc base=utc \
# -drive file=disk.img,if=none,format=raw,id=x1 -device virtio-blk-device,drive=x1,bus=virtio-mmio-bus.1 # -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" RISCV64_UBOOT_PATH="../tools/arch/riscv64/u-boot-${UBOOT_VERSION}-riscv64"
DISK_NAME="disk-image-${ARCH}.img"
QEMU=qemu-system-${ARCH} QEMU=qemu-system-${ARCH}
QEMU_DISK_IMAGE="../bin/${DISK_NAME}" QEMU_DISK_IMAGE="../bin/${ARCH}/disk.img"
QEMU_MEMORY="512M" QEMU_MEMORY="512M"
QEMU_MEMORY_BACKEND="dragonos-qemu-shm.ram" QEMU_MEMORY_BACKEND="dragonos-qemu-shm.ram"
QEMU_MEMORY_BACKEND_PATH_PREFIX="/dev/shm" 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_SERIAL=" -serial chardev:mux -monitor chardev:mux -chardev stdio,id=mux,mux=on,signal=off,logfile=${QEMU_SERIAL_LOG_FILE} "
QEMU_MONITOR="" QEMU_MONITOR=""
QEMU_ARGUMENT+=" --nographic " QEMU_ARGUMENT+=" --nographic "
QEMU_ARGUMENT+=" -kernel ../bin/kernel/kernel.elf " QEMU_ARGUMENT+=" -kernel ../bin/${ARCH}/kernel/kernel.elf "
;; ;;
esac;shift 2;; esac;shift 2;;
@ -216,7 +214,7 @@ if [ ${BIOS_TYPE} == uefi ] ;then
else else
# 如果是i386架构或者x86_64架构就直接启动 # 如果是i386架构或者x86_64架构就直接启动
if [ ${ARCH} == x86_64 ] || [ ${ARCH} == i386 ] ;then if [ ${ARCH} == x86_64 ] || [ ${ARCH} == i386 ] ;then
${QEMU} ${QEMU_ARGUMENT} echo "${QEMU} ${QEMU_ARGUMENT}"
elif [ ${ARCH} == riscv64 ] ;then elif [ ${ARCH} == riscv64 ] ;then
# 如果是riscv64架构就与efi启动一样 # 如果是riscv64架构就与efi启动一样
install_riscv_uboot install_riscv_uboot

160
oscomp/write_disk_image.sh Normal file
View File

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

View File

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

View File

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

View File

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

View File

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