这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【PocketBeagle2】二,Linux系统移植,构建自己的系统

共1条 1/1 1 跳转至

【PocketBeagle2】二,Linux系统移植,构建自己的系统

菜鸟
2025-09-28 10:43:54     打赏
【PocketBeagle2】二,Linux系统移植,构建自己的系统

参考链接:Debian: Getting Started with the PocketBeagle 2 - Embedded / Linux Guides - DigiKey TechForum - An Electronic Component and Engineering Solution Forum

安装依赖

sudo apt update  \
sudo apt-get install -y build-essential git

整体流程图

image-20250928102919962.pngimage-20250928102919962

一,交叉编译工具的安装32 位 arm-linux-gnueabi-gcc
# 下载
wget -c https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.5.0/x86_64-gcc-11.5.0-nolibc-arm-linux-gnueabi.tar.xz
# 解压
tar -vxf x86_64-gcc-11.5.0-nolibc-arm-linux-gnueabi.tar.xz
# 添加环境变量
export CC32=`pwd`/gcc-11.5.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-
# 测试交叉编译器
${CC32}gcc --version

image-20250926170711544image-20250926170711544.png

64 位 arm-linux-gnueabi-gcc
# 下载
wget -c https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.5.0/x86_64-gcc-11.5.0-nolibc-aarch64-linux.tar.xz
# 解压
tar -xf x86_64-gcc-11.5.0-nolibc-aarch64-linux.tar.xz
# 添加环境变量
export CC64=`pwd`/gcc-11.5.0-nolibc/aarch64-linux/bin/aarch64-linux-
# 测试交叉编译器
${CC64}gcc --version

image-20250926174854863image-20250926174854863.png

二,TF-A编译

TF-A全称是Trusted Firmware-A,也就是可信固件-A,-A表示针对Cortex-A内核处理器,-M表示针对Cortex-M内核处理器。主要负责构建安全可信的启动环境运行时服务。它就像是嵌入式系统启动过程中一位至关重要的"安全卫士",确保从芯片上电开始,每一步都安全可靠。

详细的参考链接:TF-A(Trusted Firmware-A)及其启动流程详解:以stm32MP1平台为例-CSDN博客

下载
git clone -b lts-v2.12.3 https://github.com/TrustedFirmware-A/trusted-firmware-a.git --depth=1
构建
make -C ./trusted-firmware-a/ -j4 CROSS_COMPILE=${CC64} PLAT=k3 ARCH=aarch64 SPD=opteed TARGET_BOARD=lite K3_USART=0x6 all
参数说明
make调用 GNU Make 构建工具,根据 Makefile 规则管理编译过程。
-C ./trusted-firmware-a/指示 make 在开始工作前,先切换到 ./trusted-firmware-a/ 目录下寻找 Makefile。
-j4指定并行编译任务数为 4,即同时使用 4 个进程进行编译,能显著加快编译速度。
CROSS_COMPILE=${CC64}定义交叉编译工具链的前缀。${CC64} 是一个变量,其值可能是类似 aarch64-linux-gnu- 的字符串,用于指定编译器和工具。
PLAT=k3指定目标硬件平台为 k3,这通常指 Texas Instruments (TI) 的 Keystone 系列处理器。
ARCH=aarch64指定目标处理器架构为 AArch64,即 64 位的 ARM 架构。
SPD=opteed设定安全分区驱动程序(SPD)为 opteed,表示 BL31 将使用 OP-TEE 作为其安全世界操作系统。
TARGET_BOARD=lite指定目标开发板的具体型号或配置为 lite 版本。
K3_USART=0x6可能用于配置特定平台(K3)的调试串口(USART)编号或地址为 0x6。
all指定 Makefile 中的最终构建目标,通常是编译生成所有必要的二进制文件
三,OPTEE 编译和配置

OP-TEE(Open Portable Trusted Execution Environment)在嵌入式系统中发挥着关键作用,主要提供一个安全可信的执行环境,用于保护嵌入式系统中的关键数据和敏感信息。

依赖安装
sudo apt update  \
sudo apt-get install -y python3-cryptography python3-minimal  \
sudo apt-get install -y python3-pyelftools
下载
git clone -b 4.6.0 https://github.com/OP-TEE/optee_os.git --depth=1
构建
make -C ./optee_os/ -j4 CROSS_COMPILE=${CC32} CROSS_COMPILE64=${CC64} CFG_ARM64_core=y PLATFORM=k3-am62x CFG_WITH_SOFTWARE_PRNG=y CFG_CONSOLE_UART=0x6 all
make调用 GNU Make 构建工具,根据 Makefile 规则管理编译过程。
-C ./optee_os/指示 make 在开始工作前,先切换到 ./optee_os/ 目录下寻找 Makefile。
-j4指定并行编译任务数为 4,即同时使用 4 个进程进行编译,能显著加快编译速度。
CROSS_COMPILE=${CC32}定义 32 位(AArch32)交叉编译工具链的前缀。${CC32} 是一个变量,其值可能是类似 arm-linux-gnueabihf- 的字符串。
CROSS_COMPILE64=${CC64}定义 64 位(AArch64)交叉编译工具链的前缀。${CC64} 是一个变量,其值可能是类似 aarch64-linux-gnu- 的字符串。
CFG_ARM64_core=y指示编译目标为 64 位的 ARM 核心(AArch64)。
PLATFORM=k3-am62x指定目标硬件平台为 Texas Instruments (TI) 的 AM62x 系列处理器。
CFG_WITH_SOFTWARE_PRNG=y启用软件伪随机数生成器。这是一个重要的安全特性,用于在硬件随机数生成器不可用或不满足需求时提供随机数源。
CFG_CONSOLE_UART=0x6配置 OP-TEE 输出调试信息的串口(UART)设备编号或地址为 0x6。这个值需要与具体硬件板卡的设计相匹配。
all指定 Makefile 中的默认构建目标,即编译所有必要的组件。
四,TI Linux 固件下载源码
git clone -b 11.00.13 https://github.com/beagleboard/ti-linux-firmware.git --depth=1
五,U-Boot编译依赖安装
sudo apt update  \
sudo apt-get install -y bc bison flex libgnutls28-dev libssl-dev \
sudo apt-get install -y python3-dev python3-jsonschema  \
sudo apt-get install -y python3-setuptools python3-yaml  \
sudo apt-get install -y swig uuid-dev yamllint
下载u-boot源码
git clone -b v2025.07-am6232-pocketbeagle2 https://github.com/beagleboard/u-boot.git --depth=1
R5 核编译

R5 核的主要功能是初始化 DDR 并引导 A53 核启动。TI 的 AM62x 系列并未进行 DDR 兼容性设计。

# 配置
make -C ./u-boot/ O=../CORTEXR CROSS_COMPILE=${CC32} am6232_pocketbeagle2_r5_defconfig  
# 构建
make -C ./u-boot/ -j4 O=../CORTEXR CROSS_COMPILE=${CC32} BINMAN_INDIRS=../ti-linux-firmware/
# 复制构建产物
mkdir -p ./input/
cp -v ./CORTEXR/tiboot3-am62x-hs-fs-evm.bin ./input/
命令组成部分解释
第一条命令 (make ... defconfig)配置阶段:为特定硬件生成构建配置
make -C ./u-boot/./u-boot/ 目录中执行 make。
O=../CORTEXR将所有的编译输出文件(如 .o, .bin)都指定到 ../CORTEXR 目录,保持源码目录的干净。
CROSS_COMPILE=${CC32}指定 32 位 ARM 架构的交叉编译工具链前缀。变量 ${CC32} 可能类似于 arm-none-linux-gnueabihf-
am6232_pocketbeagle2_r5_defconfig选择针对 TI AM6232 芯片的 PocketBeagle2 板卡且运行在 Cortex-R5 核心上的默认配置文件。此命令会在输出目录生成最终的 .config 文件。
第二条命令 (make ... all)构建阶段:实际编译生成 U-Boot 镜像
make -C ./u-boot/再次在 ./u-boot/ 目录执行 make。
-j4使用 4 个并行任务进行编译,以加快速度。
O=../CORTEXR确保构建过程使用上一步在 ../CORTEXR 目录中生成的配置。
CROSS_COMPILE=${CC32}与配置阶段保持一致,使用相同的交叉编译器。
BINMAN_INDIRS=../ti-linux-firmware/告诉 U-Boot 的 binman 工具(用于打包最终镜像)去 ../ti-linux-firmware/ 目录查找可能需要的预编译固件等二进制文件。
(默认目标 all)编译并生成最终的 U-Boot 镜像文件,如 u-boot.bin
A53 核编译

TI 的 U-Boot 分为 R5 核和 A53 核两个版本

# 配置
make -C ./u-boot/ O=../CORTEXA CROSS_COMPILE=${CC64} am6232_pocketbeagle2_a53_defconfig
# 构建
make -C ./u-boot/ -j4 O=../CORTEXA CROSS_COMPILE=${CC64} BL31=../trusted-firmware-a/build/k3/lite/release/bl31.bin TEE=../optee_os/out/arm-plat-k3/core/tee-pager_v2.bin BINMAN_INDIRS=../ti-linux-firmware/
# 复制构建产物
cp -v ./CORTEXA/tispl.bin ./input/  
cp -v ./CORTEXA/u-boot.img ./input/
参数作用
-C ./u-boot/进入 u-boot 源码目录执行编译
O=../CORTEXA输出目录设为 ../CORTEXA(与 R5 核的输出分离)
CROSS_COMPILE=${CC64}指定 64 位 ARM 交叉编译器(如 aarch64-linux-gnu-
am6232_pocketbeagle2_a53_defconfig使用针对 A53 核心的默认配置(与之前的 R5 配置不同)
参数作用
-j4启用 4 线程并行编译加速
BL31=...关键! 指定 TF-A 编译生成的 bl31.bin 路径(安全监控固件)
TEE=...关键! 指定 OP-TEE 编译生成的 tee-pager_v2.bin 路径(安全执行环境)
BINMAN_INDIRS=...指定额外二进制依赖目录(如 TI 官方固件)
文件用途
tispl.binTI 专用初始引导加载程序,包含 TF-A、OP-TEE 和 U-Boot 的整合镜像
u-boot.img标准 U-Boot 镜像,通常由 tispl.bin 加载后执行
注意事项
  1. 路径一致性 BL31TEE 的路径必须与之前编译 TF-A/OP-TEE 的输出路径匹配。

  2. 环境变量 确保 ${CC64} 已正确设置为 64 位 ARM 工具链(如 export CC64=aarch64-linux-gnu-)。

  3. 依赖文件 ../ti-linux-firmware/ 目录需包含 TI 平台所需的专用固件(如 DDR 初始化代码)。

最终输出文件说明文件加载顺序功能
tispl.bin1整合了 TF-A + OP-TEE + U-Boot SPL,负责初始化 DDR、加载完整 U-Boot
u-boot.img2完整的 U-Boot,加载操作系统内核并传递控制权

这两个文件是启动链的核心,需烧录到设备的 Boot 分区


六,Linux Kernel 编译下载内核
git clone -b v6.12.43-ti-arm64-r52 https://github.com/beagleboard/linux.git
编译内核
#!/bin/bash -e
#
# 自定义内核构建脚本
# 简化版本,仅包含核心构建步骤
#

set -e  # 任何命令失败立即退出

# 基础变量设置
DIR=$(pwd)
KERNEL_DIR="${KERNEL_DIR:-$DIR/KERNEL}"  # 允许通过环境变量覆盖
DEPLOY_DIR="${DIR}/deploy"

# 默认配置(可通过环境变量覆盖)
KERNEL_ARCH="${KERNEL_ARCH:-arm64}"
CONFIG="${CONFIG:-defconfig}"
CC="${CC:-aarch64-linux-gnu-}"  # 根据你的架构调整
CORES="${CORES:-$(nproc)}"
BUILD="${BUILD:-}"

# 创建部署目录
mkdir -p "${DEPLOY_DIR}"

# 颜色输出函数
red() { echo -e "\033[31m$@\033[0m"; }
green() { echo -e "\033[32m$@\033[0m"; }
blue() { echo -e "\033[34m$@\033[0m"; }

# 检查内核目录是否存在
check_kernel_dir() {
   if [ ! -d "${KERNEL_DIR}" ]; then
       red "错误: 内核目录不存在: ${KERNEL_DIR}"
       red "请设置 KERNEL_DIR 环境变量指向你的内核源码目录"
       red "例如: export KERNEL_DIR=/path/to/your/kernel"
       exit 1
   fi
   
   if [ ! -f "${KERNEL_DIR}/Makefile" ]; then
       red "错误: ${KERNEL_DIR} 不是有效的内核源码目录"
       exit 1
   fi
   
   green "✓ 内核目录检查通过: ${KERNEL_DIR}"
}

# 步骤1: 配置内核
copy_defconfig() {
   blue "步骤1: 配置内核..."
   
   cd "${KERNEL_DIR}"
   
   # 清理之前的构建
   green "清理构建环境..."
   make ARCH=${KERNEL_ARCH} CROSS_COMPILE="${CC}" distclean || true
   
   # 应用默认配置
   green "应用默认配置: ${CONFIG}"
   make ARCH=${KERNEL_ARCH} CROSS_COMPILE="${CC}" ${CONFIG}
   
   # 更新配置
   green "更新配置..."
   make ARCH=${KERNEL_ARCH} CROSS_COMPILE="${CC}" olddefconfig
   
   cd "${DIR}"
   green "✓ 内核配置完成"
}

# 步骤2: 可选交互式配置
make_menuconfig() {
   if [ "${SKIP_MENUCONFIG}" != "1" ]; then
       blue "步骤2: 启动交互式配置界面..."
       
       cd "${KERNEL_DIR}"
       green "当前配置将启动 menuconfig 界面"
       green "按任意键继续,或 Ctrl+C 跳过..."
       read -n 1 -s
       
       make ARCH=${KERNEL_ARCH} CROSS_COMPILE="${CC}" menuconfig
       
       cd "${DIR}"
       green "✓ 交互式配置完成"
   else
       green "跳过交互式配置 (SKIP_MENUCONFIG=1)"
   fi
}

# 步骤3: 编译内核
make_kernel() {
   blue "步骤3: 编译内核、模块和设备树..."
   
   # 确定镜像类型
   if [ "${KERNEL_ARCH}" = "arm" ]; then
       image="zImage"
   else
       image="Image"
   fi
   
   cd "${KERNEL_DIR}"
   
   # 编译内核和模块
   green "编译内核镜像和模块 (使用 ${CORES} 个核心)..."
   echo "命令: make -j${CORES} ARCH=${KERNEL_ARCH} LOCALVERSION=${BUILD} CROSS_COMPILE=\"${CC}\" ${image} modules"
   make -j${CORES} ARCH=${KERNEL_ARCH} LOCALVERSION=${BUILD} CROSS_COMPILE="${CC}" ${image} modules
   
   # 编译设备树
   green "编译设备树二进制文件..."
   echo "命令: make -j${CORES} ARCH=${KERNEL_ARCH} LOCALVERSION=${BUILD} CROSS_COMPILE=\"${CC}\" dtbs"
   make -j${CORES} ARCH=${KERNEL_ARCH} LOCALVERSION=${BUILD} CROSS_COMPILE="${CC}" dtbs
   
   # 获取内核版本
   KERNEL_UTS=$(cat "${KERNEL_DIR}/include/generated/utsrelease.h" | awk '{print $3}' | sed 's/\"//g')
   green "内核版本: ${KERNEL_UTS}"
   
   # 复制内核镜像和配置到部署目录
   if [ -f "./arch/${KERNEL_ARCH}/boot/${image}" ]; then
       green "复制内核镜像到部署目录..."
       cp -v "./arch/${KERNEL_ARCH}/boot/${image}" "${DEPLOY_DIR}/${KERNEL_UTS}.${image}"
       cp -v ".config" "${DEPLOY_DIR}/config-${KERNEL_UTS}"
   else
       red "错误: 内核镜像未生成"
       exit 1
   fi
   
   cd "${DIR}"
   green "✓ 内核编译完成"
}

# 步骤4: 打包模块
make_modules_pkg() {
   blue "步骤4: 打包内核模块..."
   
   cd "${KERNEL_DIR}"
   
   # 创建临时目录
   TEMP_DIR="${DEPLOY_DIR}/tmp_modules"
   rm -rf "${TEMP_DIR}"
   mkdir -p "${TEMP_DIR}"
   
   # 安装模块到临时目录
   green "安装模块到临时目录..."
   make -s ARCH=${KERNEL_ARCH} LOCALVERSION=${BUILD} CROSS_COMPILE="${CC}" \
         modules_install INSTALL_MOD_PATH="${TEMP_DIR}"
   
   # 打包模块
   green "打包模块..."
   cd "${TEMP_DIR}"
   tar czf "${DEPLOY_DIR}/${KERNEL_UTS}-modules.tar.gz" .
   
   # 清理
   cd "${DIR}"
   rm -rf "${TEMP_DIR}"
   
   green "✓ 模块打包完成: ${DEPLOY_DIR}/${KERNEL_UTS}-modules.tar.gz"
}

# 步骤5: 打包设备树
make_dtbs_pkg() {
   blue "步骤5: 打包设备树二进制文件..."
   
   cd "${KERNEL_DIR}"
   
   # 创建临时目录
   TEMP_DIR="${DEPLOY_DIR}/tmp_dtbs"
   rm -rf "${TEMP_DIR}"
   mkdir -p "${TEMP_DIR}"
   
   # 安装设备树到临时目录
   green "安装设备树到临时目录..."
   make -s ARCH=${KERNEL_ARCH} LOCALVERSION=${BUILD} CROSS_COMPILE="${CC}" \
         dtbs_install INSTALL_DTBS_PATH="${TEMP_DIR}"
   
   # 打包设备树
   green "打包设备树..."
   cd "${TEMP_DIR}"
   tar czf "${DEPLOY_DIR}/${KERNEL_UTS}-dtbs.tar.gz" .
   
   # 清理
   cd "${DIR}"
   rm -rf "${TEMP_DIR}"
   
   green "✓ 设备树打包完成: ${DEPLOY_DIR}/${KERNEL_UTS}-dtbs.tar.gz"
}

# 显示构建信息
show_build_info() {
   blue "=========================================="
   blue "           自定义内核构建脚本"
   blue "=========================================="
   echo "内核目录: ${KERNEL_DIR}"
   echo "架构: ${KERNEL_ARCH}"
   echo "配置: ${CONFIG}"
   echo "编译器: ${CC}"
   echo "并行编译: ${CORES} 核心"
   echo "构建标签: ${BUILD}"
   echo "部署目录: ${DEPLOY_DIR}"
   blue "=========================================="
}

# 主构建流程
main() {
   show_build_info
   
   # 检查内核目录
   check_kernel_dir
   
   # 执行构建步骤
   copy_defconfig
   make_menuconfig
   make_kernel
   make_modules_pkg
   make_dtbs_pkg
   
   # 显示构建结果
   green "=========================================="
   green "           构建完成!"
   green "=========================================="
   green "生成的文件:"
   ls -lh "${DEPLOY_DIR}/${KERNEL_UTS}"*
   echo ""
   green "内核版本: ${KERNEL_UTS}"
   echo "${KERNEL_UTS}" > "${DIR}/kernel_version"
   green "版本信息已保存到: ${DIR}/kernel_version"
}

# 帮助信息
show_help() {
   echo "用法: $0 [选项]"
   echo ""
   echo "选项:"
   echo "  -h, --help          显示此帮助信息"
   echo "  -s, --skip-menuconfig  跳过交互式配置"
   echo ""
   echo "环境变量:"
   echo "  KERNEL_DIR   内核源码目录路径 (默认: ./KERNEL)"
   echo "  KERNEL_ARCH  目标架构 (默认: arm64)"
   echo "  CONFIG       内核配置 (默认: defconfig)"
   echo "  CC           交叉编译工具链前缀"
   echo "  CORES        并行编译核心数 (默认: 自动检测)"
   echo "  BUILD        构建版本标签"
   echo ""
   echo "示例:"
   echo "  $0"
   echo "  KERNEL_DIR=/path/to/kernel CONFIG=my_defconfig $0"
   echo "  $0 --skip-menuconfig"
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
   case $1 in
       -h|--help)
           show_help
           exit 0
           ;;
       -s|--skip-menuconfig)
           export SKIP_MENUCONFIG=1
           shift
           ;;
       *)
           red "未知选项: $1"
           show_help
           exit 1
           ;;
   esac
done

# 运行主函数
main
设置环境变量
export KERNEL_DIR="/home/mxz/pocketbeagle_2/sdk/linux"
export KERNEL_ARCH="arm64"
export CONFIG="defconfig"
export CORES=8
export BUILD="-custom"
export CC="/home/mxz/pocketbeagle_2/sdk/gcc-11.5.0-nolibc/aarch64-linux/bin/aarch64-linux-"
环境变量含义你的设置影响范围
KERNEL_DIR内核源码路径/home/user/linux-6.15源码位置
KERNEL_ARCH目标架构arm64CPU指令集
CONFIG配置类型defconfig功能特性
CC编译器前缀aarch64-linux-gnu-编译工具
CORES并行编译数8编译速度
BUILD版本后缀-custom版本标识
构建
./build.sh
# 最后输出内容

内核版本: 6.12.43-custom-ga59d522530aa
复制内核镜像到部署目录...
'./arch/arm64/boot/Image' -> '/home/mxz/pocketbeagle_2/sdk/linux/deploy/6.12.43-custom-ga59d522530aa.Image'
'.config' -> '/home/mxz/pocketbeagle_2/sdk/linux/deploy/config-6.12.43-custom-ga59d522530aa'
✓ 内核编译完成
步骤4: 打包内核模块...
安装模块到临时目录...
打包模块...
✓ 模块打包完成: /home/mxz/pocketbeagle_2/sdk/linux/deploy/6.12.43-custom-ga59d522530aa-modules.tar.gz
步骤5: 打包设备树二进制文件...
安装设备树到临时目录...
打包设备树...
✓ 设备树打包完成: /home/mxz/pocketbeagle_2/sdk/linux/deploy/6.12.43-custom-ga59d522530aa-dtbs.tar.gz
==========================================
          构建完成!
==========================================
生成的文件:
-rw-rw-r-- 1 mxz mxz 13M  9月 24 16:23 /home/mxz/pocketbeagle_2/sdk/linux/deploy/6.12.43-custom-ga59d522530aa-dtbs.tar.gz
-rw-rw-r-- 1 mxz mxz 46M  9月 24 16:22 /home/mxz/pocketbeagle_2/sdk/linux/deploy/6.12.43-custom-ga59d522530aa.Image
-rw-rw-r-- 1 mxz mxz 78M  9月 24 16:23 /home/mxz/pocketbeagle_2/sdk/linux/deploy/6.12.43-custom-ga59d522530aa-modules.tar.gz

内核版本: 6.12.43-custom-ga59d522530aa
版本信息已保存到: /home/mxz/pocketbeagle_2/sdk/linux/kernel_version
mxz@kone:~/pocketbeagle_2/sdk/linux$

编译命令的实际展开

# 在KERNEL_DIR目录中执行的实际命令:
make -j8 ARCH=arm64 LOCALVERSION=-custom CROSS_COMPILE=aarch64-linux-gnu- defconfig
make -j8 ARCH=arm64 LOCALVERSION=-custom CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs

生成的文件命名

# 部署目录中的文件:
deploy/
├── 6.15.0-custom.Image          # 内核镜像
├── config-6.15.0-custom         # 内核配置
├── 6.15.0-custom-modules.tar.gz # 模块包
└── 6.15.0-custom-dtbs.tar.gz    # 设备树包
本组成部分具体值含义与来源
主版本号 (A.B.C)6.12.43这是内核源码本身的版本,由 Makefile 中的 VERSIONPATCHLEVELSUBLEVEL 定义。
本地版本 (LOCALVERSION)-custom这是你的自定义标识。它来源于你设置的环境变量 BUILD="-custom",编译时通过 LOCALVERSION 变量附加到主版本号后。
自动版本后缀-ga59d522530aa这是内核构建系统自动添加的。它基于你编译时所在的 Git 提交点的缩写哈希值 (ga59d522530aa),表示你基于一个特定的代码状态进行了编译。
七,构建根文件系统下载源码
wget -c https://rcn-ee.com/rootfs/eewiki/minfs/debian-12.11-minimal-arm64-2025-05-28.tar.xz
校验
sha256sum debian-12.11-minimal-arm64-2025-05-28.tar.xz
解压
tar xf debian-12.11-minimal-arm64-2025-05-28.tar.xz


八,安装内核和根文件系统添加环境变量
export kernel_version=6.12.43-custom-ga59d522530aa
使用 genimage 创建根文件系统下载安装genimage
git clone https://github.com/pengutronix/genimage
cd genimage
./autogen.sh  && ./configure && make
sudo make install  # 安装到系统路径
创建 genimage 工作目录
sudo mkdir -p ./input/.rootfs
复制根文件系统
sudo tar xfvp ./debian-*-*-arm64-*/arm64-rootfs-*.tar -C ./input/.rootfs/
sync
启用首次启动自定义配置
sudo cp ./input/.rootfs/etc/bbb.io/templates/sysconf.txt ./input/

用文本编辑器打开./input/sysconf.txt,修改用户设置:

  • user_name=

  • user_password=

  • hostname=

sudo nano ./input/sysconf.txt
# This file will be automatically evaluated and installed at next boot
# time, and regenerated (to avoid leaking passwords and such information).
#
# To force it to be evaluated immediately, you can run (as root):
#
#     /usr/sbin/bbbio-set-sysconf
#
# You can disable the file evaluation by disabling the bbbio-set-sysconf
# service in systemd:
#
#     systemctl disable bbbio-set-sysconf
#
# Comments (all portions of a line following a '#' character) are
# ignored. This file is read line by line. Valid
# configuration lines are of the form 'key=value'. Whitespace around
# 'key' and 'value' is ignored. This file will be _regenerated_ every
# time it is evaluated.
#
# We follow the convention to indent with one space comments, and
# leave no space to indicate the line is an example that could be
# uncommented.

# root_password - Set a password for the root user (not used in ubuntu)
root_password=kone

# root_authorized_key - Set an authorized key for a root ssh login (not used in ubuntu)
#root_authorized_key=

# user_name - Set a user name for the user (1000)
user_name=kone

# user_password - Set a password for user (1000)
user_password=kone

# user_authorized_key - Set an authorized key for a user (1000) ssh login
#user_authorized_key=

# iwd_psk_file - Set a configuration for iwd https://wiki.archlinux.org/title/iwd
#iwd_psk_file=

# wifi_regdom - Country Code (ISO Alpha-2) Requests the country be set for the system.
#wifi_regdom=US

# hostapd_file - Set a configuration for hostapd https://wiki.gentoo.org/wiki/Hostapd
hostapd_file=SoftAp0.conf

# hostname - Set the system hostname.
hostname=kone

# keymap - Set the system keymap.
keymap=us

# timezone - Set the system timezone.
timezone=America/Chicago

# usb_enable_dhcp - enable usb gadget to startup in dhcp mode, useful for Win/Mac with ICS enabled
usb_enable_dhcp=yes

# enable_ufw - enable ufw firewall (https://en.wikipedia.org/wiki/Uncomplicated_Firewall)
enable_ufw=yes

# ufw_allow_ssh - allow ssh access over port 22
ufw_allow_ssh=yes

# ufw_allow_http - allow http access over port 80
ufw_allow_http=yes

# ufw_allow_https - allow https access over port 443
ufw_allow_https=yes

# ufw_allow_nodered - allow nodered access over port 1880 (https://nodered.org/)
ufw_allow_nodered=yes

# ufw_allow_vscode - allow vscode access over port 3000 (https://github.com/coder/code-server)
ufw_allow_vscode=yes

# ufw_allow_vnc - allow vnc access over port 5901
ufw_allow_vnc=yes

# ufw_allow_cockpit - allow cockpit access over port 9090 (https://cockpit-project.org/)
ufw_allow_cockpit=yes


配置 extlinux.conf
sudo sh -c "echo 'label Linux' > ./input/extlinux.conf"
sudo sh -c "echo '    kernel /Image.gz' >> ./input/extlinux.conf"
sudo sh -c "echo '    fdtdir /' >> ./input/extlinux.conf"
sudo sh -c "echo '    append console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02860000 root=/dev/mmcblk1p2 ro rootfstype=ext4 rootwait net.ifnames=0' >> ./input/extlinux.conf"
复制内核镜像
sudo cp -v ./linux/deploy/${kernel_version}.Image ./input/Image.gz
复制内核设备树二进制文件
sudo mkdir -p ./input/dtbs/
sudo tar xfv ./linux/deploy/${kernel_version}-dtbs.tar.gz -C ./input/dtbs/
sudo cp -v ./input/dtbs/ti/k3-am6232-pocketbeagle2.dtb ./input/k3-am6232-pocketbeagle2.dtb
复制内核模块
sudo tar xfv ./linux/deploy/${kernel_version}-modules.tar.gz -C ./input/.rootfs/usr/
文件系统表(/etc/fstab)
sudo sh -c "echo '/dev/mmcblk1p2  /  auto  errors=remount-ro  0  1' >> ./input/.rootfs/etc/fstab"
sudo sh -c "echo '/dev/mmcblk1p1  /boot/firmware  vfat user,uid=1000,gid=1000,defaults 0 2' >> ./input/.rootfs/etc/fstab"
检查分区大小
sudo du -sh ./input/.rootfs/
创建 rootfs.ext4
sudo dd if=/dev/zero of=./input/rootfs.ext4 bs=1 count=0 seek=1600M
sudo mkfs.ext4 -F ./input/rootfs.ext4 -d ./input/.rootfs/

image-20250926224833116image-20250926224833116.png


九,使用 genimage 创建 sdcard.img

创建 genimage.cfg 文件

nano genimage.cfg
#genimage.cfg
image boot.vfat {
       vfat {
           files = {
                   "tispl.bin",
                   "u-boot.img",
                   "Image.gz",
                   "sysconf.txt",
           }
           file tiboot3.bin {
                   image = tiboot3-am62x-hs-fs-evm.bin
           }
           file ti/k3-am6232-pocketbeagle2.dtb {
                   image = k3-am6232-pocketbeagle2.dtb
           }
           file extlinux/extlinux.conf {
                   image = extlinux.conf
           }
       }
       size = 256M
}
image sdcard.img {
       hdimage {
       }
       partition u-boot {
               partition-type = 0xC
               bootable = "true"
               image = "boot.vfat"
       }
       partition rootfs {
               partition-type = 0x83
               image = "rootfs.ext4"
       }
}
运行 genimage 生成镜像
sudo genimage --rootpath `mktemp` --config genimage.cfg

genimage 输出 sdcard.img 可通过balenaEtcher - Flash OS images to SD cards & USB drives 或其他镜像写入工具烧录到 microSD 卡。

image-20250926225430722image-20250926225430722.png

十,镜像验证

使用 growpart 扩展分区表中的分区

sudo growpart /dev/mmcblk1 2

首次重启

sudo reboot

使用 resize2fs 扩容现有文件系统

sudo resize2fs /dev/mmcblk1p2

第二次重启

sudo reboot


十一,USB_RNDIS共享网络

卸载占用 UDC 的 g_ether 驱动

# 卸载 g_ether 模块,这会释放 UDC
sudo modprobe -r g_ether

# 确认 UDC 已释放(查看服务)
cat /sys/class/udc/31000000.usb/uevent
# 应该显示 USB_UDC_DRIVER= 或者没有 USB_UDC_DRIVER 这一行

启用Gadget框架

sudo modprobe libcomposite

使用configfs创建RNDIS功能/sys/kernel/config/usb_gadget/下创建虚拟网卡

# 创建Gadget目录
mkdir -p /sys/kernel/config/usb_gadget/g1
cd /sys/kernel/config/usb_gadget/g1

# 设置USB标识符
echo "0x1d6b" > idVendor  # Linux Foundation VID
echo "0x0104" > idProduct # 示例PID

# 创建字符串描述符
mkdir -p strings/0x409
echo "1234567890" > strings/0x409/serialnumber
echo "MyBoard" > strings/0x409/manufacturer
echo "USB RNDIS Ethernet" > strings/0x409/product

# 创建RNDIS功能
mkdir -p functions/rndis.usb0 # 创建RNDIS功能配置

# 创建配置并关联功能
mkdir -p configs/c.1
ln -s functions/rndis.usb0 configs/c.1/ # 将RNDIS功能链接到配置中

# 启用Gadget,指定UDC控制器
echo $(ls /sys/class/udc) > UDC

这样就可以了,但是RNDIS在我电脑上没有驱动,难得找驱动,所以我更改了别的方式

十二,USB_NCM共享网络
# 加载`libcomposite`内核模块,这是创建USB Gadget的框架基础
sudo modprobe libcomposite
# 卸载g_ether模块,它占用着UDC控制器
sudo modprobe -r g_ether
# 加载 usb_f_ncm 模块
sudo modprobe usb_f_ncm

# Create the gadget
mkdir /sys/kernel/config/usb_gadget/g1
cd /sys/kernel/config/usb_gadget/g1

# Set device descriptor
echo 0x1d6b > idVendor    # Linux Foundation
echo 0x0104 > idProduct   # Product ID
echo 0x0100 > bcdDevice   # Device version
echo 0x0200 > bcdUSB      # USB 2.0

# Set English strings
mkdir strings/0x409
echo "1234567890" > strings/0x409/serialnumber
echo "Linux Foundation" > strings/0x409/manufacturer
echo "Composite Gadget" > strings/0x409/product

# Create a configuration
mkdir configs/c.1
# echo 120 > configs/c.1/MaxPower

# Add NCM function
mkdir functions/ncm.usb0
ln -s functions/ncm.usb0 configs/c.1/

# Add serial (ACM) function
mkdir functions/acm.usb0
ln -s functions/acm.usb0 configs/c.1/

# Bind to USB controller
echo $(ls /sys/class/udc) > UDC
echo "31000000.usb" > /sys/kernel/config/usb_gadget/g1/UDC

这里电脑也成功识别到了网口设备,但是 sudo dhclient usb0  一直无法成功,猜测ACM影响到了NCM

ACM 确实会影响NCM
  1. 清理现有配置:首先需要解除UDC绑定,然后移除ACM功能。

    # 进入您的gadget目录
    cd /sys/kernel/config/usb_gadget/g1

    # 非常重要:先解除UDC绑定,才能修改配置
    echo "" > UDC

    # 删除configs/c.1/目录下指向acm.usb0的符号链接
    rm configs/c.1/acm.usb0

    # 删除acm功能目录本身
    rmdir functions/acm.usb0
  2. (可选但推荐)为NCM功能设置MAC地址:这可以使网络接口的MAC地址固定,避免每次重启变化。

    # 在functions/ncm.usb0目录下设置设备端和主机端的MAC地址
    echo "02:00:00:00:00:02" > functions/ncm.usb0/dev_addr
    echo "02:00:00:00:00:01" > functions/ncm.usb0/host_addr
  3. 重新激活Gadget:将修改后的配置重新绑定到UDC。

    echo "31000000.usb" > UDC

    执行后,请等待几秒钟,然后用 ifconfig -a 命令查看 usb0 接口是否重新出现。

    sudo dhclient usb0

    image-20250928081408074image-20250928081408074.pngimage-20250928081440749.png

sudo dhclient usb0
ping baidu.com

image-20250928081249103.png


image-20250928081249103



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]