3 MIPI Camera Guide

This commit is contained in:
OrangePi CM5 Builder 2026-04-03 18:28:16 +08:00
parent 2c6459be9f
commit 90adb8e023
20 changed files with 445 additions and 144 deletions

BIN
Image/MiniLoaderAll.bin Normal file

Binary file not shown.

BIN
Image/bl31.elf Normal file

Binary file not shown.

BIN
Image/bl32.bin Normal file

Binary file not shown.

13
Image/parameter.txt Normal file
View File

@ -0,0 +1,13 @@
FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3588
MACHINE_ID: 007
MANUFACTURER: RK3588
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 0xffffffff
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00010000@0x00068000(backup),0x01c00000@0x00078000(rootfs),0x00040000@0x01c78000(oem),-@0x01cb8000(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
uuid:boot=7A3F0000-0000-446A-8000-702F00006273

BIN
afptool Executable file

Binary file not shown.

View File

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
# ============================================================================ # ============================================================================
# Orange Pi 5 Ultra - update.img 完整编译脚本 # Orange Pi 5 Ultra - update.img ?????????
# 官方orangepi-build系统 - 支持多种源码获取方式 # ???orangepi-build??? - ???????????????
# ============================================================================ # ============================================================================
set -e set -e
@ -14,14 +14,14 @@ BUILD_DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${WORK_DIR}/build_${BUILD_DATE}.log" LOG_FILE="${WORK_DIR}/build_${BUILD_DATE}.log"
MODE="auto" MODE="auto"
# 颜色输出 # ??????
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
NC='\033[0m' NC='\033[0m'
# ============================================================================ # ============================================================================
# 日志记录函数 # ?????????
# ============================================================================ # ============================================================================
log() { log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE" echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
@ -36,77 +36,153 @@ log_warn() {
} }
# ============================================================================ # ============================================================================
# 处理工作目录(避免路径中空格导致官方脚本异常) # ????????????
# ============================================================================ # ============================================================================
set_kconfig_option() {
local cfg_file=$1
local key=$2
local value=$3
if [ ! -f "$cfg_file" ]; then
mkdir -p "$(dirname "$cfg_file")"
: > "$cfg_file"
fi
if grep -q "^${key}=" "$cfg_file"; then
sed -i "s|^${key}=.*|${key}=${value}|" "$cfg_file"
elif grep -q "^# ${key} is not set" "$cfg_file"; then
sed -i "s|^# ${key} is not set|${key}=${value}|" "$cfg_file"
else
echo "${key}=${value}" >> "$cfg_file"
fi
}
# ============================================================================
# ?????? IMX586 ???????????????????????????
# ============================================================================
enforce_imx586_support() {
local BUILD_DIR=$1
local kernel_cfg_dir="${BUILD_DIR}/external/config/kernel"
local updated=0
log "????????? IMX586 ???..."
# ??? Orange Pi 5 Ultra??k3588 legacy??????????? for cfg in "${kernel_cfg_dir}"/linux-rockchip-rk3588-legacy*.config; do
[ -f "$cfg" ] || continue
set_kconfig_option "$cfg" "CONFIG_VIDEO_IMX586" "y"
updated=1
done
# userpatches ?????????????????????????????? IMX586?? local userpatch_cfg="${BUILD_DIR}/userpatches/linux-rockchip-rk3588-legacy-opi5max.config"
set_kconfig_option "$userpatch_cfg" "CONFIG_VIDEO_IMX586" "y"
updated=1
if [ "$updated" -eq 1 ]; then
log "???????IMX586 ???"
else
log_warn "???????????rk3588 legacy ???????????????????????
fi
}
# ============================================================================
# ????????IMX586 ??????
# ============================================================================
verify_imx586_support() {
local BUILD_DIR=$1
local kernel_tree="${BUILD_DIR}/kernel/orange-pi-5.10-rk35xx"
local kernel_cfg="${kernel_tree}/.config"
local driver_src="${kernel_tree}/drivers/media/i2c/imx586.c"
log "??? IMX586 ??????..."
if [ ! -f "$driver_src" ]; then
log_error "??? IMX586 ??????: $driver_src"
return 1
fi
if [ ! -f "$kernel_cfg" ]; then
log_error "?????????????? $kernel_cfg"
return 1
fi
if grep -Eq '^CONFIG_VIDEO_IMX586=(y|m)$' "$kernel_cfg"; then
log "??IMX586 ???????? $(grep -E '^CONFIG_VIDEO_IMX586=' "$kernel_cfg" | head -1)"
return 0
fi
log_error "IMX586 ????????? CONFIG_VIDEO_IMX586=y/m??
return 1
}
# ============================================================================
# ???????????????????????????????????# ============================================================================
prepare_workspace() { prepare_workspace() {
mkdir -p "$WORK_DIR" mkdir -p "$WORK_DIR"
if [ -d "$LEGACY_WORK_DIR" ]; then if [ -d "$LEGACY_WORK_DIR" ]; then
log "检测到旧目录: $LEGACY_WORK_DIR" log "?????????? $LEGACY_WORK_DIR"
# 同步关键目录,尽量复用已有下载/缓存,避免重复拉取。 # ??????????????????????????????????????? if [ -d "$LEGACY_WORK_DIR/SDKs" ] && [ ! -e "$WORK_DIR/SDKs" ]; then
if [ -d "$LEGACY_WORK_DIR/SDKs" ] && [ ! -e "$WORK_DIR/SDKs" ]; then
cp -a "$LEGACY_WORK_DIR/SDKs" "$WORK_DIR/" cp -a "$LEGACY_WORK_DIR/SDKs" "$WORK_DIR/"
log "✓ 已迁移 SDKs 到新目录" log "???????SDKs ??????"
fi fi
if [ -d "$LEGACY_WORK_DIR/sources" ] && [ ! -e "$WORK_DIR/sources" ]; then if [ -d "$LEGACY_WORK_DIR/sources" ] && [ ! -e "$WORK_DIR/sources" ]; then
cp -a "$LEGACY_WORK_DIR/sources" "$WORK_DIR/" cp -a "$LEGACY_WORK_DIR/sources" "$WORK_DIR/"
log "✓ 已迁移 sources 到新目录" log "???????sources ??????"
fi fi
if [ -d "$LEGACY_WORK_DIR/orangepi-build" ] && [ ! -e "$WORK_DIR/orangepi-build" ]; then if [ -d "$LEGACY_WORK_DIR/orangepi-build" ] && [ ! -e "$WORK_DIR/orangepi-build" ]; then
cp -a "$LEGACY_WORK_DIR/orangepi-build" "$WORK_DIR/" cp -a "$LEGACY_WORK_DIR/orangepi-build" "$WORK_DIR/"
log "✓ 已迁移 orangepi-build 到新目录" log "???????orangepi-build ??????"
fi fi
fi fi
} }
# ============================================================================ # ============================================================================
# 检查环境和依赖 # ???????????
# ============================================================================ # ============================================================================
check_environment() { check_environment() {
log "检查编译环境..." log "??????????.."
# 检查必需工具 # ??????????
local required_tools=("git" "gcc" "make" "device-tree-compiler") local required_tools=("git" "gcc" "make" "device-tree-compiler")
for tool in "${required_tools[@]}"; do for tool in "${required_tools[@]}"; do
if ! command -v "$tool" &> /dev/null; then if ! command -v "$tool" &> /dev/null; then
log_warn "$tool 未安装,尝试安装..." log_warn "$tool ????????????..."
apt-get update apt-get update
apt-get install -y "$tool" apt-get install -y "$tool"
else else
log "$tool 已安装" log "??$tool ?????
fi fi
done done
# 检查交叉编译工具链 # ??????????????
if ! command -v aarch64-linux-gnu-gcc &> /dev/null; then if ! command -v aarch64-linux-gnu-gcc &> /dev/null; then
log_warn "aarch64-linux-gnu-gcc 未安装,尝试安装..." log_warn "aarch64-linux-gnu-gcc ????????????..."
apt-get install -y gcc-aarch64-linux-gnu build-essential apt-get install -y gcc-aarch64-linux-gnu build-essential
else else
log "✓ aarch64-linux-gnu-gcc 已安装" log "??aarch64-linux-gnu-gcc ?????
fi fi
log "环境检查完成" log "??????????
} }
# ============================================================================ # ============================================================================
# 配置 git 以应对网络问题 # ??? git ???????????# ============================================================================
# ============================================================================
configure_git() { configure_git() {
log "配置 git 网络参数..." log "??? git ??????..."
git config --global http.connectTimeout 120 git config --global http.connectTimeout 120
git config --global http.postBuffer 524288000 git config --global http.postBuffer 524288000
git config --global core.compression 0 git config --global core.compression 0
git config --global url."https://".insteadOf git:// git config --global url."https://".insteadOf git://
log "✓ git 配置完成" log "??git ??????"
} }
# ============================================================================ # ============================================================================
# 下载源码 - 方式1: Gitee镜像国内优先 # ?????? - ???1: Gitee????????????
# ============================================================================ # ============================================================================
download_from_gitee() { download_from_gitee() {
local repo_name=$1 local repo_name=$1
@ -114,26 +190,26 @@ download_from_gitee() {
local branch=$3 local branch=$3
local target_dir=$4 local target_dir=$4
log "尝试从 Gitee 下载 $repo_name (分支: $branch)..." log "?????Gitee ??? $repo_name (???: $branch)..."
if [ -d "$target_dir" ]; then if [ -d "$target_dir" ]; then
log "目录已存在,更新代码..." log "???????????????..."
cd "$target_dir" cd "$target_dir"
git pull origin "$branch" 2>&1 && return 0 git pull origin "$branch" 2>&1 && return 0
cd - > /dev/null cd - > /dev/null
fi fi
if git clone --depth=1 -b "$branch" "$repo_url" "$target_dir" 2>&1; then if git clone --depth=1 -b "$branch" "$repo_url" "$target_dir" 2>&1; then
log "✓ 从 Gitee 下载成功" log "????Gitee ??????"
return 0 return 0
else else
log_warn "从 Gitee 下载失败" log_warn "??Gitee ??????"
return 1 return 1
fi fi
} }
# ============================================================================ # ============================================================================
# 下载源码 - 方式2: GitHub (带重试) # ?????? - ???2: GitHub (?????
# ============================================================================ # ============================================================================
download_from_github() { download_from_github() {
local repo_name=$1 local repo_name=$1
@ -142,43 +218,43 @@ download_from_github() {
local target_dir=$4 local target_dir=$4
local retry_count=3 local retry_count=3
log "尝试从 GitHub 下载 $repo_name (分支: $branch)..." log "?????GitHub ??? $repo_name (???: $branch)..."
if [ -d "$target_dir" ]; then if [ -d "$target_dir" ]; then
log "目录已存在,更新代码..." log "???????????????..."
cd "$target_dir" cd "$target_dir"
git pull origin "$branch" 2>&1 && return 0 git pull origin "$branch" 2>&1 && return 0
cd - > /dev/null cd - > /dev/null
fi fi
for ((i=1; i<=retry_count; i++)); do for ((i=1; i<=retry_count; i++)); do
log "GitHub 克隆尝试 $i/$retry_count..." log "GitHub ?????? $i/$retry_count..."
if git clone --depth=1 -b "$branch" "$repo_url" "$target_dir" 2>&1; then if git clone --depth=1 -b "$branch" "$repo_url" "$target_dir" 2>&1; then
log "✓ 从 GitHub 下载成功" log "????GitHub ??????"
return 0 return 0
fi fi
sleep 5 sleep 5
done done
log_warn "GitHub 下载最终失败" log_warn "GitHub ??????????
return 1 return 1
} }
# ============================================================================ # ============================================================================
# 获取 orangepi-build # ??? orangepi-build
# ============================================================================ # ============================================================================
get_orangepi_build() { get_orangepi_build() {
log "获取 orangepi-build 编译系统..." log "??? orangepi-build ??????..."
local BUILD_DIR="${WORK_DIR}/orangepi-build" local BUILD_DIR="${WORK_DIR}/orangepi-build"
# 第1优先级: 从本地 SDKs 目录提取 # ??????? ?????SDKs ??????
if extract_from_sdks "orangepi-build" "$BUILD_DIR"; then if extract_from_sdks "orangepi-build" "$BUILD_DIR"; then
ORANGEPI_BUILD_DIR="$BUILD_DIR" ORANGEPI_BUILD_DIR="$BUILD_DIR"
return 0 return 0
fi fi
# 第2优先级: Gitee 镜像 # ??????? Gitee ???
if download_from_gitee \ if download_from_gitee \
"orangepi-build" \ "orangepi-build" \
"https://gitee.com/orangepi-xunlong/orangepi-build.git" \ "https://gitee.com/orangepi-xunlong/orangepi-build.git" \
@ -188,7 +264,7 @@ get_orangepi_build() {
return 0 return 0
fi fi
# 第3优先级: GitHub # ??????? GitHub
if download_from_github \ if download_from_github \
"orangepi-build" \ "orangepi-build" \
"https://github.com/orangepi-xunlong/orangepi-build.git" \ "https://github.com/orangepi-xunlong/orangepi-build.git" \
@ -198,12 +274,12 @@ get_orangepi_build() {
return 0 return 0
fi fi
log_error "无法获取 orangepi-build" log_error "?????? orangepi-build"
return 1 return 1
} }
# ============================================================================ # ============================================================================
# 建立持久化缓存(避免每次重复下载工具链) # ??????????????????????????????
# ============================================================================ # ============================================================================
setup_build_cache_links() { setup_build_cache_links() {
local build_dir=$1 local build_dir=$1
@ -213,8 +289,7 @@ setup_build_cache_links() {
mkdir -p "$shared_dl" "$shared_toolchains" "$shared_ext_cache" mkdir -p "$shared_dl" "$shared_toolchains" "$shared_ext_cache"
# 如果旧目录里已有下载内容,首次迁移到共享缓存。 # ??????????????????????????????????? if [ -d "$build_dir/dl" ] && [ ! -L "$build_dir/dl" ] && [ -z "$(ls -A "$shared_dl" 2>/dev/null)" ]; then
if [ -d "$build_dir/dl" ] && [ ! -L "$build_dir/dl" ] && [ -z "$(ls -A "$shared_dl" 2>/dev/null)" ]; then
cp -a "$build_dir/dl/." "$shared_dl/" 2>/dev/null || true cp -a "$build_dir/dl/." "$shared_dl/" 2>/dev/null || true
fi fi
if [ -d "$build_dir/toolchains" ] && [ ! -L "$build_dir/toolchains" ] && [ -z "$(ls -A "$shared_toolchains" 2>/dev/null)" ]; then if [ -d "$build_dir/toolchains" ] && [ ! -L "$build_dir/toolchains" ] && [ -z "$(ls -A "$shared_toolchains" 2>/dev/null)" ]; then
@ -230,39 +305,38 @@ setup_build_cache_links() {
ln -s "$shared_toolchains" "$build_dir/toolchains" ln -s "$shared_toolchains" "$build_dir/toolchains"
ln -s "$shared_ext_cache" "$build_dir/external/cache" ln -s "$shared_ext_cache" "$build_dir/external/cache"
log "✓ 已启用共享缓存" log "?????????????
log " dl: $shared_dl" log " dl: $shared_dl"
log " toolchains: $shared_toolchains" log " toolchains: $shared_toolchains"
log " external cache: $shared_ext_cache" log " external cache: $shared_ext_cache"
} }
# ============================================================================ # ============================================================================
# 方式3: 从本地 SDKs 目录提取源码包 # ???3: ?????SDKs ???????????# ============================================================================
# ============================================================================
extract_from_sdks() { extract_from_sdks() {
local repo_name=$1 local repo_name=$1
local target_dir=$2 local target_dir=$2
log "尝试从 SDKs 目录提取 $repo_name..." log "?????SDKs ?????? $repo_name..."
# 检查目标目录是否已存在 # ?????????????????
if [ -d "$target_dir" ]; then if [ -d "$target_dir" ]; then
log "✓ 目录已存在: $target_dir" log "?????????? $target_dir"
return 0 return 0
fi fi
# 方式1: 查找 orangepi-build-next.zip # ???1: ??? orangepi-build-next.zip
if [ "$repo_name" = "orangepi-build" ]; then if [ "$repo_name" = "orangepi-build" ]; then
local archive="${WORK_DIR}/SDKs/orangepi-build-next.zip" local archive="${WORK_DIR}/SDKs/orangepi-build-next.zip"
if [ -f "$archive" ]; then if [ -f "$archive" ]; then
log "找到源码包: $archive" log "???????? $archive"
log "解压中..." log "?????.."
mkdir -p "$target_dir" mkdir -p "$target_dir"
unzip -q "$archive" -d "$target_dir" 2>/dev/null || return 1 unzip -q "$archive" -d "$target_dir" 2>/dev/null || return 1
# 处理可能的子目录结构 # ???????????????
if [ -d "${target_dir}/orangepi-build"* ]; then if [ -d "${target_dir}/orangepi-build"* ]; then
mv "${target_dir}"/orangepi-build* "${target_dir}_tmp" mv "${target_dir}"/orangepi-build* "${target_dir}_tmp"
rm -rf "$target_dir" rm -rf "$target_dir"
@ -274,28 +348,28 @@ extract_from_sdks() {
fi fi
if [ -f "${target_dir}/build.sh" ]; then if [ -f "${target_dir}/build.sh" ]; then
log "✓ 从 SDKs 解压成功" log "????SDKs ??????"
return 0 return 0
fi fi
fi fi
# 方式2: 查找 OrangePi_Build-master.zip # ???2: ??? OrangePi_Build-master.zip
archive="${WORK_DIR}/SDKs/OrangePi_Build-master.zip" archive="${WORK_DIR}/SDKs/OrangePi_Build-master.zip"
if [ -f "$archive" ]; then if [ -f "$archive" ]; then
log "找到备选源码包: $archive" log "???????????: $archive"
log "解压中..." log "?????.."
mkdir -p "$target_dir" mkdir -p "$target_dir"
unzip -q "$archive" -d "$target_dir" 2>/dev/null || return 1 unzip -q "$archive" -d "$target_dir" 2>/dev/null || return 1
# 处理可能的子目录结构 # ???????????????
if [ -d "${target_dir}/OrangePi_Build-master" ]; then if [ -d "${target_dir}/OrangePi_Build-master" ]; then
mv "${target_dir}/OrangePi_Build-master"/* "$target_dir"/ 2>/dev/null || true mv "${target_dir}/OrangePi_Build-master"/* "$target_dir"/ 2>/dev/null || true
rmdir "${target_dir}/OrangePi_Build-master" 2>/dev/null || true rmdir "${target_dir}/OrangePi_Build-master" 2>/dev/null || true
fi fi
if [ -f "${target_dir}/build.sh" ]; then if [ -f "${target_dir}/build.sh" ]; then
log "✓ 从 SDKs 解压成功" log "????SDKs ??????"
return 0 return 0
fi fi
fi fi
@ -307,10 +381,10 @@ extract_from_sdks() {
} }
# ============================================================================ # ============================================================================
# 检查本地预准备的源码包 # ?????????????????
# ============================================================================ # ============================================================================
check_local_sources() { check_local_sources() {
log "检查本地是否存在预准备的源码包..." log "???????????????????????..."
local sources_dir="${WORK_DIR}/sources" local sources_dir="${WORK_DIR}/sources"
@ -318,10 +392,10 @@ check_local_sources() {
return 1 return 1
fi fi
# 检查是否存在 orangepi-build 源码 # ??????????orangepi-build ???
for archive in "$sources_dir"/{orangepi-build,u-boot,linux,kernel}*.tar* "$sources_dir"/*.zip; do for archive in "$sources_dir"/{orangepi-build,u-boot,linux,kernel}*.tar* "$sources_dir"/*.zip; do
if [ -f "$archive" ]; then if [ -f "$archive" ]; then
log "找到本地源码包: $archive" log "??????????? $archive"
return 0 return 0
fi fi
done done
@ -330,39 +404,37 @@ check_local_sources() {
} }
# ============================================================================ # ============================================================================
# 编译 update.img (使用 orangepi-build) # ??? update.img (??? orangepi-build)
# ============================================================================ # ============================================================================
build_update_img() { build_update_img() {
local BUILD_DIR=$1 local BUILD_DIR=$1
log "开始编译 update.img..." log "???????update.img..."
cd "$BUILD_DIR" cd "$BUILD_DIR"
# 显示已有源码信息 # ????????????
log "编译系统目录结构:" log "????????????:"
ls -la | head -20 >> "$LOG_FILE" ls -la | head -20 >> "$LOG_FILE"
# 确保脚本有执行权限 # ?????????????? chmod +x build.sh
chmod +x build.sh
# 使用官方编译命令编译完整镜像 # ?????????????????????
# 参数说明: # ??????:
# BOARD=orangepi5ultra - 开发板型号 # BOARD=orangepi5ultra - ????????
# BRANCH=legacy - 使用 linux5.10 (支持 IMX586 相机) # BRANCH=legacy - ??? linux5.10 (??? IMX586 ???)
# BUILD_OPT=image - 编译完整镜像 # BUILD_OPT=image - ?????????
# RELEASE=bullseye - Debian Bullseye 发行版 # RELEASE=bullseye - Debian Bullseye ????? # BUILD_DESKTOP=no - ????????? (??????????????yes)
# BUILD_DESKTOP=no - 编译服务器版 (更小体积,可选改为 yes)
if [ "$MODE" = "menu" ]; then if [ "$MODE" = "menu" ]; then
log "执行官方编译脚本(交互模式)..." log "?????????????????????..."
log "将进入 ncurses 菜单,请手动选择编译类型" log "?????ncurses ??????????????????"
# ncurses 必须直连终端,不能通过 tee 管道输出 # ncurses ????????????????? tee ??????
sudo ./build.sh sudo ./build.sh
local build_rc=$? local build_rc=$?
else else
log "执行官方编译脚本(自动模式)..." log "?????????????????????..."
log "编译参数: BOARD=orangepi5ultra BRANCH=legacy BUILD_OPT=image KERNEL_CONFIGURE=no" log "??????: BOARD=orangepi5ultra BRANCH=legacy BUILD_OPT=image KERNEL_CONFIGURE=no"
sudo ./build.sh \ sudo ./build.sh \
BOARD=orangepi5ultra \ BOARD=orangepi5ultra \
@ -375,67 +447,64 @@ build_update_img() {
fi fi
if [ ${build_rc:-1} -eq 0 ]; then if [ ${build_rc:-1} -eq 0 ]; then
log "✓ 编译成功" log "????????"
return 0 return 0
else else
# 某些上游脚本会在收尾阶段返回非0但镜像已成功产出。 # ??????????????????????????????????????? local produced_img
local produced_img
produced_img=$(find "$BUILD_DIR/output/images" -name "*.img" -type f 2>/dev/null | head -1) produced_img=$(find "$BUILD_DIR/output/images" -name "*.img" -type f 2>/dev/null | head -1)
if [ -n "$produced_img" ]; then if [ -n "$produced_img" ]; then
log_warn "build.sh 返回非0但已检测到镜像产物: $produced_img" log_warn "build.sh ????????????????????: $produced_img"
log_warn "按成功继续执行验证步骤" log_warn "?????????????????
return 0 return 0
fi fi
log_error "编译失败" log_error "??????"
return 1 return 1
fi fi
} }
# ============================================================================ # ============================================================================
# 验证编译结果 # ?????????
# ============================================================================ # ============================================================================
verify_build() { verify_build() {
local BUILD_DIR=$1 local BUILD_DIR=$1
log "验证编译结果..." log "?????????..."
local output_dir="${BUILD_DIR}/output/images" local output_dir="${BUILD_DIR}/output/images"
if [ ! -d "$output_dir" ]; then if [ ! -d "$output_dir" ]; then
log_error "输出目录不存在: $output_dir" log_error "??????????? $output_dir"
return 1 return 1
fi fi
# 优先查找 update.img找不到则接受任意 .img 作为总包产物。 # ?????? update.img??????????????.img ??????????? local update_img
local update_img
update_img=$(find "$output_dir" -name "*update*.img" -type f 2>/dev/null | head -1) update_img=$(find "$output_dir" -name "*update*.img" -type f 2>/dev/null | head -1)
if [ -z "$update_img" ]; then if [ -z "$update_img" ]; then
update_img=$(find "$output_dir" -name "*.img" -type f 2>/dev/null | head -1) update_img=$(find "$output_dir" -name "*.img" -type f 2>/dev/null | head -1)
fi fi
if [ -z "$update_img" ]; then if [ -z "$update_img" ]; then
log_error "未找到镜像文件 (*.img)" log_error "???????????(*.img)"
return 1 return 1
fi fi
log "✓ 找到编译结果: $update_img" log "???????????: $update_img"
local img_size=$(du -sh "$update_img" | awk '{print $1}') local img_size=$(du -sh "$update_img" | awk '{print $1}')
log "镜像大小: $img_size" log "??????: $img_size"
# 生成校验和 # ???????? log "??? SHA256 ?????.."
log "生成 SHA256 校验和..."
sha256sum "$update_img" > "${update_img}.sha256" sha256sum "$update_img" > "${update_img}.sha256"
log "编译结果信息:" log "?????????:"
cat >> "$LOG_FILE" << EOF cat >> "$LOG_FILE" << EOF
=== 编译完成 === === ?????? ===
时间: $(date) ???: $(date)
镜像文件: $update_img ??????: $update_img
大小: $img_size ???: $img_size
校验和: $(cat "${update_img}.sha256") ????? $(cat "${update_img}.sha256")
EOF EOF
@ -443,8 +512,7 @@ EOF
} }
# ============================================================================ # ============================================================================
# 主流程 # ?????# ============================================================================
# ============================================================================
main() { main() {
case "${1:-}" in case "${1:-}" in
menu|interactive) menu|interactive)
@ -454,88 +522,95 @@ main() {
MODE="auto" MODE="auto"
;; ;;
*) *)
echo "用法: $0 [auto|menu]" echo "???: $0 [auto|menu]"
echo " auto: 默认自动编译(无 ncurses 菜单)" echo " auto: ???????????? ncurses ?????
echo " menu: 进入官方 ncurses 菜单手动选择" echo " menu: ?????? ncurses ?????????"
exit 1 exit 1
;; ;;
esac esac
log "==========================================" log "=========================================="
log "Orange Pi 5 Ultra - update.img 编译" log "Orange Pi 5 Ultra - update.img ???"
log "==========================================" log "=========================================="
log "工作目录: $WORK_DIR" log "??????: $WORK_DIR"
log "旧目录(兼容): $LEGACY_WORK_DIR" log "????????): $LEGACY_WORK_DIR"
log "日志文件: $LOG_FILE" log "??????: $LOG_FILE"
log "运行模式: $MODE" log "??????: $MODE"
prepare_workspace prepare_workspace
cd "$WORK_DIR" || { log_error "无法进入工作目录"; exit 1; } cd "$WORK_DIR" || { log_error "????????????"; exit 1; }
# 第1步: 检查环境 # ???? ??????? check_environment
check_environment
# 第2步: 配置git # ???? ???git
configure_git configure_git
# 第3步: 获取 orangepi-build # ???? ??? orangepi-build
log "" log ""
log "========== 步骤1: 获取源码 ==========" log "========== ???1: ?????? =========="
if ! get_orangepi_build; then if ! get_orangepi_build; then
log_error "获取 orangepi-build 失败" log_error "??? orangepi-build ???"
log "" log ""
log "解决方案:" log "??????:"
log "1. ✓ 自动优先使用 \${WORK_DIR}/SDKs/ 目录下的源码包:" log "1. ??????????? \${WORK_DIR}/SDKs/ ???????????"
log " - orangepi-build-next.zip" log " - orangepi-build-next.zip"
log " - OrangePi_Build-master.zip" log " - OrangePi_Build-master.zip"
log "" log ""
log "2. 如果上述 SDKs 目录缺少文件,请:" log "2. ?????? SDKs ????????????:"
log " a) 检查 ${WORK_DIR}/SDKs/ 目录是否存在" log " a) ????${WORK_DIR}/SDKs/ ?????????"
log " b) 确保源码包完整且未损坏" log " b) ?????????????????
log " c) 或将官方源码包放入该目录并重新运行" log " c) ??????????????????????????
log "" log ""
log "3. 作为备选,可将源码放在 ${WORK_DIR}/sources/ 目录下" log "3. ????????????????? ${WORK_DIR}/sources/ ?????
log "" log ""
log "4. 若选择网络下载:" log "4. ???????????:"
log " - 确保有稳定的网络连接" log " - ???????????????"
log " - 如需认证,请配置 git 凭证: git config --global credential.helper store" log " - ???????????? git ???: git config --global credential.helper store"
exit 1 exit 1
fi fi
BUILD_DIR="$ORANGEPI_BUILD_DIR" BUILD_DIR="$ORANGEPI_BUILD_DIR"
# 第3.5步: 配置持久缓存 # ??.5?? ?????????
setup_build_cache_links "$BUILD_DIR" setup_build_cache_links "$BUILD_DIR"
# ??.6?? ?????? IMX586 ???
enforce_imx586_support "$BUILD_DIR"
# 第4步: 编译 update.img # ???? ??? update.img
log "" log ""
log "========== 步骤2: 编译镜像 ==========" log "========== ???2: ?????? =========="
if ! build_update_img "$BUILD_DIR"; then if ! build_update_img "$BUILD_DIR"; then
log_error "编译失败,详情查看日志: $LOG_FILE" log_error "????????????????? $LOG_FILE"
exit 1 exit 1
fi fi
# 第5步: 验证结果 # ???? ??????
log "" log ""
log "========== 步骤3: 验证结果 ==========" log "========== ???3: ?????? =========="
if ! verify_build "$BUILD_DIR"; then if ! verify_build "$BUILD_DIR"; then
log_error "验证失败" log_error "??????"
exit 1
fi
if ! verify_imx586_support "$BUILD_DIR"; then
log_error "IMX586 ?????????"
exit 1 exit 1
fi fi
log "" log ""
log "==========================================" log "=========================================="
log "✓ 编译完成!" log "??????????
log "==========================================" log "=========================================="
log "后续步骤:" log "??????:"
log "1. 下载镜像: scp root@www.yuquanjun.cn:/data/OrangePi_CM5/orangepi-build/output/images/*/update.img ./" log "1. ??????: scp root@www.yuquanjun.cn:/data/OrangePi_CM5/orangepi-build/output/images/*/update.img ./"
log "2. 使用 RKDevTool 或 balenaEtcher 烧录镜像" log "2. ??? RKDevTool ??balenaEtcher ??????"
log "==========================================" log "=========================================="
} }
# 运行主程序 # ????????main "$@"
main "$@"

23
package-file Normal file
View File

@ -0,0 +1,23 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
trust Image/trust.img
uboot Image/uboot.img
misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
recovery Image/recovery.img
rootfs Image/rootfs.img
oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

23
package-file.backup Normal file
View File

@ -0,0 +1,23 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
#trust Image/trust.img
uboot Image/uboot.img
misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
recovery Image/recovery.img
rootfs Image/rootfs.img
oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

22
rk3588-mkupdate.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
pause()
{
echo "Press any key to quit:"
read -n1 -s key
exit 1
}
echo "start to make update.img..."
if [ ! -f "Image/parameter" -a ! -f "Image/parameter.txt" ]; then
echo "Error:No found parameter!"
exit 1
fi
if [ ! -f "package-file" ]; then
echo "Error:No found package-file!"
exit 1
fi
./afptool -pack ./ Image/update.img || pause
./rkImageMaker -RK3588 Image/MiniLoaderAll.bin Image/update.img update.img -os_type:androidos || pause
echo "Making ./Image/update.img OK."
#echo "Press any key to quit:"
#read -n1 -s key
exit $?

23
rk3588-package-file Normal file
View File

@ -0,0 +1,23 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
trust Image/trust.img
uboot Image/uboot.img
misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
recovery Image/recovery.img
rootfs Image/rootfs.img
oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

24
rk3588-package-file-ab Normal file
View File

@ -0,0 +1,24 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
#trust Image/trust.img
uboot Image/uboot.img
misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot_a Image/boot.img
boot_b Image/boot.img
system_a Image/rootfs.img
system_b Image/rootfs.img
oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

View File

@ -0,0 +1,23 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
#trust Image/trust.img
uboot Image/uboot.img
#misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
#recovery Image/recovery.img
rootfs Image/rootfs.img
#oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

View File

@ -0,0 +1,23 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
#trust Image/trust.img
uboot Image/uboot.img
#misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
#recovery Image/recovery.img
rootfs Image/rootfs.img
#oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

BIN
rkImageMaker Executable file

Binary file not shown.

11
start_compile.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
if [ -d "/data/OrangePi_CM5" ]; then
cd "/data/OrangePi_CM5"
else
cd "/data/OrangePi CM5"
fi
sudo chmod +x compile-orangepi5ultra.sh
sudo ./compile-orangepi5ultra.sh

5
steps.txt Normal file
View File

@ -0,0 +1,5 @@
OrangePI5-Ultra RK3588 cam0 ov13855, cam1 imx586 cam2 ov13855
1. 烧录香橙派官方镜像Orangepi5ultra_1.0.0_ubuntu_jammy_desktop_xfce_linux5.10.160.img
2. 安装尤工发布的imx586驱动C:\Users\qjyu\Documents\Lookzn\OrangePi_CM5\imx586_2\linux-dtb-legacy-rockchip-rk3588_1.0.0_arm64.deblinux-image-legacy-rockchip-rk3588_1.0.0_arm64.deb, imx586_default_default.json
3. /boot/orangepiEnv.txt : overlays=opi5ultra-cam0 opi5ultra-cam1 opi5ultra-cam2
4. 重启后运行test_camera.sh查看3个摄像头视频

Binary file not shown.

View File

@ -0,0 +1,13 @@
FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3588
MACHINE_ID: 007
MANUFACTURER: RK3588
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 0xffffffff
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00010000@0x00068000(backup),0x01c00000@0x00078000(rootfs),0x00040000@0x01c78000(oem),-@0x01cb8000(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
uuid:boot=7A3F0000-0000-446A-8000-702F00006273

View File

@ -0,0 +1,23 @@
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
trust Image/trust.img
uboot Image/uboot.img
misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
recovery Image/recovery.img
rootfs Image/rootfs.img
oem Image/oem.img
userdata Image/userdata.img
# 要写入backup分区的文件就是自身update.img
# SELF 是关键字表示升级文件update.img自身
# 在生成升级文件时不加入SELF文件的内容但在头部信息中有记录
# 在解包升级文件时不解包SELF文件的内容。
backup RESERVED
#update-script update-script
#recover-script recover-script

BIN
verify_unpack/rkImageMaker Executable file

Binary file not shown.