From c521e274e9a7cfad2468e0bc5e5930cabe6b9ea9 Mon Sep 17 00:00:00 2001 From: Del Wang Date: Sun, 28 Dec 2025 18:25:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=B5=8B=E8=AF=95=20?= =?UTF-8?q?runtime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/hello/Cargo.lock | 7 ++++++ apps/hello/Cargo.toml | 6 ++++++ apps/hello/src/main.rs | 9 ++++++++ apps/runtime/.gitignore | 2 ++ apps/runtime/Dockerfile | 47 +++++++++++++++++++++++++++++++++++++++++ apps/runtime/README.md | 9 ++++++++ apps/runtime/build.sh | 36 +++++++++++++++++++++++++++++++ apps/runtime/run.sh | 40 +++++++++++++++++++++++++++++++++++ apps/runtime/runtime.sh | 37 ++++++++++++++++++++++++++++++++ 9 files changed, 193 insertions(+) create mode 100644 apps/hello/Cargo.lock create mode 100644 apps/hello/Cargo.toml create mode 100644 apps/hello/src/main.rs create mode 100644 apps/runtime/.gitignore create mode 100644 apps/runtime/Dockerfile create mode 100644 apps/runtime/README.md create mode 100755 apps/runtime/build.sh create mode 100644 apps/runtime/run.sh create mode 100644 apps/runtime/runtime.sh diff --git a/apps/hello/Cargo.lock b/apps/hello/Cargo.lock new file mode 100644 index 0000000..bdfea16 --- /dev/null +++ b/apps/hello/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "hello" +version = "0.1.0" diff --git a/apps/hello/Cargo.toml b/apps/hello/Cargo.toml new file mode 100644 index 0000000..f6f3649 --- /dev/null +++ b/apps/hello/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/apps/hello/src/main.rs b/apps/hello/src/main.rs new file mode 100644 index 0000000..dfdb1fc --- /dev/null +++ b/apps/hello/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + println!("Hello from OpenWrt (ARMhf)!"); + println!("System information (via /proc/version):"); + if let Ok(version) = std::fs::read_to_string("/proc/version") { + println!("{}", version); + } else { + println!("Could not read /proc/version (running in simulation?)"); + } +} diff --git a/apps/runtime/.gitignore b/apps/runtime/.gitignore new file mode 100644 index 0000000..5230df1 --- /dev/null +++ b/apps/runtime/.gitignore @@ -0,0 +1,2 @@ +squashfs-root +root.squashfs \ No newline at end of file diff --git a/apps/runtime/Dockerfile b/apps/runtime/Dockerfile new file mode 100644 index 0000000..3562e90 --- /dev/null +++ b/apps/runtime/Dockerfile @@ -0,0 +1,47 @@ +FROM --platform=linux/amd64 ubuntu:20.04 + +ENV DEBIAN_FRONTEND=noninteractive + +# 换成阿里云源 +RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \ + sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list + +# 安装必要的依赖 +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && apt-get install -y \ + curl \ + git \ + build-essential \ + qemu-user-static \ + pkg-config \ + libssl-dev \ + xz-utils \ + squashfs-tools + +# 配置交叉编译工具链(Linaro GCC 7.5.0) +ENV PATH="/opt/toolchain/bin:${PATH}" +RUN mkdir -p /opt/toolchain && \ + curl -fSL -o toolchain.tar.xz https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz && \ + tar -xJf toolchain.tar.xz -C /opt/toolchain --strip-components=1 && \ + rm toolchain.tar.xz + +# 安装 Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +ENV PATH="/root/.cargo/bin:${PATH}" +RUN rustup target add armv7-unknown-linux-gnueabihf + +# 配置 Cargo +ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc +ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUSTFLAGS="-C link-arg=-Wl,-dynamic-linker,/lib/ld-linux-armhf.so.3" + +# 设置 CC +ENV CC_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc + +WORKDIR /app + +COPY run.sh /usr/local/bin/run +COPY runtime.sh /usr/local/bin/runtime +RUN chmod +x /usr/local/bin/run /usr/local/bin/runtime + +CMD ["/bin/bash"] diff --git a/apps/runtime/README.md b/apps/runtime/README.md new file mode 100644 index 0000000..15c7fac --- /dev/null +++ b/apps/runtime/README.md @@ -0,0 +1,9 @@ +# Open-XiaoAI Runtime(OH2P v1.58.1) + +```bash +root@OH2P:~# uname -a +Linux OH2P 4.9.61 #1 SMP PREEMPT Fri Jun 27 06:11:47 2025 aarch64 GNU/Linux + +root@OH2P:~# file /lib/libc-2.25.so +app/runtime/squashfs-root/lib/libc-2.25.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, stripped +``` diff --git a/apps/runtime/build.sh b/apps/runtime/build.sh new file mode 100755 index 0000000..b4672ab --- /dev/null +++ b/apps/runtime/build.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +# 在 macOS 上,使用 host.docker.internal 访问宿主机的代理端口 +# 如果你的代理软件没有开启 "Allow LAN"(允许局域网连接),请确保它监听的是 0.0.0.0 而不仅仅是 127.0.0.1 +PROXY="http://host.docker.internal:7890" + +# 1. 构建编译环境镜像 +# echo "Building Docker image with proxy..." +# docker build \ +# --build-arg http_proxy=$PROXY \ +# --build-arg https_proxy=$PROXY \ +# -t open-xiaoai-runtime . + +# # 2. 编译 hello world demo +echo "Compiling hello demo..." +rm -rf ../hello/target # 先清理旧的构建产物,防止缓存干扰 +docker run --rm -v $(pwd)/../hello:/app/hello open-xiaoai-runtime \ + cargo build --manifest-path hello/Cargo.toml --target armv7-unknown-linux-gnueabihf --release + +# # 3. 运行编译出的二进制文件 (通过 QEMU 模拟) +echo "Running compiled binary via QEMU..." +docker run --rm -v $(pwd)/../hello/target/armv7-unknown-linux-gnueabihf/release/hello:/app/hello \ + -v $(pwd)/root.squashfs:/app/root.squashfs open-xiaoai-runtime \ + run /app/hello + +# 4. 交互模式运行 +# docker run --rm -it --privileged \ +# -v $(pwd)/root.squashfs:/app/root.squashfs \ +# open-xiaoai-runtime \ +# run + +# 5. 上传二进制文件到小爱音箱 +# dd if=target/armv7-unknown-linux-gnueabihf/release/hello \ +# | ssh -o HostKeyAlgorithms=+ssh-rsa root@192.168.31.235 "dd of=/data/hello" +# ssh -o HostKeyAlgorithms=+ssh-rsa root@192.168.31.235 "dd if=/data/hello" | hello \ No newline at end of file diff --git a/apps/runtime/run.sh b/apps/runtime/run.sh new file mode 100644 index 0000000..78cda98 --- /dev/null +++ b/apps/runtime/run.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +set -e + +# 定义 sysroot 目录 +SYSROOT_DIR="/opt/sysroot" + +# 如果 /opt/sysroot 已经有内容(通过 -v 挂载了 squashfs-root),则跳过解压 +if [ -d "$SYSROOT_DIR/bin" ] || [ -d "$SYSROOT_DIR/lib" ]; then + echo "Using existing sysroot at $SYSROOT_DIR" +else + mkdir -p "$SYSROOT_DIR" + # 优先使用环境变量指定的 squashfs 文件,否则使用默认的 root.squashfs + ROOTFS_FILE="${SYSROOT_FILE:-root.squashfs}" + + if [ -f "$ROOTFS_FILE" ]; then + echo -e "\n🔥 Unsquashing $ROOTFS_FILE to $SYSROOT_DIR...\n" + unsquashfs -d "$SYSROOT_DIR" -f "$ROOTFS_FILE" + echo -e "\n✅ Unsquashed rootfs\n" + else + echo "Error: Sysroot file $ROOTFS_FILE not found and $SYSROOT_DIR is empty." + exit 1 + fi +fi + +# 检查第一个参数。如果在 sysroot 下存在该文件,则自动补全路径 +# 比如 `run /bin/sh` 会被转换为 `run /opt/sysroot/bin/sh` +if [ -n "$1" ] && [ -f "$SYSROOT_DIR$1" ]; then + CMD="$SYSROOT_DIR$1" + shift + set -- "$CMD" "$@" +fi + + +if [ $# -eq 0 ]; then + # 如果没有提供参数,则默认在 sysroot 中启动 shell + exec runtime +else + exec qemu-arm-static -L "$SYSROOT_DIR" "$@" +fi diff --git a/apps/runtime/runtime.sh b/apps/runtime/runtime.sh new file mode 100644 index 0000000..385b76f --- /dev/null +++ b/apps/runtime/runtime.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +SYSROOT="/opt/sysroot" +QEMU_BIN="/usr/bin/qemu-arm-static" + + +echo "正在准备 OpenWrt 模拟环境..." + +# 1. 拷贝 QEMU 静态二进制文件 +cp "$QEMU_BIN" "$SYSROOT/usr/bin/" + +# 2. 挂载必要文件系统 +mount_fs() { + for dir in proc sys dev dev/pts tmp; do + mkdir -p "$SYSROOT/$dir" + if ! mountpoint -q "$SYSROOT/$dir"; then + if [[ "$dir" == "proc" ]]; then + mount -t proc proc "$SYSROOT/$dir" + elif [[ "$dir" == "sys" ]]; then + mount -t sysfs sysfs "$SYSROOT/$dir" + else + mount --bind "/$dir" "$SYSROOT/$dir" + fi + fi + done +} + +mount_fs + + +# 3. 执行进入命令 +# 注意:OpenWrt 默认没有 bash,通常使用 /bin/sh (busybox) +echo "------------------------------------------------" +echo "成功进入 OpenWrt 环境。输入 'exit' 退出。" +echo "------------------------------------------------" + +chroot "$SYSROOT" /usr/bin/$(basename $QEMU_BIN) /bin/sh \ No newline at end of file