Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - drivercraft/ostool: Rust构建OS的工具集 · GitHub
Skip to content

Repository files navigation

ostool

CheckCrates.ioLicenseRust


🌐 Language | 语言

English | 简体中文 (当前 | Current)


📖 项目简介

ostool 是一个专为操作系统开发而设计的 Rust 工具集,旨在为 OS 开发者提供便捷的构建、配置和启动环境。它特别适合嵌入式系统开发,支持通过 Qemu 虚拟机和 U-Boot 引导程序进行系统测试和调试。

✨ 核心特性

  • 🔧 一体化工具链 - 集构建、配置、运行于一体的完整解决方案
  • 🖥️ 现代化 TUI - 基于终端的用户界面,提供直观的配置编辑体验
  • ⚙️ 智能配置管理 - JSON Schema 驱动的配置验证和编辑
  • 🚀 多种启动方式 - 支持 Qemu 虚拟机和 U-Boot 硬件启动
  • 🌐 跨平台支持 - Linux、Windows 等多平台兼容
  • 📦 模块化架构 - 可扩展的组件设计,便于定制和集成

🏗️ 项目架构

ostool 采用 Rust 工作空间架构,包含以下核心模块:

核心组件

组件功能描述主要用途
ostool主要工具包CLI 工具,构建和运行系统
jkconfig配置编辑器TUI 配置编辑界面
fitimageFIT 镜像构建U-Boot 兼容的启动镜像生成
uboot-shellU-Boot 通信串口通信和命令执行

技术栈

  • Rust - 核心开发语言,提供内存安全和性能
  • Ratatui - 现代化 TUI 框架
  • JSON Schema - 配置验证和类型安全
  • Tokio - 异步运行时
  • Serialport - 串口通信
  • Clap - 命令行参数解析

🚀 快速开始

安装

# 从 crates.io 安装
cargo install ostool
# 或从源码构建
git clone https://github.com/ZR233/ostool.git
cd ostool
cargo install --path .

基本使用

1. 查看帮助

# 查看主帮助
ostool --help
# 查看构建帮助
ostool build --help
# 查看运行帮助
ostool run --help
# 查看配置帮助
ostool menuconfig --help

2. 配置管理

# 使用 TUI 编辑构建配置
ostool menuconfig
# 配置 QEMU 运行参数
ostool menuconfig qemu
# 配置 U-Boot 运行参数
ostool menuconfig uboot

3. 构建系统

# 构建项目(使用默认配置文件 .build.toml)
ostool build
# 指定配置文件构建
ostool build --config custom-build.toml
# 临时覆盖 Cargo package / binary target
ostool build --config custom-build.toml --package paging-test --bin basic
# 临时构建 Cargo test target
ostool build --config custom-build.toml --package paging-test --test kernel_axtest
# 在指定工作目录中构建
ostool --workdir /path/to/project build

4. 运行系统

# 使用 Qemu 运行
ostool run qemu
# 使用 Qemu 运行并启用调试
ostool run qemu --debug
# 使用 Qemu 运行并转储 DTB 文件
ostool run qemu --dtb-dump
# 指定 Qemu 配置文件运行
ostool run qemu --qemu-config my-qemu.toml
# 临时覆盖 Cargo package / binary/test target 后运行
ostool run qemu --package paging-test --bin basic
# 使用 U-Boot 运行
ostool run uboot
# 指定 U-Boot 配置文件运行
ostool run uboot --uboot-config my-uboot.toml
# 配置远端开发板服务器
ostool board config
# 查看远端开发板类型
ostool board ls
# 在远端开发板上运行
ostool board run
# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic

交互退出:在串口终端(如 ostool run uboot)中,按下 Ctrl+A 后再按 x,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。 更多键盘快捷键映射可参考源码 ostool/src/sterm/mod.rs

⚙️ 配置文件

ostool 使用多个独立的 TOML 配置文件,每个文件负责不同的功能模块:

构建配置 (.build.toml)

构建配置文件定义了如何编译你的操作系统内核。

Cargo 构建系统示例

[system]
# 使用 Cargo 构建系统system = "Cargo"
[system.Cargo]
# 目标三元组target = "aarch64-unknown-none"# 包名称package = "my-os-kernel"# 二进制 target 名称。包内只有一个 binary 时可省略;# 包内有多个 binary 时建议设置,或在命令行传 `--bin <name>`。bin = "my-os-kernel"# test target 名称。用于构建可执行 `[[test]]` 目标,例如 `harness = false`# 的内核测试;与 `bin` 互斥,也可在命令行传 `--test <name>`。# test = "my-os-kernel-axtest"# 启用的特性features = ["page-alloc-4g"]
# 日志级别log = "Info"# 环境变量env = { "RUSTFLAGS" = "-C link-arg=-Tlinker.ld" }
# Cargo 构建 profile,可选值为 "Debug" 或 "Release"。# 省略时保持兼容行为:QEMU --debug 使用 Debug,其它构建/运行使用 Release。profile = "Release"# 如需禁用从 someboot build-info.toml 自动注入 Cargo 参数,可显式设置为 true。# disable_someboot_build_config = true# 额外的 cargo 参数args = []
# 构建前执行的命令pre_build_cmds = ["make prepare"]
# 构建后执行的命令post_build_cmds = ["make post-process"]
# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

命令行 --package/--bin/--test 会先覆盖 .build.toml 中的 Cargo 包/目标选择,再用于 ${package} 变量展开和 someboot build-info.toml 自动参数注入。

自定义构建系统示例

[system]
# 使用自定义构建系统system = "Custom"
[system.Custom]
# 构建命令build_cmd = "make ARCH=aarch64 A=examples/helloworld"# 生成的 ELF 文件路径elf_path = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"# 可选兼容字段。U-Boot、board 和 UEFI QEMU 运行会自动准备所需 BIN。to_bin = false

QEMU 配置 (.qemu.toml)

QEMU 配置文件定义了虚拟机的启动参数。

# QEMU 启动参数args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]
# 启用 UEFI 引导uefi = false# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。to_bin = false# 失败运行的正则表达式(用于自动检测)fail_regex = ["panic", "error", "failed"]

U-Boot 配置 (.uboot.toml)

U-Boot 配置文件定义了硬件启动参数。

# 串口设备serial = "/dev/ttyUSB0"# 波特率baud_rate = "115200"# 设备树文件(可选)dtb_file = "tools/device_tree.dtb"# 内核加载地址(可选)kernel_load_addr = "0x80080000"# 网络启动配置(可选)
[net]
interface = "eth0"board_ip = "192.168.1.100"# 板子重置命令(可选)board_reset_cmd = "reset"# 板子断电命令(可选)board_power_off_cmd = "poweroff"# 失败启动的正则表达式fail_regex = ["Boot failed", "Error loading kernel"]

有序 Shell 初始化步骤

QEMU、U-Boot 和 board 配置都使用 shell_check_steps 描述有序的 shell 命令与结果检查。例如先从 Axvisor shell 切换到 VM console,再在 guest shell 中执行测试命令:

fail_regex = ["(?i)failed|panic"]
shell_check_steps = [
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" },
{ shell_prefix = "root@starry:/root #", shell_cmd = "pwd && echo 'starry guest test pass'", success_regex = ["(?m)^starry guest test pass\\s*$"], fail_regex = ["(?i)failed|panic"], timeout = 30 },
]

数组下标就是执行顺序。需要发送命令的步骤必须能取得非空 shell_prefix;后续命令步骤省略它时会自动继承前一步的 prefix,显式写空字符串会报错。shell_cmd 可以省略,此时该步骤不等待 prompt、不发送命令,只按 success_regex/fail_regex 检查输出,适合 profile autorun 或内核自行运行测试的场景。

步骤同时配置 success_regexfail_regex 时,ostool 会先检查失败表达式,再检查成功表达式;任意一个成功表达式匹配后就进入下一步,任意一个失败表达式匹配则测试失败。只配置 fail_regex 会因为没有成功完成条件而被拒绝。timeout 是命令步骤发送完成后的等待秒数,且必须大于 0;不发送命令的被动步骤应使用顶层总 timeout

如果一步没有配置 success_regexfail_regex,命令完成 write/flush 后直接进入下一步。最后一步完成后,整个 shell-check 序列即视为测试成功。顶层 fail_regextimeout 分别是全局失败条件和总超时;步骤内 fail_regex 只在当前步骤等待结果时生效。

顶层 success_regex 已移除;成功条件必须放到相应的 shell_check_steps 步骤中。步骤的 prefix、命令和正则支持普通变量展开。board 的 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>} 仅在每一步的 shell_cmd 中展开。

只检查自行产生的输出时,可以使用无命令步骤:

[[shell_check_steps]]
success_regex = ["(?m)^TEST_PASSED\\s*$"]

这是一次配置硬切换:旧的顶层 shell prefix/command、旧步骤数组及旧步骤命令字段已经移除,旧配置需要整体迁移到 shell_check_steps,不会被兼容读取。

对于运行在 Axvisor 后面的 Starry guest,把旧的顶层成功表达式放到执行 guest 命令的步骤中;这样该步骤自己的 success/fail 负责判断命令结果,顶层 fail 继续兜底整个运行过程。

环境变量支持

配置文件支持环境变量替换,使用 ${env:VAR_NAME:-default} 格式:

# .uboot.toml 示例serial = "${env:SERIAL_DEVICE:-/dev/ttyUSB0}"baud_rate = "${env:BAUD_RATE:-115200}"

Board 全局配置 (~/.ostool/config.toml)

ostool board 系列命令默认读取用户级全局配置。首次执行相关命令时,如果该文件不存在,会自动创建默认配置:

[board]
server = "http://localhost:2999"auth_mode = "disabled"

可以通过下面的命令打开 TUI 编辑器修改:

ostool board config

server 应使用包含 http://https:// 的完整 URL;可选的 port 会覆盖 URL 中的端口。为兼容旧的局域网配置,裸 IPv4 或 IPv6 地址会自动补为 http://。基线版本写出的 server_ip / port 也会在读取时迁移为 server / port,下一次保存配置时只写新格式;无 scheme 的主机名不支持。项目级 .board.toml 中的 server / port 仍可用于 ostool board run,其优先级低于命令行参数,高于全局配置。

.board.toml 可以用 session_files 声明相对于配置文件目录的共享文件。调用方通过 BoardRunRequest::with_session_files 提供该目录,ostool 会在 board session 建立后按原相对路径上传,并在每个 shell_check_stepsshell_cmd 中展开 ${boardServerIp}${boardServerHttpBaseUrl}${sessionFile:<relative-path>}。绝对路径、..、符号链接逃逸、重复路径及缺失 文件都会在运行前被拒绝;接口不提供 alias 或上传改名。

公网开发板认证

局域网直接连接 ostool-server 时保留上述匿名 HTTP 配置。公网认证网关使用完整 HTTPS 地址:

[board]
server = "https://203.0.113.10:8443"auth_mode = "required"

登录使用浏览器设备授权流程,或从标准输入导入在 Web 管理台创建的个人访问令牌(PAT):

ostool login --server https://203.0.113.10:8443
printf'%s'"$OSTOOL_PAT"| ostool login --with-token --server https://203.0.113.10:8443
ostool auth status --server https://203.0.113.10:8443
ostool logout --server https://203.0.113.10:8443

OAuth 登录会自动刷新短期 access token;PAT 直接用于 Bearer 认证,不会刷新。凭据优先保存到系统 credential store;不可用时会警告并退回用户级凭据文件。自动化场景可设置 OSTOOL_BOARD_ACCESS_TOKEN,该 token 不保存也不刷新。

公网认证必须使用 HTTPS。客户端仅使用系统信任库验证证书;部署组织私有 CA 时,需由运维将其根证书安装到客户端系统。不要使用 HTTP、跳过证书验证或把 token 放进配置文件。

🛠️ 子项目详解

JKConfig - 智能配置编辑器

JKConfig 是一个基于 JSON Schema 的 TUI 配置编辑器,提供以下功能:

主要特性

  • 🎯 智能界面生成 - 自动从 JSON Schema 生成编辑界面
  • 🔒 类型安全 - 支持复杂数据类型和验证规则
  • 📝 多格式支持 - TOML、JSON 格式读写
  • 💾 自动备份 - 保存时自动创建备份文件
  • ⌨️ 快捷键支持 - Vim 风格的键盘操作

使用方法

# 安装
cargo install jkconfig
# 编辑配置
jkconfig -c config.toml -s config-schema.json
# 自动检测 schema
jkconfig -c config.toml

键盘快捷键

导航:
↑/↓ 或 j/k - 上下移动
Enter - 编辑项目
Esc - 返回上级
操作:
S - 保存并退出
Q - 不保存退出
C - 清除当前值
M - 切换菜单状态
Tab - 切换选项
~ - 调试控制台

FitImage - FIT 镜像构建工具

FitImage 是用于创建 U-Boot 兼容的 FIT (Flattened Image Tree) 镜像的专业工具:

主要特性

  • 🏗️ 标准 FIT 格式 - 完全符合 U-Boot FIT 规范
  • 📦 多组件支持 - 内核、设备树、ramdisk 等
  • 🗜️ 压缩功能 - gzip 压缩减少镜像大小
  • 🔐 校验支持 - CRC32、SHA1 等多种校验算法
  • 🎯 架构兼容 - ARM、ARM64 等多种架构

使用示例

use fitimage::{FitImageBuilder,FitImageConfig,ComponentConfig};// 创建 FIT 镜像配置let config = FitImageConfig::new("My FIT Image").with_kernel(ComponentConfig::new("kernel", kernel_data).with_type("kernel").with_arch("arm64").with_load_address(0x80080000)).with_fdt(ComponentConfig::new("fdt", fdt_data).with_type("flat_dt").with_arch("arm64"));// 构建镜像letmut builder = FitImageBuilder::new();let fit_data = builder.build(config)?;// 保存文件
std::fs::write("image.fit", fit_data)?;

🎯 使用场景

1. 本地开发工作流

# 1. 初始化项目
git clone <your-os-project>cd<your-os-project># 2. 使用 menuconfig 配置构建参数
ostool menuconfig
# 3. 配置 QEMU 运行参数
ostool menuconfig qemu
# 4. 构建项目
ostool build
# 5. 使用 Qemu 运行
ostool run qemu
# 6. 启用调试模式运行
ostool run qemu --debug

2. 远程构建和硬件测试

# 1. 使用 menuconfig 配置自定义构建
ostool menuconfig
# 2. 配置 U-Boot 运行参数
ostool menuconfig uboot
# 3. 执行构建
ostool build
# 4. 通过 U-Boot 启动到硬件
ostool run uboot
# 5. 指定自定义 U-Boot 配置
ostool run uboot --uboot-config custom-uboot.toml

3. 嵌入式系统开发

  • 🎯 多架构支持 - ARM64、RISC-V64 等多种架构
  • 🔧 设备树管理 - 自动处理 DTB 文件和设备树配置
  • 📡 网络启动 - 支持 TFTP 网络启动和远程加载
  • 🖥️ 串口调试 - 实时串口监控和调试信息输出
  • 🔐 FIT 镜像 - 创建 U-Boot 兼容的 FIT 启动镜像
  • 自动化构建 - 支持构建前后脚本和自定义命令

4. 高级调试场景

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 转储 DTB 文件用于调试
ostool run qemu --dtb-dump
# 在指定工作目录中操作
ostool --workdir /path/to/kernel build
ostool --workdir /path/to/kernel run qemu

🔧 高级配置

U-Boot 网络启动设置

# TFTP 需要 root 权限绑定 69 端口
sudo setcap cap_net_bind_service=+eip $(which ostool)

在 Linux 上使用系统 TFTP 根目录(默认 /srv/tftp)时,ostool 会在 /srv/tftp/ostool 下暂存 FIT 镜像,并在任务结束后使用普通用户权限删除暂存目录。 请为该目录配置专用用户组:

# 首次配置
sudo groupadd ostool
sudo usermod -aG ostool "$USER"
sudo install -d -o root -g ostool -m 2775 /srv/tftp/ostool

配置完成后,重新登录;也可以在当前终端启动一个已应用新用户组的 shell:

newgrp ostool

如果 ostool 组已经存在,可以跳过 groupadd。执行 newgrp ostool 或重新登录后, 新用户组权限才会生效;不需要重启 tftpd-hpa。ostool 不会在任务结束时使用 sudo rmdir;目录缺少组写权限时,清理操作会返回错误。

调试配置

[qemu]
args = "-s -S"# 启用 GDB 调试
[uboot]
# 启用详细日志log_level = "debug"

🐛 故障排除

常见问题

Q: U-Boot 启动失败? A: 检查以下几点:

  • 串口设备路径是否正确(/dev/ttyUSB0 或其他)
  • 串口权限是否足够(可能需要 sudo usermod -a -G dialout $USER
  • 波特率设置是否与硬件匹配
  • 设备树文件路径是否正确

Q: Qemu 无法启动? A: 检查以下几点:

  • 构建生成的内核文件是否存在
  • QEMU 配置中的架构参数是否正确
  • 是否安装了对应架构的 QEMU(如 qemu-system-aarch64

Q: 构建失败? A: 检查以下几点:

  • 构建配置文件格式是否正确
  • 自定义构建命令是否能在终端中执行
  • 目标架构的交叉编译工具链是否安装

Q: 配置文件格式错误? A: 检查以下几点:

  • TOML 语法是否正确(使用在线 TOML 验证器)
  • 配置文件是否使用了正确的字段名
  • 数组和字符串格式是否符合规范

Q: menuconfig 无法启动? A: 检查以下几点:

  • 终端是否支持 TUI 界面
  • 是否安装了必要的依赖(如 ncurses)
  • 配置文件权限是否正确

调试技巧

# 启用详细日志
RUST_LOG=debug ostool run qemu
# 查看完整的命令行帮助
ostool --help
ostool build --help
ostool run --help
ostool run qemu --help
ostool run uboot --help
ostool menuconfig --help
# 检查配置文件是否被正确加载
RUST_LOG=debug ostool build 2>&1| grep -i config
# 在指定工作目录中调试
ostool --workdir /path/to/project build

权限问题解决

# 将用户添加到 dialout 组以访问串口设备
sudo usermod -a -G dialout $USER# 重新登录或重启使权限生效# 或者临时使用 sudo 运行
sudo ostool run uboot

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建 特性分支 (git checkout -b feature/amazing-feature)
  3. 提交 更改 (git commit -m 'Add some amazing feature')
  4. 推送 到分支 (git push origin feature/amazing-feature)
  5. 创建 Pull Request

开发环境设置

git clone https://github.com/ZR233/ostool.git
cd ostool
cargo build
cargo test

📄 许可证

本项目采用双重许可证:

🔗 相关链接

🙏 致谢

感谢所有为 ostool 项目做出贡献的开发者和用户!

About

Rust构建OS的工具集

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages