Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,34 @@
- `arch-platform-porting`: project-local skill at `.claude/skills/arch-platform-porting/SKILL.md`
- Use `arch-platform-porting` when the user wants to add, adapt, debug, or review architecture/platform support for ArceOS, StarryOS, Axvisor, someboot, dynamic UEFI platform boot, SMP startup, QEMU boot configs, target JSON files, axbuild arch mapping, axcpu trap/context code, axplat-dyn, somehal, or LoongArch/x86/aarch64/riscv platform bring-up issues.

## Rust Coding Standards

- Use the pinned Rust 2024 nightly toolchain and the repository rustfmt configuration as the formatting source of truth; do not restate rustfmt-owned layout rules in prose.
- Prefer `#![no_std]` for reusable kernel, component, memory, virtualization, and portable driver crates; add `alloc`, `std`, or feature-gated support only where the crate boundary requires it.
- Keep crate and module boundaries aligned with TGOSKits layers: reusable logic belongs in `components/`, `drivers/`, `memory/`, or `virtualization/`; OS glue belongs near the consuming ArceOS, StarryOS, Axvisor, or platform layer.
- Keep modules domain-focused. Use private implementation modules by default, expose only intentional public surfaces, and re-export stable entry points from `lib.rs` when that improves the public API.
- Name items by their domain invariant, such as address space, IRQ line, VM, device, queue, request, page, frame, capability, or error condition. Avoid generic names like `data`, `info`, `mgr`, or `handle` when a stronger project concept is known.
- Prefer small functions that perform one state transition, hardware operation, syscall step, validation step, or conversion. Split probe/map/register/enable flows into named phases when each phase has distinct invariants or failure handling.
- Make mutation and side effects visible through `&mut`, returned values, typed state transitions, or clearly named APIs. Avoid boolean-heavy control flags when separate functions, enums, or configuration structs express the intent better.
- Prefer typed IDs, newtypes, `repr(transparent)` wrappers, const constructors, operation enums, and bitflags over raw `usize`, strings, or loosely related parameters.
- Separate plain data from behavior-owning objects. Configuration, descriptors, and wire-format data may expose fields; types that own invariants, resources, locks, or hardware state should keep representation private and expose intent-revealing methods.
- Split large objects by reason to change and by owned invariant. Prefer separate types for immutable configuration, validated descriptors, mutable runtime state, queues, IRQ endpoints, capability handles, and OS adapters when those parts have different lifetimes or synchronization rules.
- Use traits as small capability boundaries, not inheritance hierarchies. Expose the capability the consumer needs, and prefer extension traits, adapter types, or feature-gated APIs over growing a central trait for optional behavior.
- Prefer composition over inheritance-shaped designs. Build larger services from named parts such as control ports, queues, backends, allocators, registries, and adapters; use concrete fields or generics for static composition and trait objects only at dynamic capability or plugin boundaries.
- Do not force callers to reach through nested objects to perform work. Keep internal parts private when they are implementation details, and expose small methods that express the boundary action, state transition, or query the caller actually needs.
- Keep driver cores independent from OS runtime glue. MMIO, DMA, IRQ, queue, wake, poll, and task-scheduling contracts should cross explicit capability boundaries such as `mmio-api`, `dma-api`, `rdif-*`, or runtime adapter layers.
- Use workspace package names and `[workspace.dependencies]` where available. Prefer workspace metadata, disable default features for `no_std` dependencies unless required, and avoid ad hoc git/path/registry overrides.
- Library and domain crates should expose typed errors that callers can match and translate. Prefer `thiserror` for nontrivial error enums when the dependency is acceptable; tiny or dependency-sensitive crates may implement `Display` and `core::error::Error` manually.
- Host-side `bin` and tool crates should use `anyhow::Result`, `Context`, `anyhow!`, and `bail!` for top-level orchestration and human-facing error reports. Do not leak `anyhow::Error` into reusable library APIs; translate typed domain errors to `ax_errno::{AxError, AxResult}` at ArceOS or kernel integration boundaries.
- Return explicit unsupported or error variants for unimplemented platform, firmware, hardware, guest, user-memory, filesystem, and network paths. Do not silently fall back, guess a default device/IRQ/address, or stringify structured metadata when callers need to make a decision.
- Use `unwrap`, `expect`, and `panic` only in tests, impossible-state assertions, one-time initialization failures, or documented invariants. Recoverable runtime failures should return `Result` or `Option` with enough context for translation or retry.
- Keep `unsafe` blocks as small as practical and place checked preconditions next to them. Every `unsafe fn` or `unsafe trait` needs a `# Safety` contract; every nontrivial `unsafe` block or `unsafe impl` should document pointer validity, aliasing, MMIO/DMA ownership, user-memory access, interrupt context, or lifetime assumptions.
- For concurrency, choose repo primitives deliberately: sleepable locks for sleepable paths, IRQ-aware or non-sleeping locks for interrupt and scheduler-sensitive paths, and narrow critical sections. Document lock ordering when a module owns multiple locks, and avoid wake/notify callbacks while holding broad locks.
- Use atomics with explicit publish/observe reasoning. Prefer Acquire/Release/AcqRel for synchronization; use `Relaxed` only for counters or proven non-synchronizing state, with the synchronization path documented where it is not obvious.
- Comments should explain invariants, safety contracts, protocol steps, hardware quirks, concurrency ordering, or non-obvious tradeoffs; do not restate the code. Public APIs and shared code comments should be in English.
- Remove duplicated knowledge, not every repeated line. Centralize protocol constants, layout rules, error conversions, and boundary invariants, but avoid premature abstractions that hide control flow or make call sites harder to audit.
- Refactor in small verified steps. Keep behavior stable unless the change intentionally updates semantics, and pair risky refactors with the lowest-layer deterministic regression or validation that can catch a breakage.

## Other Requirements

- When changing logic, run a relevant `cargo clippy` check after the code change.
Expand Down
109 changes: 1 addition & 108 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,108 +1 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Repository Overview

TGOSKits is a monorepo workspace for OS and virtualization development, containing three systems that share a common component layer:

- **ArceOS** (`os/arceos/`) — modular unikernel kernel; provides HAL, scheduling, networking, filesystem, memory management
- **StarryOS** (`os/StarryOS/`) — Linux-compatible OS built on ArceOS modules; adds syscalls, process management, signals
- **Axvisor** (`os/axvisor/`) — type-1 hypervisor built on ArceOS; adds vCPU/VM management, guest image loading

Dependency flow: `components/` + `drivers/` → ArceOS modules → StarryOS / Axvisor

## Build System

All builds, runs, and tests go through `cargo xtask` (implemented in `scripts/axbuild/`).

### Common Commands

```bash
# ArceOS
cargo xtask arceos qemu --package arceos-helloworld --arch aarch64
cargo xtask arceos build --package arceos-helloworld --arch riscv64

# StarryOS (prepare rootfs once first)
cargo xtask starry rootfs --arch aarch64
cargo xtask starry qemu --arch aarch64

# Axvisor
cargo xtask axvisor qemu --arch aarch64

# Linting
cargo xtask clippy # all workspace crates, no-deps by default; prints timing
cargo xtask clippy --package <crate> # specific crate
cargo xtask clippy --since <git-ref> # only changed crates
cargo xtask clippy --all # all workspace crates
cargo xtask sync-lint --since <git-ref> # check suspicious Relaxed atomic ordering

# Formatting
cargo fmt --all -- --check
cargo fmt --all

# Host std tests
cargo xtask test # runs against scripts/test/std_crates.csv whitelist

# Board management
cargo xtask board ls
cargo xtask board connect -b <board-type>
```

Supported architectures: `aarch64`, `riscv64`, `x86_64`, `loongarch64`

### Cargo Aliases (`.cargo/config.toml`)

`cargo arceos`, `cargo starry`, `cargo axvisor`, `cargo board` are shortcuts for the xtask subcommands.

## Toolchain

- Rust nightly-2026-04-27, edition 2024, resolver v3 (see `rust-toolchain.toml`)
- Targets: `x86_64-unknown-none`, `riscv64gc-unknown-none-elf`, `aarch64-unknown-none-softfloat`, `loongarch64-unknown-none-softfloat`
- Container image: `ghcr.io/rcore-os/tgoskits-container:latest`

## Code Style

`rustfmt.toml` enforces: `group_imports = "StdExternalCrate"`, `imports_granularity = "Crate"`, `format_strings = true`, `use_field_init_shorthand = true`.

## Architecture

### Components (`components/`)

Reusable `#![no_std]` crates shared across all three OSes: `axplat` (platform trait framework), `axcpu`, `memory_addr`/`memory_set`, `page_table_multiarch`, `percpu`, `kspin`, `kernel_guard`, `axerrno`, `axio`, `crate_interface`, `starry-process`/`starry-signal`/`starry-vm`, virtualization primitives (`axvcpu`, `axvm`, `axvisor_api`, arch-specific vcpu/vgic).

### Drivers (`drivers/`)

Organized by device type: `blk/`, `net/`, `pci/`, `intc/`, `serial/`, `usb/`, `soc/`, `npu/`, `tpu/`.

**Four-layer cross-kernel model:**
1. **Driver Core** (`drivers/<type>/<crate>/src/`) — OS-independent, `#![no_std]`, registers and state machines only
2. **Capability Boundary** — small trait objects: `mmio_api::MmioOp`, `dma_api::DmaOp`
3. **OS Glue** (`platform/axplat-dyn/src/drivers/`) — FDT/PCI probe, MMIO mapping, IRQ registration
4. **Runtime** — blocking/poll/future wrappers

**rdif traits** (`drivers/interface/rdif-*`) define per-device-class interfaces. **rdrive** (`drivers/rdrive/`) is the dynamic driver management framework with priority-sorted two-phase probing and PID-aware device locking.

### Platform (`platform/`)

Board-level platform crates: `axplat-dyn` (dynamic dispatch), `somehal`, and RISC-V / LoongArch static board packages; RISC-V QEMU, x86_64 QEMU, and Axvisor x86_64 use the dynamic platform path.

## CI

- **fmt**: `cargo fmt --all -- --check`
- **clippy**: `cargo xtask clippy --since <base>` (incremental for PRs; prints start, finish, and elapsed time)
- **sync-lint**: `cargo xtask sync-lint --since <base>`
- **std tests**: `cargo xtask test`
- **QEMU tests**: ArceOS/StarryOS/Axvisor across all 4 architectures
- **Board tests**: self-hosted runners for OrangePi-5-Plus, RDK-S100
- Std test crate list: `scripts/test/std_crates.csv`

## Conventions

- PR titles: Conventional Commits `type(scope): content`, e.g. `feat(axbuild): add board test flow`, `fix(starry-process): correct tty cleanup`
- PR titles in English, bodies in Chinese
- For any PR review, fully read (完整阅读) `.claude/skills/review-single-pr/SKILL.md` first; `AGENTS.md` and that skill are the review source of truth.
- Before deciding merge readiness, create a todo/checklist from the full `review-single-pr` requirements and verify each applicable item as satisfied, not applicable with reason, or blocking with evidence.
- Do not silence clippy warnings with `allow`; fix the root cause
- Do not add agent/AI branding or signatures to commits/PRs
- Read and strictly follow all conventions in AGENTS.md
see AGENTS.md