01 / THE SIGNAL

我们发现了什么

# qh — 面向 AI 代理(和人类)的 QEMU 测试框架 在几秒钟内启动一个裸内核镜像(或现成的 Alpine 镜像),通过内置的桥接代理与其通信(类似于 qemu-guest-agent,但更轻量且与内核无关),获得网络功能,并在不到一秒的时间内重建根文件系统。标题:GitHub - b3s3da/qemu-harness:面向 AI 代理的 QEMU 测试框架:几秒钟内启动 aarch64/arm/riscv64/x86_64 内核,通过 guest agent 执

  • 来源:GitHub(发现于 2026-10-06)
  • 证据等级:D · 发现产品或需求信号,暂未获得可核验的商业证据。
  • 商业模式:待核验
  • 主题:独立产品
  • 初筛评分:15.1/100 · 收录 1 次
#独立开发#待验证#产品发现
02 / SOURCE & EVIDENCE

证据,比故事更重要。

发现产品或需求信号,暂未获得可核验的商业证据。

规则清洗与初筛,未经人工商业核验。原文语境、实际客户和付费情况仍需自行验证。

引用与数字披露

来源类型(原作者自述/第三方测算/媒体转引)需采集端标注,本版尚未落字段。

短句引用
作者
未标注
抓取日期
来源类型
未标注
数字口径
币种
未标注
口径
未标注
披露主体
未标注
披露日期
未标注

中文辅助译文(全文)

qh — 一个面向 AI 代理(以及人类)的 QEMU 测试工具

在几秒内启动一个裸内核镜像(或现成的 Alpine 镜像),通过虚拟机内部桥接代理与其通信 (可以理解为 qemu-guest-agent,但更小巧且不依赖于特定内核),获得网络连接,并在不到一秒内重建根文件系统。 专为 IoT / 嵌入式内核仿真 而构建:支持 aarch64、arm32、riscv64 和 x86_64 客户机,可使用你指定的任何 machine/DTB/cmdline。

  • qh up → 虚拟机就绪(代理响应中)约需 2–5 秒,qh exec 'cmd' → 以 JSON 形式返回 stdout/stderr/exit code。
  • Rootfs = Alpine 用户空间 + 你的 overlay 目录,在主机上打包成 initramfs 耗时约 0.3 秒(qh reload)。无需 root 权限,无需 WSL,无需挂载。
  • 兼容没有 virtio-net 的标准内核:代理将以太网帧通过串行通道隧道传输到 QEMU 的用户模式网络。
  • 内置一个 skill(skill/SKILL.md),以便 Claude Code / Grok 或任何支持 SKILL.md 的代理知道如何驱动它。
  • 以 Windows 优先(在 Windows 10 + QEMU 11 上测试通过),主机端仅使用 Python 标准库,Go 仅用于交叉编译客户机代理。Linux/macOS 也可使用。

快速开始

Windows - 一行命令(下载测试工具到 ~\tools\qemu-harness,提示通过 winget 安装 Python / QEMU / Go, 构建客户机代理,将 qh 添加到你的 PATH,为 Claude Code 和 Grok 安装代理 skill):

irm https://raw.githubusercontent.com/b3s3da/qemu-harness/main/install.ps1 | iex

选项(-Yes = 永不询问,-Arch all,-Dir,-NoDeps,-NoPath,-NoSkills,-Smoke):

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/b3s3da/qemu-harness/main/install.ps1))) -Yes -Arch all -Smoke

将脚本通过管道传给 iex 会以不可见的方式执行——如果你愿意,可以克隆仓库(或下载 install.ps1),阅读其内容,然后运行 .\install.ps1。 Linux / macOS:git clone ... && ./install.sh(需要 Python 3、qemu-system-*、Go)。

然后,在任何项目文件夹中(先打开一个新的终端,以便 PATH 生效):

mkdir lab ; cd lab
qh up --kernel alpine:aarch64 # or --kernel path\to\Image
qh exec 'uname -a; ip -4 -o a show eth0'
qh down

要求:Python >= 3.8,QEMU(qemu-system-<arch> 在 PATH 上或位于 C:\Program Files\qemu),Go >= 1.22(用于 qh setup),首次运行需要联网。 安装程序是幂等的:重新运行它会原地更新测试工具并保留 cache/。

命令

命令功能
`qh setup [--arch A\all]`获取 Alpine 微型 rootfs,构建客户机代理(缓存在 cache/<arch>)
qh up [--kernel K] [-n NAME]构建 initramfs,启动,等待代理
qh exec [--json] [--timeout N] [--bg] CMD…在客户机中运行;传递 exit code;支持 --cwd、-e K=V、--stdin、--argv
qh put SRC DST / qh get SRC DST复制文件或目录(在线使用 zlib 压缩;请保持文件较小,参见性能说明)
qh reload [任何虚拟机选项]重建 rootfs 并使用相同端口重新启动;kernel/dtb/mem/cmdline 可更改
qh fwd HOST:GUEST在运行时添加主机→客户机的 TCP 转发(0 = 选择空闲的主机端口)
qh logs [-f] [--tail N] / qh console --send CMD串行控制台日志 / 与其交互
qh probe [--kernel K]内核支持的功能以及 qh 会选择的传输方式
qh dtb -o m.dtb转储 QEMU 生成的设备树(已打包),使用 dtc 编辑,通过 --dtb 回传
`qh kernel fetch ARCH [virt\lts]`下载 Alpine 内核及 virtio/tun/9p 模块
qh up --dry-run打印准确的 QEMU 命令行
qh ls / down / rm / qmp CMD生命周期与原始 QMP

所有命令都支持 --json。状态保存在你执行命令所在目录的 ./.qh/<name>/ 中(支持多个虚拟机:-n NAME)。

配置(项目中的 qh.json,回退到 qh.example.json)

{ "kernel": "alpine:aarch64", "mem": "512M", "smp": 2, "fs": ["fs"], "pkgs": ["dropbear", "mosquitto"], "fwd": ["2222:22"] }

每个键都有对应的 CLI 标志(--arch --kernel --initrd --bios --machine --cpu --mem --smp --dtb --disk --append --net --fs --pkg --fwd --chan --nic --bus --chan-tty --qemu-arg)。 kernel 也可以是 alpine:<arch>[:virt|lts]。

自定义你的客户机

Overlay:fs 中列出的目录下的所有文件都会被复制到 Alpine rootfs 之上(后出现的覆盖先出现的)。可以将固件、配置、服务放在那里。 可执行位会被推断(#!、ELF、bin/、sbin/)。fs/etc/qh.d/rc.local 在虚拟机被声明为就绪之前运行;cmdline 上的 qh.init=/path 会运行一个钩子。 软件包:pkgs 中的名称会根据 Alpine 的索引解析(包含依赖),并在主机上解包——无需 apk。 内核模块:提供一个完整的树(lib/modules/<ver>/modules.dep,未压缩的 .ko),init 时通过 modprobe 加载 virtio/tun/9p;零散的 `.ko + modules.order 通过 insmod` 加载。 * 自带的 overlay 会启动 dropbear(root,空密码——仅限实验环境!)、mosquitto 和 httpd。

工作原理

qh CLI ──tcp──► per-VM daemon ──tcp──► QEMU chardev ══ virtio-serial / PCI-UART / spare UART ══► qh-agent (Go, in guest)
│ │ exec/put/get
└─ ethernet frames ◄──► QEMU "stream" netdev ─ hub ─ slirp (10.0.2.0/24, DNS, hostfwd) ◄── tap eth0 (if no virtio-net)

qh 读取内核内嵌的配置(/proc/config.gz)或 <kernel>.config,并选择最佳传输方式:如果存在 virtio-console + virtio-net(PCI 或 MMIO),则使用它们;否则使用内置的 8250-PCI UART(或通过 --chan serial --chan-tty 指定的备用板载 UART),并在客户机中使用 tap 设备。 处理没有 devtmpfs 的内核(mdev -s)。线协议使用 JSON 行(agent/main.go),以太网帧使用 F<base64> 行。

性能说明

使用 virtio-net(Alpine 内核,大多数发行版内核)时,网络速度正常。在标准的 Android GKI 镜像上(无 NIC 驱动,virtio 作为模块),隧道提供约 15 KB/s 写入客户机、75 KB/s 读出的速度——对于脚本、MQTT、HTTP 探测足够;将大型负载放在 fs/ 中并使用 qh reload。

故障排除

  • 代理未响应:qh logs --tail 80,然后 qh probe。既无 virtio-console 也无 8250-PCI 的内核需要 --chan serial --chan-tty /dev/ttyXX,或 --initrd X --no-wait + qh console。
  • Git Bash 会将 /tmp/x 参数改写为 Windows 路径——设置 MSYS_NO_PATHCONV=1。
  • 无闪烁的控制台窗口:QEMU 和守护进程使用 CREATE_NO_WINDOW 启动。
  • aarch64/arm/riscv64 在 x86 主机上以 TCG 运行(稍慢但可用);在匹配的架构主机上,QEMU 可以使用 --qemu-arg "-accel whpx" / KVM。

许可证

GPL-3.0-or-later — 参见 LICENSE。客户机用户空间为 Alpine Linux(在安装时下载,每个软件包有各自的许可证)。

译文由上游机器翻译生成,可能有误;判断请以英文原文为准。

英文原文(来源本站未改写)

qh — a QEMU harness for AI agents (and humans)

Boot a bare kernel image (or a ready-made Alpine one) in seconds, talk to it through an in-guest bridge agent (think qemu-guest-agent, but tiny and kernel-agnostic), get networking, and rebuild the root filesystem in a fraction of a second. Built for IoT / embedded kernel emulation: aarch64, arm32, riscv64 and x86_64 guests, any machine/DTB/cmdline you throw at it.

  • qh up → VM ready (agent answering) in ~2–5 s, qh exec 'cmd' → stdout/stderr/exit code as JSON.
  • Rootfs = Alpine userland + your overlay dirs, packed into an initramfs on the host in ~0.3 s (qh reload). No root, no WSL, no mounts.
  • Works with stock kernels that have no virtio-net: the agent tunnels ethernet over a serial channel into QEMU's user-mode network.
  • Ships a skill (skill/SKILL.md) so Claude Code / Grok / any SKILL.md-aware agent knows how to drive it.
  • Windows-first (tested on Windows 10 + QEMU 11), pure Python stdlib on the host, Go only to cross-build the guest agent. Linux/macOS work too.

Quick start

Windows - one line (downloads the harness to ~ ools\qemu-harness, offers to install Python / QEMU / Go via winget, builds the guest agent, adds qh to your PATH, installs the agent skill for Claude Code and Grok):

irm https://raw.githubusercontent.com/b3s3da/qemu-harness/main/install.ps1 | iex

Options (-Yes = never ask, -Arch all, -Dir, -NoDeps, -NoPath, -NoSkills, -Smoke):

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/b3s3da/qemu-harness/main/install.ps1))) -Yes -Arch all -Smoke

Piping a script into iex runs it unseen - if you prefer, clone the repo (or download install.ps1), read it, and run .\install.ps1. Linux / macOS: git clone ... && ./install.sh (needs Python 3, qemu-system-*, Go).

Then, in any project folder (open a new terminal first so PATH is picked up):

mkdir lab ; cd lab
qh up --kernel alpine:aarch64          # or --kernel path	o\Image
qh exec 'uname -a; ip -4 -o a show eth0'
qh down

Requirements: Python >= 3.8, QEMU (qemu-system-<arch> on PATH or C:\Program Files\qemu), Go >= 1.22 (for qh setup), internet for the first run. The installer is idempotent: re-running it updates the harness in place and keeps cache/.

Commands

commandwhat it does
`qh setup [--arch A\all]`fetch Alpine minirootfs, build the guest agent (cached in cache/<arch>)
qh up [--kernel K] [-n NAME]build initramfs, boot, wait for the agent
qh exec [--json] [--timeout N] [--bg] CMD…run in the guest; exit code propagated; --cwd, -e K=V, --stdin, --argv
qh put SRC DST / qh get SRC DSTcopy files or dirs (zlib on the wire; keep them small, see Performance)
qh reload [any VM option]rebuild rootfs and relaunch with the same ports; kernel/dtb/mem/cmdline may change
qh fwd HOST:GUESTadd a host→guest TCP forward at runtime (0 = pick a free host port)
qh logs [-f] [--tail N] / qh console --send CMDserial console log / talk to it
qh probe [--kernel K]what the kernel supports and which transports qh would pick
qh dtb -o m.dtbdump QEMU's generated device tree (packed), edit with dtc, feed back with --dtb
`qh kernel fetch ARCH [virt\lts]`download an Alpine kernel + virtio/tun/9p modules
qh up --dry-runprint the exact QEMU command line
qh ls / down / rm / qmp CMDlifecycle and raw QMP

Everything takes --json. State lives in ./.qh/<name>/ of the directory you run in (several VMs: -n NAME).

Configuration (qh.json in your project, falls back to qh.example.json)

{ "kernel": "alpine:aarch64", "mem": "512M", "smp": 2, "fs": ["fs"], "pkgs": ["dropbear", "mosquitto"], "fwd": ["2222:22"] }

Every key has a CLI flag (--arch --kernel --initrd --bios --machine --cpu --mem --smp --dtb --disk --append --net --fs --pkg --fwd --chan --nic --bus --chan-tty --qemu-arg). kernel may also be alpine:<arch>[:virt|lts].

Making the guest yours

  • Overlay: everything under the directories listed in fs is copied over the Alpine rootfs (later wins).Put firmware, configs, services there.Executable bits are inferred (#!, ELF, bin/, sbin/). fs/etc/qh.d/rc.local runs before the VM is declared ready;qh.init=/path on the cmdline runs a hook.
  • Packages: names in pkgs are resolved against Alpine's index (deps included) and unpacked on the host — no apk needed.
  • Kernel modules: ship a full tree (lib/modules/<ver>/modules.dep, uncompressed .ko) and init modprobes virtio/tun/9p;loose *.ko + modules.order are insmoded.
  • The bundled overlay starts dropbear (root, empty password — lab only!

), mosquitto, and httpd.

How it works

 qh CLI ──tcp──► per-VM daemon ──tcp──► QEMU chardev ══ virtio-serial / PCI-UART / spare UART ══► qh-agent (Go, in guest)
                    │                                                                                │ exec/put/get
                    └─ ethernet frames ◄──► QEMU "stream" netdev ─ hub ─ slirp (10.0.2.0/24, DNS, hostfwd) ◄── tap eth0 (if no virtio-net)

qh reads the kernel's embedded config (/proc/config.gz) or <kernel>.config and picks the best transport: virtio-console + virtio-net (PCI or MMIO) when present; otherwise the built-in 8250-PCI UART (or a spare board UART via --chan serial --chan-tty) with a tap device in the guest. Kernels without devtmpfs are handled (mdev -s). The wire protocol is JSON lines (agent/main.go), ethernet frames are F<base64> lines.

Performance notes

With virtio-net (Alpine kernels, most distro kernels) the network is normal speed. On a stock Android GKI image (no NIC drivers, virtio as modules) the tunnel gives roughly 15 KB/s into the guest and 75 KB/s out — fine for scripts, MQTT, HTTP probes; put big payloads in fs/ and qh reload instead.

Troubleshooting

  • agent did not respond: qh logs --tail 80, then qh probe. A kernel with neither virtio-console nor 8250-PCI needs --chan serial --chan-tty /dev/ttyXX, or --initrd X --no-wait + qh console.
  • Git Bash rewrites /tmp/x arguments into Windows paths — set MSYS_NO_PATHCONV=1.
  • No flashing console windows: QEMU and the daemon start with CREATE_NO_WINDOW.
  • aarch64/arm/riscv64 run under TCG on x86 hosts (slow-ish but fine); on a matching host QEMU may use --qemu-arg "-accel whpx" / KVM.

License

GPL-3.0-or-later — see LICENSE. The guest userland is Alpine Linux (downloaded at setup time, own licenses per package).

出处https://github.com/b3s3da/qemu-harness抓取日期 · 采集源 GitHub

03 / EVIDENCE GAPS

这条还缺什么证据?

下面每条都由本条已有字段推出(等级、理由、商业模式、来源次数、是否演示), 本站不生成推测性结论;通用验证方法放在方法论页。

  • 可核验的收入或付费证据查官网定价页与付费口径;第三方数据源(如 GetLatka)只作旁证,需标注来源与时点。
  • 商业模式未定确认按席位/按用量/授权还是开源托管版收费;开源项目另查 LICENSE 与是否存在付费版。
  • 只有单一来源找一手站点或其他渠道是否重复出现同一产品;社区热帖数量不等于商业进展。

通用验证清单(谁有这个问题/谁愿意付费/一个人能交付哪一小步)见我们的筛选方法。

04 / SIGNAL HISTORY

发现时间线