Files
DragonOS/flake.nix
T
aLinCheandlongjin b1db90db11 feat(pi_lock): feat pi_lock and fix lock (#1926)
* fix(lock): fix pi_lock and rwlock

Signed-off-by: aLinChe <1129332011@qq.com>

* fix(wakeup): fix wakeup()

Signed-off-by: aLinChe <1129332011@qq.com>

* fix(stop_task): fix stop_task() dequeue + kick

Signed-off-by: aLinChe <1129332011@qq.com>

* fix(nix)

Signed-off-by: aLinChe <1129332011@qq.com>

* fix(stop_task)

Signed-off-by: aLinChe <1129332011@qq.com>

* fmt

Signed-off-by: aLinChe <1129332011@qq.com>

* fix(process): avoid requeueing stopped tasks

Signed-off-by: longjin <longjin@dragonos.org>

* fix(sched): use atomic state in pick next task

Signed-off-by: longjin <longjin@dragonos.org>

* add nix run .#start-debug-*

Signed-off-by: aLinChe <1129332011@qq.com>

---------

Signed-off-by: aLinChe <1129332011@qq.com>
Signed-off-by: longjin <longjin@dragonos.org>
Co-authored-by: longjin <longjin@dragonos.org>
2026-05-28 20:42:00 +08:00

378 lines
14 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
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";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
flake-parts.url = "github:hercules-ci/flake-parts";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
inputs@{
self,
nixpkgs,
fenix,
flake-parts,
treefmt-nix,
}:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
inputs.treefmt-nix.flakeModule
];
systems = [
"x86_64-linux"
];
perSystem =
{
self',
inputs',
system,
...
}:
let
nixpkgs = inputs.nixpkgs;
fenix = inputs.fenix;
pkgs = nixpkgs.legacyPackages.${system};
lib = pkgs.lib;
rootfsType = "ext4";
buildDir = "./bin"; # Specifying temp file location
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-from-toml = rust-toolchain-toml.toolchain.components or [ ];
rust-required-components = [
"cargo"
"rustc"
"rust-std"
];
rust-missing-required = builtins.filter (
component: !(builtins.elem component rust-components-from-toml)
) rust-required-components;
rust-components-effective = lib.unique (rust-components-from-toml ++ rust-required-components);
rust-components-selected =
if rust-missing-required == [ ] then
rust-components-effective
else
builtins.trace "Warning: kernel/rust-toolchain.toml is missing required Rust components: ${lib.concatStringsSep ", " rust-missing-required}. DragonOS Nix build will auto-add them. Recommended: add them to kernel/rust-toolchain.toml to keep one explicit source of truth." rust-components-effective;
rust-dist-root = "https://rsproxy.cn/dist";
rust-toolchain-base = fenix.packages.${system}.toolchainOf {
root = rust-dist-root;
channel = rust-channel;
date = rust-date;
# Fixed-output hash for Rust channel metadata.
# Update this when rust-toolchain channel/date changes:
# 1) run nix develop / nix run
# 2) copy the "got: sha256-..." from mismatch error to this field
# 3) re-run nix develop and verify rustc/cargo come from rust-toolchain-wrapped/bin
sha256 = "sha256-ggvRZZFjlAlrZVjqul/f/UpU5CEhDbdKZU0OCR8Uzbc=";
};
rust-toolchain-raw = rust-toolchain-base.withComponents rust-components-selected;
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
autotest = "none"; # syscall / dunit
syscall = {
enable = true;
testDir = "/opt/gvisor";
version = "20251218";
};
dunitest = {
enable = true;
testDir = "/opt/tests/dunitest";
};
};
mkOutputs =
target:
let
diskPath = "${buildDir}/disk-image-${target}.img";
# vsock 固定配置(nix run .#start-* / .#yolo-* 生效):
# - guestCid 不能为 2host CID
vsockConfig = {
enable = true;
guestCid = 3;
deviceModel = "vhost-vsock-pci-non-transitional";
};
qemuScripts = import ./tools/qemu/default.nix {
inherit
lib
pkgs
testOpt
diskPath
;
# QEMU 相关参数:
# 内核位置
kernel = "${buildDir}/kernel/kernel.elf"; # TODO: make it a drv 用nix构建内核,避免指定相对目录
# 不开 GDB stub,普通启动
debug = false;
enableVsock = vsockConfig.enable;
vsockGuestCid = vsockConfig.guestCid;
vsockDeviceModel = vsockConfig.deviceModel;
# 启用 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;
enableVsock = vsockConfig.enable;
vsockGuestCid = vsockConfig.guestCid;
vsockDeviceModel = vsockConfig.deviceModel;
# 启用 VM 状态管理,与 make qemu 行为保持一致
vmstateDir = "${buildDir}/vmstate";
# 优先使用系统 QEMU,避免 Nix 下载 QEMU 依赖
preferSystemQemu = true;
};
qemuScriptsDebug = import ./tools/qemu/default.nix {
inherit
lib
pkgs
testOpt
diskPath
;
# QEMU 相关参数:
# 内核位置
kernel = "${buildDir}/kernel/kernel.elf";
# 开启 GDB stub,用于调试
debug = true;
enableVsock = vsockConfig.enable;
vsockGuestCid = vsockConfig.guestCid;
vsockDeviceModel = vsockConfig.deviceModel;
# 启用 VM 状态管理,与 make qemu 行为保持一致
vmstateDir = "${buildDir}/vmstate";
};
startPkg = qemuScripts.${target};
startSystemPkg = qemuScriptsSystem.${target};
startDebugPkg = qemuScriptsDebug.${target};
rootfsPkg = pkgs.callPackage ./user/default.nix {
inherit
lib
pkgs
nixpkgs
fenix
system
target
testOpt
rootfsType
buildDir
diskPath
;
};
gdbBin = if target == "x86_64" then "rust-gdb" else "gdb-multiarch";
gdbScript = pkgs.writeScriptBin "dragonos-gdb" ''
#!${pkgs.runtimeShell}
GDB_PORT_FILE="${buildDir}/vmstate/gdb"
if [ ! -f "$GDB_PORT_FILE" ]; then
echo "Error: VM not running or GDB port not allocated"
echo "Start VM first: nix run .#start-debug-''${target}"
exit 1
fi
GDB_PORT=$(cat "$GDB_PORT_FILE")
GDB_INIT_TMP=$(mktemp)
trap "rm -f $GDB_INIT_TMP" EXIT
sed "s/{{GDB_PORT}}/$GDB_PORT/" ${./tools/.gdbinit} > "$GDB_INIT_TMP"
echo "Connecting to GDB port: $GDB_PORT"
exec ${gdbBin} -n -x "$GDB_INIT_TMP"
'';
# 一键化构建启动脚本 (yolo: You Only Live Once - 一条命令跑通全部)
runApp = pkgs.writeScriptBin "dragonos-yolo" ''
#!${pkgs.runtimeShell}
set -e
export USING_DRAGONOS_NIX_ENV=1
export PATH=${rust-toolchain}/bin:$PATH
echo "==> Step 1: Building kernel with make kernel..."
${pkgs.gnumake}/bin/make kernel
echo "==> Step 2: Building rootfs (re-evaluating userland packages)..."
${pkgs.nix}/bin/nix run .#rootfs-${target}
echo "==> Step 3: Starting DragonOS..."
exec ${pkgs.nix}/bin/nix run .#start-${target} -- "$@"
'';
in
{
apps = {
# yolo-${target}: 一键化构建启动命令 (make kernel + rootfs + start)
"yolo-${target}" = {
type = "app";
program = "${runApp}/bin/dragonos-yolo";
meta.description = "一键化构建并启动DragonOS (${target})";
};
# start-${target} 的产物只是一个shell脚本,因此启动相关的参数,直接在上面修改即可,
# 脚本不占什么空间所以重复eval也没关系,并且最终产出的脚本可读性更好.
"start-${target}" = {
type = "app";
program = "${startPkg}/bin/dragonos-run";
meta.description = "以 ${target} 启动DragonOS";
};
"start-system-${target}" = {
type = "app";
program = "${startSystemPkg}/bin/dragonos-run";
meta.description = "以系统 QEMU 启动DragonOS (${target})";
};
"start-debug-${target}" = {
type = "app";
program = "${startDebugPkg}/bin/dragonos-run";
meta.description = "以调试模式启动DragonOS (开启GDB stub, ${target})";
};
# rootfs 中涉及到基于docker镜像的rootfs构建,修改了 user/ 下软件包相关内容后,
# rootfs 的docker镜像会重复构建,并且由于nix特性,副本会全部保留
# 因此可能会占很多空间,如果要清理空间请执行 nix store gc
"rootfs-${target}" = {
type = "app";
program = "${rootfsPkg}/bin/dragonos-rootfs";
meta.description = "构建 ${target} rootfs 镜像";
};
"gdb-${target}" = {
type = "app";
program = "${gdbScript}/bin/dragonos-gdb";
meta.description = "Connect GDB to running DragonOS (${target})";
};
};
packages = {
"yolo-${target}" = runApp;
"start-${target}" = startPkg;
"start-system-${target}" = startSystemPkg;
"start-debug-${target}" = startDebugPkg;
"rootfs-${target}" = rootfsPkg;
"gdb-${target}" = gdbScript;
};
};
allOutputs = map mkOutputs [
"x86_64"
"riscv64"
];
merged =
lib.foldl'
(acc: elem: {
apps = acc.apps // elem.apps;
packages = acc.packages // elem.packages;
})
{
apps = { };
packages = { };
}
allOutputs;
in
{
inherit (merged) apps packages;
# treefmt formatter配置 (使用nixfmt)
treefmt = {
projectRootFile = "flake.nix";
programs = {
nixfmt = {
enable = true;
package = pkgs.nixfmt-rfc-style;
};
};
settings.formatter.nixfmt.excludes = [ ".direnv/**" ];
};
devShells.default = pkgs.mkShell {
# 基础工具链
buildInputs = with pkgs; [
git
llvm
libclang
gcc
rust-toolchain
zlib
gnumake
qemu_kvm
meson
ninja
];
env = {
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
USING_DRAGONOS_NIX_ENV = 1;
};
# Shell启动脚本
shellHook = ''
export PATH=${rust-toolchain}/bin:$PATH
# 自动创建 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 " Rust toolchain:"
echo " rustc: $(rustc -V)"
echo " cargo: $(cargo -V)"
echo " path : ${rust-toolchain}/bin (prepended)"
echo ""
echo "要运行 DragonOS,请构建内核、rootfs,再QEMU运行"
echo ""
echo " 以下命令都会沿用当前 shell 的 Rust/Cargo 工具链:"
echo " 一键运行: nix run .#yolo-x86_64"
echo " 构建内核: make kernel"
echo " 构建 rootfs: nix run .#rootfs-x86_64"
echo " QEMU 运行: nix run .#start-x86_64"
echo ""
echo " 文档: https://docs.dragonos.org.cn/"
'';
};
};
};
}