From 0482f02e1b6766ad2a427c606e20ed8c8f8fadeb Mon Sep 17 00:00:00 2001 From: LoGin Date: Wed, 11 Feb 2026 13:16:55 +0800 Subject: [PATCH] feat: enhance nix config and bootstrap (#1775) - Upgrade Docker image version from v1.21 to v1.22 across dev container and CI workflows - Add .nix-gc-root to .gitignore - Enhance nix configuration with Chinese mirrors, auto GC root, and system QEMU support - Update bootstrap script with improved nix installation and configuration options - Update DADK dependency to v0.6.1 Signed-off-by: longjin --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 2 +- .github/workflows/makefile.yml | 12 +- .github/workflows/nightly-build.yml | 2 +- .github/workflows/test-mm.yaml | 4 +- .github/workflows/test-x86.yml | 2 +- .gitignore | 1 + docs/introduction/develop_nix.md | 17 +- flake.nix | 76 ++++++++- tools/bootstrap.sh | 243 +++++++++++++++++++++++++--- tools/build_in_docker.sh | 2 +- tools/qemu/default.nix | 25 ++- 12 files changed, 349 insertions(+), 39 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 27a861c99..2e74f9659 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM dragonos/dragonos-dev:v1.21 +FROM dragonos/dragonos-dev:v1.22 # 设置环境变量 ENV TZ=Asia/Shanghai diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 66db24af8..ee8e26f93 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json", "name": "DragonOS Dev Container", - "image": "docker.cnb.cool/dragonos-community/dragonos/dragonos-devcontainer:v1.19", + "image": "docker.cnb.cool/dragonos-community/dragonos/dragonos-devcontainer:v1.22", "features": { "ghcr.io/devcontainers/features/common-utils:2": { "installZsh": "false", diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index 23c49cab2..557658e23 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -11,14 +11,14 @@ jobs: name: Format check ${{ matrix.arch }} runs-on: ubuntu-latest continue-on-error: true - container: dragonos/dragonos-dev:v1.21 + container: dragonos/dragonos-dev:v1.22 strategy: matrix: arch: [x86_64, riscv64, loongarch64] steps: - - run: echo "Running in dragonos/dragonos-dev:v1.21" + - run: echo "Running in dragonos/dragonos-dev:v1.22" - uses: actions/checkout@v3 - name: Change source @@ -39,14 +39,14 @@ jobs: name: Kernel static test ${{ matrix.arch }} runs-on: ubuntu-latest continue-on-error: true - container: dragonos/dragonos-dev:v1.21 + container: dragonos/dragonos-dev:v1.22 strategy: matrix: arch: [x86_64, riscv64, loongarch64] steps: - - run: echo "Running in dragonos/dragonos-dev:v1.21" + - run: echo "Running in dragonos/dragonos-dev:v1.22" - uses: actions/checkout@v3 @@ -64,7 +64,7 @@ jobs: build: name: Build ${{ matrix.arch }} runs-on: ubuntu-latest - container: dragonos/dragonos-dev:v1.21 + container: dragonos/dragonos-dev:v1.22 continue-on-error: true strategy: matrix: @@ -81,7 +81,7 @@ jobs: checkout_params: {} steps: - - run: echo "Running in dragonos/dragonos-dev:v1.21" + - run: echo "Running in dragonos/dragonos-dev:v1.22" - uses: actions/checkout@v3 with: ${{ matrix.checkout_params }} diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index 099be46d8..fe71cf131 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -20,7 +20,7 @@ jobs: env: HOME: /root container: - image: dragonos/dragonos-dev:v1.21 + image: dragonos/dragonos-dev:v1.22 options: --privileged -v /dev:/dev steps: - name: Checkout DragonOS code diff --git a/.github/workflows/test-mm.yaml b/.github/workflows/test-mm.yaml index 568a29835..a0d3483f7 100644 --- a/.github/workflows/test-mm.yaml +++ b/.github/workflows/test-mm.yaml @@ -17,7 +17,7 @@ jobs: name: Build slab_stress (host) runs-on: ubuntu-latest container: - image: dragonos/dragonos-dev:v1.21 + image: dragonos/dragonos-dev:v1.22 options: --privileged -v /dev:/dev steps: - name: Checkout DragonOS code @@ -46,7 +46,7 @@ jobs: size: [64, 128, 255, 256] seed: [1, 2, 3] container: - image: dragonos/dragonos-dev:v1.21 + image: dragonos/dragonos-dev:v1.22 options: --privileged -v /dev:/dev steps: - name: Checkout DragonOS code diff --git a/.github/workflows/test-x86.yml b/.github/workflows/test-x86.yml index 2ee70fba4..9fc9b19be 100644 --- a/.github/workflows/test-x86.yml +++ b/.github/workflows/test-x86.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 60 container: - image: dragonos/dragonos-dev:v1.21 + image: dragonos/dragonos-dev:v1.22 options: --privileged -v /dev:/dev steps: - name: Checkout DragonOS code diff --git a/.gitignore b/.gitignore index 823f3bec4..35347d40d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ cppcheck.xml compile_commands.json /logs/ *.log +.nix-gc-root dadk-manifest.generated.toml config/rootfs.generated.toml diff --git a/docs/introduction/develop_nix.md b/docs/introduction/develop_nix.md index 06afeac9f..b3ea86c5f 100644 --- a/docs/introduction/develop_nix.md +++ b/docs/introduction/develop_nix.md @@ -11,6 +11,21 @@ nix 的引入使得 DragonOS 的开发环境不再依赖手动维护的 `bootstr - 如果你想体验 nix 带来的声明式管理,又不想更改发行版,尝试 home-manager 并在其上配置启用 flakes、direnv - 否则可以直接以 nix standalone 的方式安装 flakes,或者每次输入命令时添加 `--experimental-features 'nix-command flakes'` +## 国内镜像加速(推荐) + +如果你在国内且没有全局代理,首次拉取依赖可能很慢甚至失败。本仓库已在 `flake.nix` 内置国内镜像配置,使用 `nix develop / nix run` 时会自动生效。 + +若仍然不生效,建议在用户级配置中追加以下内容(不会覆盖你已有配置): + +```shell +mkdir -p ~/.config/nix +cat >> ~/.config/nix/nix.conf <<'EOF' +# DragonOS Nix mirror (CN) +extra-substituters = https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store https://mirrors.ustc.edu.cn/nix-channels/store +extra-trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= +EOF +``` + ## 克隆仓库 DragonOS 现在在多个托管平台上都有仓库镜像 @@ -26,7 +41,7 @@ cd DragonOS ## 激活内核编译环境 ```shell -nix develop ./tools/nix-dev-shell +nix develop ``` 如果你配置了 `direnv`,首次进入仓库目录会提示需要执行 `direnv allow`,相当于自动进入了 `nix develop` 环境。 diff --git a/flake.nix b/flake.nix index eda4ea6cc..007f566ef 100644 --- a/flake.nix +++ b/flake.nix @@ -1,6 +1,17 @@ { description = "RootFS"; + nixConfig = { + # 国内镜像优先,保留官方缓存作为回退 + extra-substituters = [ + "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store" + "https://mirrors.ustc.edu.cn/nix-channels/store" + ]; + extra-trusted-public-keys = [ + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + ]; + }; + inputs = { fenix = { url = "github:nix-community/fenix"; @@ -45,10 +56,37 @@ rootfsType = "ext4"; buildDir = "./bin"; # Specifying temp file location - rust-toolchain = fenix.packages.${system}.fromToolchainFile { - file = ./kernel/rust-toolchain.toml; + rust-toolchain-toml = builtins.fromTOML (builtins.readFile ./kernel/rust-toolchain.toml); + rust-channel-raw = rust-toolchain-toml.toolchain.channel; + rust-channel-match = builtins.match "^(stable|beta|nightly)(-([0-9]{4}-[0-9]{2}-[0-9]{2}))?$" rust-channel-raw; + rust-channel = + if rust-channel-match == null then rust-channel-raw else builtins.elemAt rust-channel-match 0; + rust-date = + if rust-channel-match == null || builtins.elemAt rust-channel-match 2 == null then + null + else + builtins.elemAt rust-channel-match 2; + rust-components = rust-toolchain-toml.toolchain.components or [ ]; + rust-dist-root = "https://rsproxy.cn/dist"; + rust-toolchain-base = fenix.packages.${system}.toolchainOf { + root = rust-dist-root; + channel = rust-channel; + date = rust-date; sha256 = "sha256-3JA9u08FrvsLdi5dGIsUeQZq3Tpn9RvWdkLus2+5cHs="; }; + rust-toolchain-raw = rust-toolchain-base.withComponents rust-components; + rust-toolchain = pkgs.symlinkJoin { + name = "rust-toolchain-wrapped"; + paths = [ rust-toolchain-raw ]; + nativeBuildInputs = [ pkgs.makeWrapper ]; + postBuild = '' + for bin in "$out/bin/"*; do + if [ -x "$bin" ]; then + wrapProgram "$bin" --prefix LD_LIBRARY_PATH : ${pkgs.zlib}/lib + fi + done + ''; + }; testOpt = { # 自动测试项目,指定内核启动环境变量参数 AUTO_TEST @@ -79,8 +117,26 @@ # 启用 VM 状态管理,与 make qemu 行为保持一致 vmstateDir = "${buildDir}/vmstate"; }; + qemuScriptsSystem = import ./tools/qemu/default.nix { + inherit + lib + pkgs + testOpt + diskPath + ; + # QEMU 相关参数: + # 内核位置 + kernel = "${buildDir}/kernel/kernel.elf"; # TODO: make it a drv 用nix构建内核,避免指定相对目录 + # -s -S + debug = false; + # 启用 VM 状态管理,与 make qemu 行为保持一致 + vmstateDir = "${buildDir}/vmstate"; + # 优先使用系统 QEMU,避免 Nix 下载 QEMU 依赖 + preferSystemQemu = true; + }; startPkg = qemuScripts.${target}; + startSystemPkg = qemuScriptsSystem.${target}; rootfsPkg = pkgs.callPackage ./user/default.nix { inherit lib @@ -126,6 +182,11 @@ program = "${startPkg}/bin/dragonos-run"; meta.description = "以 ${target} 启动DragonOS"; }; + "start-system-${target}" = { + type = "app"; + program = "${startSystemPkg}/bin/dragonos-run"; + meta.description = "以系统 QEMU 启动DragonOS (${target})"; + }; # rootfs 中涉及到基于docker镜像的rootfs构建,修改了 user/ 下软件包相关内容后, # rootfs 的docker镜像会重复构建,并且由于nix特性,副本会全部保留 # 因此可能会占很多空间,如果要清理空间请执行 nix store gc @@ -138,6 +199,7 @@ packages = { "yolo-${target}" = runApp; "start-${target}" = startPkg; + "start-system-${target}" = startSystemPkg; "rootfs-${target}" = rootfsPkg; }; }; @@ -184,8 +246,11 @@ libclang gcc rust-toolchain + zlib gnumake qemu_kvm + meson + ninja ]; env = { @@ -195,6 +260,13 @@ # Shell启动脚本 shellHook = '' + # 自动创建 GC root,避免 nix store gc 清理开发环境 + if [ -z "''${DRAGONOS_NIX_GC_ROOT:-}" ]; then + if [ ! -e ".nix-gc-root" ]; then + echo "创建 Nix GC root: .nix-gc-root" + ${pkgs.nix}/bin/nix build .#devShells.${system}.default -o ./.nix-gc-root >/dev/null 2>&1 || true + fi + fi echo "欢迎进入 DragonOS Nix 开发环境!" echo "" echo "要运行 DragonOS,请构建内核、rootfs,再QEMU运行" diff --git a/tools/bootstrap.sh b/tools/bootstrap.sh index 82b395735..f8d8120b0 100755 --- a/tools/bootstrap.sh +++ b/tools/bootstrap.sh @@ -27,6 +27,14 @@ INSTALL_MODE="" export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER:-https://rsproxy.cn} export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT:-https://rsproxy.cn/rustup} export RUST_VERSION="${RUST_VERSION:-nightly-2025-08-10}" +export NIX_MIRROR=${NIX_MIRROR:-} +export NIX_INSTALLER_URL=${NIX_INSTALLER_URL:-https://mirrors.tuna.tsinghua.edu.cn/nix/latest/install} +export NIX_INSTALLER_FALLBACK_URL=${NIX_INSTALLER_FALLBACK_URL:-https://nixos.org/nix/install} +export NIX_INSTALLER_ARGS=${NIX_INSTALLER_ARGS:---daemon} +export NIX_TRUSTED_USER=${NIX_TRUSTED_USER:-} +export NIX_AUTO_GC=${NIX_AUTO_GC:-} +export NIX_MIN_FREE=${NIX_MIN_FREE:-5G} +export NIX_MAX_FREE=${NIX_MAX_FREE:-10G} banner() { @@ -59,37 +67,235 @@ congratulations_nix() echo "| 请[关闭]当前终端, 并[重新打开]一个终端 |" echo "| 然后通过以下命令进入开发环境: |" echo "| |" - echo "| nix develop ./tools/nix-dev-shell |" + echo "| nix develop |" echo "| |" echo "|------------------------------------------|" } #################################################################################### -# 安装 Nix 包管理器 +# 配置 Nix 国内镜像源 (可选) #################################################################################### -install_nix() +setup_nix_mirror() { - if [ -n "$(which nix)" ]; then - echo "Nix 已经安装在您的系统上。" + if [ "$CI_INSTALL" = "true" ]; then return 0 fi - echo "正在安装 Nix 包管理器..." - curl -fsSL https://install.determinate.systems/nix | sh -s -- install - - if [ $? -ne 0 ]; then - echo "Nix 安装失败!" - exit 1 + local enable_mirror="" + if [ -n "$NIX_MIRROR" ]; then + if echo "$NIX_MIRROR" | grep -Eiq "^(0|false|no)$"; then + enable_mirror="" + else + enable_mirror="true" + fi + else + echo "" + echo "是否启用国内 Nix 镜像源(清华/中科大)?" + echo "若你在国内且没有全局代理,强烈推荐开启。" + printf "(y/N): " + read mirror_choice + if echo "$mirror_choice" | grep -iq "^y" ;then + enable_mirror="true" + fi fi - echo "Nix 安装成功!" + if [ "$enable_mirror" = "true" ]; then + local config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/nix" + local config_file="${config_dir}/nix.conf" + mkdir -p "$config_dir" - # Source nix environment - if [ -f "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]; then - . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + if ! grep -q "DragonOS Nix mirror" "$config_file" 2>/dev/null; then + cat >> "$config_file" <<'EOF' +# DragonOS Nix mirror (CN) +substituters = https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store https://mirrors.ustc.edu.cn/nix-channels/store https://cache.nixos.org/ +trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= +EOF + echo "已写入 Nix 镜像配置: $config_file" + else + echo "已检测到 Nix 镜像配置,跳过写入。" + fi fi } +#################################################################################### +# 启用 Nix 实验特性(nix-command + flakes) +#################################################################################### +configure_nix_features() +{ + local config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/nix" + local config_file="${config_dir}/nix.conf" + mkdir -p "$config_dir" + + if ! grep -q "experimental-features" "$config_file" 2>/dev/null; then + cat >> "$config_file" <<'EOF' +# DragonOS Nix features +experimental-features = nix-command flakes +EOF + echo "已写入 Nix 实验特性配置: $config_file" + else + echo "已检测到 Nix 实验特性配置,跳过写入。" + fi +} + +#################################################################################### +# 将当前用户加入 Nix trusted-users(需要 sudo) +#################################################################################### +configure_nix_trusted_user() +{ + if [ "$CI_INSTALL" = "true" ]; then + return 0 + fi + + local enable_trust="" + if [ -n "$NIX_TRUSTED_USER" ]; then + if echo "$NIX_TRUSTED_USER" | grep -Eiq "^(0|false|no)$"; then + enable_trust="" + else + enable_trust="true" + fi + else + echo "" + echo "是否将当前用户加入 Nix trusted-users?" + echo "否则会忽略 extra-substituters 等受限配置。" + printf "(y/N): " + read trust_choice + if echo "$trust_choice" | grep -iq "^y" ;then + enable_trust="true" + fi + fi + + if [ "$enable_trust" = "true" ]; then + local sys_conf="/etc/nix/nix.conf" + if ! grep -q "DragonOS Nix trusted users" "$sys_conf" 2>/dev/null; then + sudo sh -c "printf '%s\n' '# DragonOS Nix trusted users' 'trusted-users = root $USER' >> \"$sys_conf\"" + echo "已写入 trusted-users: $sys_conf" + else + echo "已检测到 trusted-users 配置,跳过写入。" + fi + # 尝试重启 nix-daemon(若尚未安装则忽略失败) + if command -v systemctl >/dev/null 2>&1; then + sudo systemctl restart nix-daemon 2>/dev/null || true + fi + fi +} + +#################################################################################### +# 配置 Nix 自动 GC(磁盘空间低于阈值时自动清理) +#################################################################################### +configure_nix_auto_gc() +{ + if [ "$CI_INSTALL" = "true" ]; then + return 0 + fi + + local enable_auto_gc="" + if [ -n "$NIX_AUTO_GC" ]; then + if echo "$NIX_AUTO_GC" | grep -Eiq "^(0|false|no)$"; then + enable_auto_gc="" + else + enable_auto_gc="true" + fi + else + echo "" + echo "是否启用 Nix 自动 GC?(磁盘空间不足时自动清理旧构建)" + echo "默认阈值: min-free=${NIX_MIN_FREE}, max-free=${NIX_MAX_FREE}" + printf "(y/N): " + read auto_gc_choice + if echo "$auto_gc_choice" | grep -iq "^y" ;then + enable_auto_gc="true" + fi + fi + + if [ "$enable_auto_gc" = "true" ]; then + local min_free="${NIX_MIN_FREE}" + local max_free="${NIX_MAX_FREE}" + # 将 GiB/MiB 形式转换为 Nix 可接受的 G/M + case "$min_free" in + *GiB) min_free="${min_free%GiB}G" ;; + *MiB) min_free="${min_free%MiB}M" ;; + esac + case "$max_free" in + *GiB) max_free="${max_free%GiB}G" ;; + *MiB) max_free="${max_free%MiB}M" ;; + esac + + local sys_conf="/etc/nix/nix.conf" + local user_conf="${XDG_CONFIG_HOME:-$HOME/.config}/nix/nix.conf" + local target_conf="" + + if [ -w "$sys_conf" ] || sudo -n true 2>/dev/null; then + target_conf="$sys_conf" + sudo sh -c "mkdir -p \"$(dirname "$sys_conf")\"" + if sudo sh -c "grep -q 'DragonOS Nix auto gc' \"$sys_conf\" 2>/dev/null"; then + sudo sed -i "s/^min-free.*/min-free = ${min_free}/" "$sys_conf" + sudo sed -i "s/^max-free.*/max-free = ${max_free}/" "$sys_conf" + echo "已更新 Nix 自动 GC 配置: $sys_conf" + else + sudo sh -c "printf '%s\n' '# DragonOS Nix auto gc' 'min-free = $min_free' 'max-free = $max_free' >> \"$sys_conf\"" + echo "已写入 Nix 自动 GC 配置: $sys_conf" + fi + else + mkdir -p "$(dirname "$user_conf")" + target_conf="$user_conf" + if grep -q "DragonOS Nix auto gc" "$user_conf" 2>/dev/null; then + sed -i "s/^min-free.*/min-free = ${min_free}/" "$user_conf" + sed -i "s/^max-free.*/max-free = ${max_free}/" "$user_conf" + echo "已更新 Nix 自动 GC 配置: $user_conf" + else + cat >> "$user_conf" </dev/null 2>&1; then + echo "Nix 已经安装在您的系统上。" + else + echo "正在安装 Nix 包管理器..." + set -o pipefail + if ! curl -fsSL "$NIX_INSTALLER_URL" | sh -s -- $NIX_INSTALLER_ARGS; then + echo "镜像下载失败,尝试官方地址..." + if ! curl -fsSL "$NIX_INSTALLER_FALLBACK_URL" | sh -s -- $NIX_INSTALLER_ARGS; then + echo "Nix 安装脚本下载失败!" + set +o pipefail + exit 1 + fi + fi + set +o pipefail + + echo "Nix 安装成功!" + + # Source nix environment + if [ -f "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]; then + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + fi + fi + + # 配置 trusted-users + configure_nix_trusted_user + + # 配置 Nix 实验特性 + configure_nix_features + + # 配置 Nix 自动 GC + configure_nix_auto_gc + + congratulations_nix +} + #################################################################################### # 询问用户选择安装模式 #################################################################################### @@ -439,14 +645,13 @@ banner # 开始横幅 # 询问安装模式 ask_install_mode -# 如果是 nix 模式,直接结束 +# 仅在 nix 模式下安装并配置 Nix;legacy 模式不安装 Nix if [ "$INSTALL_MODE" = "nix" ]; then install_nix - congratulations_nix exit 0 fi -# 以下是 legacy 模式的安装流程 +# 以下是 legacy 模式的安装流程(不安装 Nix,仅安装传统依赖) echo "安装传统依赖..." if [ "Darwin" == "$(uname -s)" ]; then @@ -485,7 +690,7 @@ fi rustInstall # 安装dadk -cargo +nightly install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v0.6.0 || exit 1 +cargo +nightly install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v0.6.1 --locked || exit 1 bashpath=$(cd `dirname $0`; pwd) diff --git a/tools/build_in_docker.sh b/tools/build_in_docker.sh index 9c710fa6b..1a1f89e53 100755 --- a/tools/build_in_docker.sh +++ b/tools/build_in_docker.sh @@ -1,6 +1,6 @@ docker rm -f dragonos-build || echo "No existed container" cpu_count=$(cat /proc/cpuinfo |grep "processor"|wc -l) -docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.21 bash << EOF +docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.22 bash << EOF source ~/.cargo/env source ~/.bashrc cd /data diff --git a/tools/qemu/default.nix b/tools/qemu/default.nix index 56f792550..cc89d3a20 100644 --- a/tools/qemu/default.nix +++ b/tools/qemu/default.nix @@ -6,10 +6,11 @@ testOpt, debug ? false, vmstateDir ? null, + preferSystemQemu ? false, }: let - qemuFirmware = pkgs.callPackage ./qemu-firmware.nix { }; + qemuFirmware = if preferSystemQemu then null else pkgs.callPackage ./qemu-firmware.nix { }; baseConfig = { nographic = true; @@ -161,6 +162,7 @@ let # VM 状态目录配置 vmstateDirStr = if vmstateDir != null then vmstateDir else ""; hasVmstateDir = vmstateDir != null; + preferSystemQemuStr = if preferSystemQemu then "true" else "false"; in pkgs.writeScriptBin name '' @@ -168,6 +170,13 @@ let if [ ! -d "bin" ]; then echo "Error: Please run from project root (bin/ missing)."; exit 1; fi + if [ "${preferSystemQemuStr}" = "true" ]; then + if ! command -v "${qemuBin}" >/dev/null 2>&1; then + echo "Error: 系统未找到 ${qemuBin},请安装 QEMU 或改用 nix 提供的 start 目标。" + exit 1 + fi + fi + # 端口查找函数:从指定端口开始查找可用端口 find_available_port() { local start_port=$1 @@ -242,11 +251,15 @@ let ${ if hasVmstateDir then '' - sudo bash -c 'pidfile="$1"; shift; echo $$ > "$pidfile"; exec "$@"' bash "$VMSTATE_DIR/pid" ${qemuBin} ${qemuFlagsStr} "''${NET_ARGS[@]}" -L ${qemuFirmware} "''${ARCH_FLAGS[@]}" "''${BOOT_ARGS[@]}" "''${DISK_ARGS[@]}" "$@" + sudo bash -c 'pidfile="$1"; shift; echo $$ > "$pidfile"; exec "$@"' bash "$VMSTATE_DIR/pid" ${qemuBin} ${qemuFlagsStr} "''${NET_ARGS[@]}" ${ + if qemuFirmware != null then "-L ${qemuFirmware}" else "" + } "''${ARCH_FLAGS[@]}" "''${BOOT_ARGS[@]}" "''${DISK_ARGS[@]}" "$@" '' else '' - sudo ${qemuBin} ${qemuFlagsStr} "''${NET_ARGS[@]}" -L ${qemuFirmware} "''${ARCH_FLAGS[@]}" "''${BOOT_ARGS[@]}" "''${DISK_ARGS[@]}" "$@" + sudo ${qemuBin} ${qemuFlagsStr} "''${NET_ARGS[@]}" ${ + if qemuFirmware != null then "-L ${qemuFirmware}" else "" + } "''${ARCH_FLAGS[@]}" "''${BOOT_ARGS[@]}" "''${DISK_ARGS[@]}" "$@" '' } ''; @@ -257,7 +270,11 @@ let name = "dragonos-run"; inherit arch; isNographic = if arch == "riscv64" then true else baseConfig.nographic; - qemuBin = "${pkgs.qemu_kvm}/bin/qemu-system-${arch}"; + qemuBin = + if preferSystemQemu then + "qemu-system-${arch}" + else + "${pkgs.qemu_kvm}/bin/qemu-system-${arch}"; } ); in