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
18 changes: 18 additions & 0 deletions apps/starry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,24 @@ cargo xtask starry app run -t gdb-smoke --arch riscv64 \
--qemu-config qemu-riscv64-gdbserver.toml
```

## jcode

The `jcode` case is an x86_64 QEMU app workflow that downloads the jcode AI coding
agent from GitHub releases, patches the glibc-linked binary for musl compatibility
using `patchelf`, builds a glibc stub shared library, and injects everything into
the app rootfs overlay.

```bash
apps/starry/jcode/prepare_jcode_rootfs.sh
cargo xtask starry qemu \
--arch x86_64 \
--qemu-config apps/starry/jcode/qemu-x86_64.toml \
--rootfs tmp/axbuild/rootfs/rootfs-x86_64-jcode.img
```

See `jcode/README.md` for interactive usage and troubleshooting.


## Orange Pi 5 Plus UVC

The `orangepi-5-plus-uvc` case needs `/usr/bin/uvc-fps` to be installed in the
Expand Down
92 changes: 92 additions & 0 deletions apps/starry/jcode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# StarryOS jcode Example

这个目录提供在 StarryOS x86_64 QEMU 中运行 jcode(AI coding agent)的手动示例。它不是 `test-suit/starryos` 用例,也不会进入 CI;下载 jcode、glibc-to-musl 补丁、rootfs 注入都只会在用户显式执行本目录脚本时发生。

## 什么是 jcode

jcode 是一个 Rust 编写的 AI coding agent harness,采用 TUI client + background server 双进程架构,通过 Unix domain socket 通信。项目地址:<https://github.com/1jehuang/jcode>

## Host 依赖

脚本需要以下 host 工具(Debian/Ubuntu):

```bash
apt-get install -y patchelf binutils curl qemu-user-static
```

## 准备 jcode Rootfs

先在 host 侧准备本地 rootfs。脚本会自动:

1. 从 GitHub releases 下载 jcode linux-x86_64 二进制
2. 下载 Alpine minirootfs 作为 staging 环境
3. 使用 `patchelf` 将 glibc-linked 的 jcode 转换为 musl 兼容
4. 编译 glibc stub 共享库(提供 `mallopt`、`__res_init` 等 glibc-only 符号)
5. 注入 jcode 二进制、SSL 库、Kerberos 依赖到 rootfs

```bash
apps/starry/jcode/prepare_jcode_rootfs.sh
```

产物位于 `tmp/axbuild/rootfs/rootfs-x86_64-jcode.img`,是本地资产,不提交到仓库。

## 离线 Smoke 测试

验证 jcode 能在 StarryOS guest 中正常运行:

```bash
cargo xtask starry qemu \
--arch x86_64 \
--qemu-config apps/starry/jcode/qemu-x86_64.toml \
--rootfs tmp/axbuild/rootfs/rootfs-x86_64-jcode.img
```

期望输出包含:

```text
STARRY_JCODE_SMOKE_PASSED
```

## 手动交互

准备 rootfs 后,可以直接启动 QEMU 进入 StarryOS shell:

```bash
cargo xtask starry qemu \
--arch x86_64 \
--rootfs tmp/axbuild/rootfs/rootfs-x86_64-jcode.img
```

进入 `root@starry` 后:

```sh
export HOME=/root
export USER=root
export SHELL=/bin/sh
export TERM=xterm-256color
export PATH=/usr/local/bin:/usr/bin:/bin:/sbin
export JCODE_NO_AUTO_UPDATE=1

# 配置 provider(需要网络和 API key)
jcode login --provider openai-compatible

# 运行 jcode TUI
jcode
```

> **注意**:`JCODE_NO_AUTO_UPDATE=1` 必须设置。jcode 的自动更新会下载 glibc 版本的二进制,覆盖已打补丁的 musl 版本,导致 jcode 无法运行。如果误触发了自动更新,需要重新运行 `prepare_jcode_rootfs.sh`。


## 内核修复

jcode 在 StarryOS 上运行需要以下内核修复(已合入 dev 分支):

- ext4 文件系统块分配和 JBD2 superblock 修复
- EPOLLET edge-triggered epoll 竞态修复
- 非阻塞 socket waker 注册
- ARP 队列扩容(32→256,TTL 60s→300s)
- TTY 终端 ANSI CPR 和 SIGWINCH 支持

## 边界

这个 example 只声明 x86_64 QEMU 下的手动演示流程。它不覆盖 jcode TUI 在线模式、CI 测试、或其他架构上的 jcode。
5 changes: 5 additions & 0 deletions apps/starry/jcode/build-x86_64-unknown-none.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target = "x86_64-unknown-none"
env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" }
log = "Warn"
features = ["qemu"]
plat_dyn = false
40 changes: 40 additions & 0 deletions apps/starry/jcode/prebuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail

app_dir="${STARRY_APP_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
overlay_dir="${STARRY_OVERLAY_DIR:-}"
workspace="${STARRY_WORKSPACE:-$(cd "$app_dir/../../.." && pwd)}"

require_env() {
local name="$1" value="$2"
if [[ -z "$value" ]]; then
echo "error: $name is required" >&2
exit 1
fi
}

require_env STARRY_OVERLAY_DIR "$overlay_dir"

# Download, patch, and build jcode assets.
"$app_dir/prepare_jcode_assets.sh"

asset_dir="$workspace/target/jcode/assets"
for f in jcode.bin libglibc_stub.so jcode; do
[[ -f "$asset_dir/$f" ]] || { echo "error: missing asset: $f" >&2; exit 1; }
done

# Populate overlay for the app runner to inject into rootfs.
install -Dm0755 "$asset_dir/jcode.bin" "$overlay_dir/usr/lib/jcode/jcode.bin"
install -Dm0755 "$asset_dir/libglibc_stub.so" "$overlay_dir/usr/lib/jcode/libglibc_stub.so"
install -Dm0755 "$asset_dir/jcode" "$overlay_dir/usr/bin/jcode"

for f in "$asset_dir"/libssl.so* "$asset_dir"/libcrypto.so*; do
[[ -f "$f" ]] && install -Dm0755 "$f" "$overlay_dir/usr/lib/jcode/"
done

for lib in libcom_err.so.2 libgssapi_krb5.so.2 libk5crypto.so.3 \
libkeyutils.so.1 libkrb5.so.3 libkrb5support.so.0; do
[[ -f "$asset_dir/$lib" ]] && install -Dm0755 "$asset_dir/$lib" "$overlay_dir/usr/lib/"
done

echo "jcode overlay ready in $overlay_dir"
Loading