OrangePi_CM5/compile-orangepi5ultra.sh

617 lines
18 KiB
Bash
Executable File

#!/bin/bash
# ============================================================================
# Orange Pi 5 Ultra - update.img ?????????
# ???orangepi-build??? - ???????????????
# ============================================================================
set -e
LEGACY_WORK_DIR="/data/OrangePi CM5"
WORK_DIR="/data/OrangePi_CM5"
CACHE_ROOT="/data/OrangePi_cache"
BUILD_DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${WORK_DIR}/build_${BUILD_DATE}.log"
MODE="auto"
# ??????
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# ============================================================================
# ?????????
# ============================================================================
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
}
log_warn() {
echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}
# ============================================================================
# ????????????
# ============================================================================
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() {
mkdir -p "$WORK_DIR"
if [ -d "$LEGACY_WORK_DIR" ]; then
log "?????????? $LEGACY_WORK_DIR"
# ??????????????????????????????????????? if [ -d "$LEGACY_WORK_DIR/SDKs" ] && [ ! -e "$WORK_DIR/SDKs" ]; then
cp -a "$LEGACY_WORK_DIR/SDKs" "$WORK_DIR/"
log "???????SDKs ??????"
fi
if [ -d "$LEGACY_WORK_DIR/sources" ] && [ ! -e "$WORK_DIR/sources" ]; then
cp -a "$LEGACY_WORK_DIR/sources" "$WORK_DIR/"
log "???????sources ??????"
fi
if [ -d "$LEGACY_WORK_DIR/orangepi-build" ] && [ ! -e "$WORK_DIR/orangepi-build" ]; then
cp -a "$LEGACY_WORK_DIR/orangepi-build" "$WORK_DIR/"
log "???????orangepi-build ??????"
fi
fi
}
# ============================================================================
# ???????????
# ============================================================================
check_environment() {
log "??????????.."
# ??????????
local required_tools=("git" "gcc" "make" "device-tree-compiler")
for tool in "${required_tools[@]}"; do
if ! command -v "$tool" &> /dev/null; then
log_warn "$tool ????????????..."
apt-get update
apt-get install -y "$tool"
else
log "??$tool ?????
fi
done
# ??????????????
if ! command -v aarch64-linux-gnu-gcc &> /dev/null; then
log_warn "aarch64-linux-gnu-gcc ????????????..."
apt-get install -y gcc-aarch64-linux-gnu build-essential
else
log "??aarch64-linux-gnu-gcc ?????
fi
log "??????????
}
# ============================================================================
# ??? git ???????????# ============================================================================
configure_git() {
log "??? git ??????..."
git config --global http.connectTimeout 120
git config --global http.postBuffer 524288000
git config --global core.compression 0
git config --global url."https://".insteadOf git://
log "??git ??????"
}
# ============================================================================
# ?????? - ???1: Gitee????????????
# ============================================================================
download_from_gitee() {
local repo_name=$1
local repo_url=$2
local branch=$3
local target_dir=$4
log "?????Gitee ??? $repo_name (???: $branch)..."
if [ -d "$target_dir" ]; then
log "???????????????..."
cd "$target_dir"
git pull origin "$branch" 2>&1 && return 0
cd - > /dev/null
fi
if git clone --depth=1 -b "$branch" "$repo_url" "$target_dir" 2>&1; then
log "????Gitee ??????"
return 0
else
log_warn "??Gitee ??????"
return 1
fi
}
# ============================================================================
# ?????? - ???2: GitHub (?????
# ============================================================================
download_from_github() {
local repo_name=$1
local repo_url=$2
local branch=$3
local target_dir=$4
local retry_count=3
log "?????GitHub ??? $repo_name (???: $branch)..."
if [ -d "$target_dir" ]; then
log "???????????????..."
cd "$target_dir"
git pull origin "$branch" 2>&1 && return 0
cd - > /dev/null
fi
for ((i=1; i<=retry_count; i++)); do
log "GitHub ?????? $i/$retry_count..."
if git clone --depth=1 -b "$branch" "$repo_url" "$target_dir" 2>&1; then
log "????GitHub ??????"
return 0
fi
sleep 5
done
log_warn "GitHub ??????????
return 1
}
# ============================================================================
# ??? orangepi-build
# ============================================================================
get_orangepi_build() {
log "??? orangepi-build ??????..."
local BUILD_DIR="${WORK_DIR}/orangepi-build"
# ??????? ?????SDKs ??????
if extract_from_sdks "orangepi-build" "$BUILD_DIR"; then
ORANGEPI_BUILD_DIR="$BUILD_DIR"
return 0
fi
# ??????? Gitee ???
if download_from_gitee \
"orangepi-build" \
"https://gitee.com/orangepi-xunlong/orangepi-build.git" \
"next" \
"$BUILD_DIR"; then
ORANGEPI_BUILD_DIR="$BUILD_DIR"
return 0
fi
# ??????? GitHub
if download_from_github \
"orangepi-build" \
"https://github.com/orangepi-xunlong/orangepi-build.git" \
"next" \
"$BUILD_DIR"; then
ORANGEPI_BUILD_DIR="$BUILD_DIR"
return 0
fi
log_error "?????? orangepi-build"
return 1
}
# ============================================================================
# ??????????????????????????????
# ============================================================================
setup_build_cache_links() {
local build_dir=$1
local shared_dl="${CACHE_ROOT}/dl"
local shared_toolchains="${CACHE_ROOT}/toolchains"
local shared_ext_cache="${CACHE_ROOT}/external-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
cp -a "$build_dir/dl/." "$shared_dl/" 2>/dev/null || true
fi
if [ -d "$build_dir/toolchains" ] && [ ! -L "$build_dir/toolchains" ] && [ -z "$(ls -A "$shared_toolchains" 2>/dev/null)" ]; then
cp -a "$build_dir/toolchains/." "$shared_toolchains/" 2>/dev/null || true
fi
if [ -d "$build_dir/external/cache" ] && [ ! -L "$build_dir/external/cache" ] && [ -z "$(ls -A "$shared_ext_cache" 2>/dev/null)" ]; then
cp -a "$build_dir/external/cache/." "$shared_ext_cache/" 2>/dev/null || true
fi
mkdir -p "$build_dir/external"
rm -rf "$build_dir/dl" "$build_dir/toolchains" "$build_dir/external/cache"
ln -s "$shared_dl" "$build_dir/dl"
ln -s "$shared_toolchains" "$build_dir/toolchains"
ln -s "$shared_ext_cache" "$build_dir/external/cache"
log "?????????????
log " dl: $shared_dl"
log " toolchains: $shared_toolchains"
log " external cache: $shared_ext_cache"
}
# ============================================================================
# ???3: ?????SDKs ???????????# ============================================================================
extract_from_sdks() {
local repo_name=$1
local target_dir=$2
log "?????SDKs ?????? $repo_name..."
# ?????????????????
if [ -d "$target_dir" ]; then
log "?????????? $target_dir"
return 0
fi
# ???1: ??? orangepi-build-next.zip
if [ "$repo_name" = "orangepi-build" ]; then
local archive="${WORK_DIR}/SDKs/orangepi-build-next.zip"
if [ -f "$archive" ]; then
log "???????? $archive"
log "?????.."
mkdir -p "$target_dir"
unzip -q "$archive" -d "$target_dir" 2>/dev/null || return 1
# ???????????????
if [ -d "${target_dir}/orangepi-build"* ]; then
mv "${target_dir}"/orangepi-build* "${target_dir}_tmp"
rm -rf "$target_dir"
mv "${target_dir}_tmp" "$target_dir"
elif [ -d "${target_dir}/orangepi-build" ]; then
local temp_build="${target_dir}/orangepi-build"
mv "$temp_build"/* "$target_dir"/ 2>/dev/null || true
rm -rf "$temp_build"
fi
if [ -f "${target_dir}/build.sh" ]; then
log "????SDKs ??????"
return 0
fi
fi
# ???2: ??? OrangePi_Build-master.zip
archive="${WORK_DIR}/SDKs/OrangePi_Build-master.zip"
if [ -f "$archive" ]; then
log "???????????: $archive"
log "?????.."
mkdir -p "$target_dir"
unzip -q "$archive" -d "$target_dir" 2>/dev/null || return 1
# ???????????????
if [ -d "${target_dir}/OrangePi_Build-master" ]; then
mv "${target_dir}/OrangePi_Build-master"/* "$target_dir"/ 2>/dev/null || true
rmdir "${target_dir}/OrangePi_Build-master" 2>/dev/null || true
fi
if [ -f "${target_dir}/build.sh" ]; then
log "????SDKs ??????"
return 0
fi
fi
return 1
fi
return 1
}
# ============================================================================
# ?????????????????
# ============================================================================
check_local_sources() {
log "???????????????????????..."
local sources_dir="${WORK_DIR}/sources"
if [ ! -d "$sources_dir" ]; then
return 1
fi
# ??????????orangepi-build ???
for archive in "$sources_dir"/{orangepi-build,u-boot,linux,kernel}*.tar* "$sources_dir"/*.zip; do
if [ -f "$archive" ]; then
log "??????????? $archive"
return 0
fi
done
return 1
}
# ============================================================================
# ??? update.img (??? orangepi-build)
# ============================================================================
build_update_img() {
local BUILD_DIR=$1
log "???????update.img..."
cd "$BUILD_DIR"
# ????????????
log "????????????:"
ls -la | head -20 >> "$LOG_FILE"
# ?????????????? chmod +x build.sh
# ?????????????????????
# ??????:
# BOARD=orangepi5ultra - ????????
# BRANCH=legacy - ??? linux5.10 (??? IMX586 ???)
# BUILD_OPT=image - ?????????
# RELEASE=bullseye - Debian Bullseye ????? # BUILD_DESKTOP=no - ????????? (??????????????yes)
if [ "$MODE" = "menu" ]; then
log "?????????????????????..."
log "?????ncurses ??????????????????"
# ncurses ????????????????? tee ??????
sudo ./build.sh
local build_rc=$?
else
log "?????????????????????..."
log "??????: BOARD=orangepi5ultra BRANCH=legacy BUILD_OPT=image KERNEL_CONFIGURE=no"
sudo ./build.sh \
BOARD=orangepi5ultra \
BRANCH=legacy \
BUILD_OPT=image \
RELEASE=bullseye \
BUILD_DESKTOP=no \
KERNEL_CONFIGURE=no 2>&1 | tee -a "$LOG_FILE"
local build_rc=${PIPESTATUS[0]}
fi
if [ ${build_rc:-1} -eq 0 ]; then
log "????????"
return 0
else
# ??????????????????????????????????????? local produced_img
produced_img=$(find "$BUILD_DIR/output/images" -name "*.img" -type f 2>/dev/null | head -1)
if [ -n "$produced_img" ]; then
log_warn "build.sh ????????????????????: $produced_img"
log_warn "?????????????????
return 0
fi
log_error "??????"
return 1
fi
}
# ============================================================================
# ?????????
# ============================================================================
verify_build() {
local BUILD_DIR=$1
log "?????????..."
local output_dir="${BUILD_DIR}/output/images"
if [ ! -d "$output_dir" ]; then
log_error "??????????? $output_dir"
return 1
fi
# ?????? update.img??????????????.img ??????????? local update_img
update_img=$(find "$output_dir" -name "*update*.img" -type f 2>/dev/null | head -1)
if [ -z "$update_img" ]; then
update_img=$(find "$output_dir" -name "*.img" -type f 2>/dev/null | head -1)
fi
if [ -z "$update_img" ]; then
log_error "???????????(*.img)"
return 1
fi
log "???????????: $update_img"
local img_size=$(du -sh "$update_img" | awk '{print $1}')
log "??????: $img_size"
# ???????? log "??? SHA256 ?????.."
sha256sum "$update_img" > "${update_img}.sha256"
log "?????????:"
cat >> "$LOG_FILE" << EOF
=== ?????? ===
???: $(date)
??????: $update_img
???: $img_size
????? $(cat "${update_img}.sha256")
EOF
return 0
}
# ============================================================================
# ?????# ============================================================================
main() {
case "${1:-}" in
menu|interactive)
MODE="menu"
;;
auto|"")
MODE="auto"
;;
*)
echo "???: $0 [auto|menu]"
echo " auto: ???????????? ncurses ?????
echo " menu: ?????? ncurses ?????????"
exit 1
;;
esac
log "=========================================="
log "Orange Pi 5 Ultra - update.img ???"
log "=========================================="
log "??????: $WORK_DIR"
log "????????): $LEGACY_WORK_DIR"
log "??????: $LOG_FILE"
log "??????: $MODE"
prepare_workspace
cd "$WORK_DIR" || { log_error "????????????"; exit 1; }
# ???? ??????? check_environment
# ???? ???git
configure_git
# ???? ??? orangepi-build
log ""
log "========== ???1: ?????? =========="
if ! get_orangepi_build; then
log_error "??? orangepi-build ???"
log ""
log "??????:"
log "1. ??????????? \${WORK_DIR}/SDKs/ ???????????"
log " - orangepi-build-next.zip"
log " - OrangePi_Build-master.zip"
log ""
log "2. ?????? SDKs ????????????:"
log " a) ????${WORK_DIR}/SDKs/ ?????????"
log " b) ?????????????????
log " c) ??????????????????????????
log ""
log "3. ????????????????? ${WORK_DIR}/sources/ ?????
log ""
log "4. ???????????:"
log " - ???????????????"
log " - ???????????? git ???: git config --global credential.helper store"
exit 1
fi
BUILD_DIR="$ORANGEPI_BUILD_DIR"
# ??.5?? ?????????
setup_build_cache_links "$BUILD_DIR"
# ??.6?? ?????? IMX586 ???
enforce_imx586_support "$BUILD_DIR"
# ???? ??? update.img
log ""
log "========== ???2: ?????? =========="
if ! build_update_img "$BUILD_DIR"; then
log_error "????????????????? $LOG_FILE"
exit 1
fi
# ???? ??????
log ""
log "========== ???3: ?????? =========="
if ! verify_build "$BUILD_DIR"; then
log_error "??????"
exit 1
fi
if ! verify_imx586_support "$BUILD_DIR"; then
log_error "IMX586 ?????????"
exit 1
fi
log ""
log "=========================================="
log "??????????
log "=========================================="
log "??????:"
log "1. ??????: scp root@www.yuquanjun.cn:/data/OrangePi_CM5/orangepi-build/output/images/*/update.img ./"
log "2. ??? RKDevTool ??balenaEtcher ??????"
log "=========================================="
}
# ????????main "$@"