ostool 0.30.1

A tool for operating system development
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
# ostool

[![Check](https://github.com/drivercraft/ostool/actions/workflows/check.yaml/badge.svg)](https://github.com/drivercraft/ostool/actions/workflows/check.yaml)
[![Crates.io](https://img.shields.io/crates/v/ostool.svg)](https://crates.io/crates/ostool)
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE)
[![Rust](https://img.shields.io/badge/rust-1.70+-orange.svg)](https://www.rust-lang.org)

---

## 🌐 Language | 语言

**[English](README.en.md)** | **简体中文** (当前 | Current)

---

## 📖 项目简介

axloader 网络控制(v2/v3/v4 旧协议兼容及 v5 设备 HTTP 接口)、持久 MAC 绑定、Web 管理、内建 QEMU 虚拟板和本地真实 FAT 磁盘验证设计见 [docs/axloader-network-control.md](docs/axloader-network-control.md),完整接口契约见 [docs/api.md](docs/api.md)。

管理后台位于 `/admin/`,使用 React + shadcn/ui。新建开发板时可先选择电源模块并手动上电,再从实时发现列表选择或手工填写 MAC;保存后完成绑定。全部管理页面采用 SSE 推送更新,断线重连保留页面与编辑草稿。详见 [管理界面与事件协议](docs/admin-ui.md)。
不兼容的板卡 TOML 会在启动时移入板卡目录下的 `quarantine/`,保留原文件和原因,其余有效板卡继续加载。

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

### ✨ 核心特性

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

## 🏗️ 项目架构

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

### 核心组件

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

### 技术栈

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

## 🚀 快速开始

### 安装

```bash
# 从 crates.io 安装
cargo install ostool

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

### 基本使用

#### 1. 查看帮助

```bash
# 查看主帮助
ostool --help

# 查看构建帮助
ostool build --help

# 查看运行帮助
ostool run --help

# 查看配置帮助
ostool menuconfig --help
```

#### 2. 配置管理

```bash
# 使用 TUI 编辑构建配置
ostool menuconfig

# 配置 QEMU 运行参数
ostool menuconfig qemu

# 配置 U-Boot 运行参数
ostool menuconfig uboot
```

#### 3. 构建系统

```bash
# 构建项目(使用默认配置文件 .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. 运行系统

```bash
# 使用 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 connect -b OrangePi-5-Plus --board-id OrangePi-5-Plus-2

# 在远端开发板上运行
ostool board run

# 在远端开发板上运行指定 Cargo binary/test target
ostool board run --package paging-test --bin basic
```

> 交互退出:在串口终端(如 `ostool run uboot`)中,按下 `Ctrl+A` 后再按 `x`,工具会检测到该序列并优雅退出,不会将按键发送到目标设备。

Unix 交互终端按原始字节转发客户机输入输出,不主动开启鼠标捕获。鼠标模式由客户机应用控制;光标位置回复和括号粘贴序列完整透传。普通 shell 可使用宿主终端的鼠标选择与粘贴。串口退出前缀启用时,连续输入两次 `Ctrl+A` 可发送一个字面 `Ctrl+A`。

串口会话通过有界通道隔离串口与 WebSocket 的收发。单条二进制或解码后的 `tx` 命令上限为 256 KiB;队列满时会话明确失败,不静默丢字节。详见 [服务器串口传输说明](ostool-server/README.md#serial-transport)。

客户端 `connect_serial_stream()` 为收发分别持有缓冲端点:远端关闭或报错后,接收方读完已收到的数据便结束;停止本地发送也能独立触发 WebSocket 关闭,不必等待接收方先退出。

> 更多键盘快捷键映射可参考源码 `ostool/src/sterm/mod.rs`。

## ⚙️ 配置文件

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

### 构建配置 (.build.toml)

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

#### Cargo 构建系统示例

```toml
[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` 自动参数注入。

#### ELF 分析产物

在 `.build.toml` 根级启用需要的分析产物。三个开关均默认为 `false`;未启用时不会调用分析工具,也不会登记分析文件。

```toml
[artifacts.analysis]
disassembly = true
elf_info = true
symbols = true
```

分析在既有的构建后钩子完成后执行,并始终读取同一个保留的原始 ELF:Cargo 构建使用 Cargo 解析出的已选可执行文件(因此会遵循 `package`、`bin`、`test` 和 `profile`),自定义构建使用 `elf_path`。Cargo 的运行时产物可能已完成复制或转换,但分析仍使用该原始源文件,因此三类分析产物描述的是原始输入,而不是运行时副本。

文件与该原始 ELF 放在同一目录,且在完整源文件名后追加稳定后缀:`<ELF>.disassembly`、`<ELF>.elf-info` 和 `<ELF>.symbols`。它们不受 `--bin-dir` 影响。每次构建都会重新生成当前请求的文件并刷新本次产物登记;后来关闭某一开关不会删除磁盘上已有的对应文件。

`elf-info` 给出从 ELF 对象解析出的架构、入口地址、各 `PT_LOAD` 段(包含物理和虚拟地址),以及存在时的 `__executable_start`,并附加 `llvm-readobj` 的详细输出。若 ELF 没有需要的符号,会在输出中明确说明而不是使构建失败。

这些功能使用现有 Rust 工具链中的 LLVM 工具;若缺少它们,运行 `rustup component add llvm-tools` 安装。无需安装 `cargo-binutils` 包装器。工具缺失、工具返回非零,或输入不是可解析的 ELF 时,构建会在启动 runner 前失败。

库调用方可通过 `build::cargo_run_with_config` 为 Cargo 构建传入完整 `BuildConfig`。`build::prepare_with_config` 为两种构建系统准备运行时与分析产物,随后由调用方加载 runner 配置并运行。既有 `cargo_build` 与 `cargo_run` 使用默认分析配置。直接构造 `BuildConfig` 时添加 `artifacts: Default::default()`:

```rust
let config = BuildConfig {
    system,
    artifacts: Default::default(),
};
```

#### 自定义构建系统示例

```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 配置文件定义了虚拟机的启动参数。

```toml
# QEMU 启动参数
args = ["-machine", "virt", "-cpu", "cortex-a57", "-nographic"]

# 启用 UEFI 引导
uefi = false

# 可选:宿主镜像和传给宿主内核的命令行
initramfs = "images/host.cpio.gz"
cmdline = "console=ttyAMA0 rdinit=/init -- rescue"

# 可选兼容字段。UEFI QEMU 会自动准备所需 BIN。
to_bin = false

# 失败运行的正则表达式(用于自动检测)
fail_regex = ["panic", "error", "failed"]
```

### U-Boot 配置 (.uboot.toml)

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

```toml
# 串口设备
serial = "/dev/ttyUSB0"

# 波特率
baud_rate = "115200"

# 设备树文件(可选)
dtb_file = "tools/device_tree.dtb"

# 可选:FIT ramdisk 和 U-Boot bootargs
initramfs = "images/host.cpio.gz"
cmdline = "console=ttyS0 rdinit=/init"

# 内核加载地址(可选)
kernel_load_addr = "0x80080000"

# 板子重置命令(可选)
board_reset_cmd = "reset"

# 板子断电命令(可选)
board_power_off_cmd = "poweroff"

# 失败启动的正则表达式
fail_regex = ["Boot failed", "Error loading kernel"]

# 网络启动配置(可选)
[net]
interface = "eth0"
board_ip = "192.168.1.100"
```

`BootPayloadConfig` 的 `cmdline` 与 `initramfs` 相互独立且都可省略;它们是 QEMU、board 与 U-Boot 的顶层运行配置,不属于构建配置。`initramfs` 是宿主归档,与 Linux guest 的 initrd 分开配置。QEMU 直启仅在 AArch64/RISC-V 路径使用 `-initrd` 和 `-append`;x86 使用 UEFI ESP 中的 `EFI/BOOT/initramfs.cpio`、`cmdline.txt`,不向裸 ELF 传 Linux x86 启动协议参数。U-Boot 的 `generate_fit_image()` 将归档作为 FIT ramdisk,并在启动前设置 `bootargs`;串口命令路径暂不接受含单引号的 `cmdline`。board HTTP Boot 将归档和内核上传到同一 session,服务端记录归档大小与 SHA-256。v5 设备由服务端把兼容入口转换为 `__x86_64_efi_pe_entry` 后反向推送,cmdline 通过 EFI LoadOptions、initramfs 通过 TGOS `BootPayload` 交接;v2/v3/v4 poll 仍收到原 `httpboot_entry`。归档上限为 256 MiB,cmdline 上限为 4095 字节且仅允许可打印 ASCII 和空格。服务端仍允许 v2 loader 启动两个新字段均未配置的旧会话,遇到任一新字段则在 poll 阶段明确拒绝。实体板卡的固件和内核须实现对应交接协议。

### 有序 Shell 初始化步骤

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

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

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

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

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

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

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

U-Boot 进入 shell 时默认通过 `<INTERRUPT>` 自动识别 prompt。某些厂商 U-Boot 会给
中断提示加时间戳,例如 `=> [   2.209] <INTERRUPT>` 或
`[ 115.141] <INTERRUPT>`;ostool 会内建识别这些格式,无需额外配置。

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

### 环境变量支持

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

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

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

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

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

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

```bash
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`,其优先级低于命令行参数,高于全局配置。

`ostool board connect -b <BOARD_TYPE>` 会按类型分配任意空闲开发板;需要连接某一块具体开发板时,可以额外传入 `--board-id <BOARD_ID>`。

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

### 公网开发板认证

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

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

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

```bash
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 风格的键盘操作

#### 使用方法

```bash
# 安装
cargo install jkconfig

# 编辑配置
jkconfig -c config.toml -s config-schema.json

# 自动检测 schema
jkconfig -c config.toml
```

#### 键盘快捷键

```text
导航:
↑/↓ 或 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 等多种架构

#### 使用示例

```rust
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")
    );

// 构建镜像
let mut builder = FitImageBuilder::new();
let fit_data = builder.build(config)?;

// 保存文件
std::fs::write("image.fit", fit_data)?;
```

## 🎯 使用场景

### 1. 本地开发工作流

```bash
# 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. 远程构建和硬件测试

```bash
# 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. 高级调试场景

```bash
# 启用详细日志
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 网络启动设置

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

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

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

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

```bash
newgrp ostool
```

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

### 调试配置

```toml
[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)
- 配置文件权限是否正确

### 调试技巧

```bash
# 启用详细日志
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
```

### 权限问题解决

```bash
# 将用户添加到 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

### 开发环境设置

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

## 📄 许可证

本项目采用双重许可证:

- [MIT License](LICENSE)
- [Apache License 2.0](LICENSE)

## 🔗 相关链接

- [GitHub 仓库](https://github.com/ZR233/ostool)
- [Crates.io 包](https://crates.io/crates/ostool)
- [问题反馈](https://github.com/ZR233/ostool/issues)
- [文档 Wiki](https://github.com/ZR233/ostool/wiki)

## 🙏 致谢

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