diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 9a0d57ff..8f910b91 100644 --- a/.devcontainer/Dockerfile +++ b/.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", "--"] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9e8e1156..1d108372 100755 --- a/.devcontainer/devcontainer.json +++ b/.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" ] } } diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index a95ad585..00000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..f0061980 --- /dev/null +++ b/.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}", + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..8175699e --- /dev/null +++ b/.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 + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile index e77e1c3b..5f108a7f 100644 --- a/Makefile +++ b/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 -.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-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) + +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为要用于编译的CPU核心数" - @echo " make build - 本地编译,并写入磁盘镜像" - @echo " make docker - Docker编译,并写入磁盘镜像" + @echo "用法:" + @echo " make ARCH=" @echo "" - @echo "编译并运行:" - @echo " make run-docker - Docker编译,写入磁盘镜像,并在QEMU中运行" - @echo " make run - 本地编译,写入磁盘镜像,并在QEMU中运行" - @echo " make run-uefi - 以uefi方式启动运行" + @echo "Example:" + @echo " make ci-run ARCH=riscv64" @echo "" - @echo "运行:" - @echo " make qemu - 不编译,直接从已有的磁盘镜像启动运行" - @echo " make qemu-uefi - 不编译,直接从已有的磁盘镜像以UEFI启动运行" + @echo "When is not specified, the default value in env.mk will be used." @echo "" - @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 - 从镜像更新子模块" diff --git a/README.md b/README.md index e58d31c8..b517e530 100644 --- a/README.md +++ b/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 镜像时,请耐心一些~ diff --git a/dadk-manifest.toml b/dadk-manifest.toml index fcfc561b..851a9fe6 100644 --- a/dadk-manifest.toml +++ b/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版本重构完成后会删除 diff --git a/docs/kernel/debug/profiling-kernel-with-dadk.md b/docs/kernel/debug/profiling-kernel-with-dadk.md index ba24b36f..11420ce5 100644 --- a/docs/kernel/debug/profiling-kernel-with-dadk.md +++ b/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内核进行性能分析,并生成一个火焰图。 diff --git a/kernel/src/Makefile b/kernel/src/Makefile index 4eb68211..c11aa163 100644 --- a/kernel/src/Makefile +++ b/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: diff --git a/kernel/src/debug/Makefile b/kernel/src/debug/Makefile index a145970d..107b7513 100644 --- a/kernel/src/debug/Makefile +++ b/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 \ No newline at end of file + rm -rf kallsyms kallsyms.o kallsyms.S + rm -rf traceback/traceback.o \ No newline at end of file diff --git a/oscomp/ci-start-riscv64.sh b/oscomp/ci-start-riscv64.sh new file mode 100644 index 00000000..f5aecc39 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/oscomp/ci-start-x86_64.sh b/oscomp/ci-start-x86_64.sh new file mode 100644 index 00000000..b1f9531c --- /dev/null +++ b/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 diff --git a/oscomp/install-dep-x86_64.sh b/oscomp/install-dep-x86_64.sh new file mode 100644 index 00000000..57c9f893 --- /dev/null +++ b/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 diff --git a/oscomp/install_musl_gcc.sh b/oscomp/install_musl_gcc.sh new file mode 100644 index 00000000..9fb9484d --- /dev/null +++ b/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交叉编译工具链在当前窗口生效!" diff --git a/oscomp/manifest-riscv64.toml b/oscomp/manifest-riscv64.toml new file mode 100644 index 00000000..851a9fe6 --- /dev/null +++ b/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" diff --git a/oscomp/manifest-x86_64.toml b/oscomp/manifest-x86_64.toml new file mode 100644 index 00000000..5a6ed1b4 --- /dev/null +++ b/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" diff --git a/oscomp/run-qemu.sh b/oscomp/run-qemu.sh index 68270605..504daffb 100644 --- a/oscomp/run-qemu.sh +++ b/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 diff --git a/oscomp/write_disk_image.sh b/oscomp/write_disk_image.sh new file mode 100644 index 00000000..61577c81 --- /dev/null +++ b/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 diff --git a/user/Makefile b/user/Makefile index c21d6179..69f0a079 100644 --- a/user/Makefile +++ b/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 diff --git a/user/apps/syscall_ebpf/Makefile b/user/apps/syscall_ebpf/Makefile index c8dadc36..8a905b8b 100644 --- a/user/apps/syscall_ebpf/Makefile +++ b/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 diff --git a/user/apps/test-chown/Makefile b/user/apps/test-chown/Makefile index 7522ea16..352c0562 100644 --- a/user/apps/test-chown/Makefile +++ b/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的安装目录中 diff --git a/user/apps/test_lo/Makefile b/user/apps/test_lo/Makefile index 7522ea16..352c0562 100644 --- a/user/apps/test_lo/Makefile +++ b/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的安装目录中