Android13 SDK 搭建
准备工作
电脑配置:编译android系统对电脑的要求是非常高的,尤其是内存如果内存太小根本没办法编译,下面是我的电脑配置,希望大家编译的适合配置尽量比我高,如果CPU性能比我差也要确保内存比我大,CPU会影响编译的速度,内存小了直接会报错。
![]() | ![]() |
|---|---|
ubnutu版本信息:
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy2
3
4
5
6
7
8
9
10
11
12
下载 SDK
开发板资料我们通过网盘提供,其中 SDK 资料目录如下大家自行下载:
由于 SDK 压缩包体积较大,我们将一个完整的 SDK 分割成多个分卷(00, 01, 02...),在下载或传输过程中任何一个分卷损坏都会导致解压失败。
将 tspi-1F-android13-SDK 整个文件夹都下载下来即可。
分割多个分卷的好处
- 突破文件大小限制: 某些云存储的单个文件限制 2-5GB,不方便上传、下载、备份。
- 便于传输和存储:分批次上传到云存储网盘,避免因网络中断重传整个大文件。
- 容错性:如果某个分卷损坏,只需要重新下载损坏的那个分卷而不需要重新下载整个 SDK
文件介绍
百度网盘中的文件介绍。
README.md
SDK 介绍:有什么,怎么快速开始使用,怎么校验验证。
extract_sdk.sh
自动解压脚本,一键执行分卷校验、内存检查、分卷合并、SDK解压、SDK文件校验等功能。
rk3566_android13_sdk_20251122.tar.xz.part.xx
完整SDK分卷后的分卷压缩包,后期需要使用他们合并再解压。自动解压脚本使用,解压完成前不建议删除。
file_checksums.sha256
用于校验解压完成后的文件完整性。自动解压脚本使用,解压完成前不建议删除。
sdk_parts_checksums.sha256
使用 sha256 验证分卷文件的完整性。自动解压脚本使用,解压完成前不建议删除。
sdk_parts_checksums.md5
使用 md5 验证分卷文件的完整性,用户可自行校验。
SDK 解压
确保系统有足够的磁盘空间
我们提供了自动解压脚本 extract_sdk.sh ,其与 SDK 分卷同处一个文件夹下。它会自动执行分卷校验、内存检查、分卷合并、SDK解压、SDK文件校验等功能。
如果要在当前目录解压则输入命令:
不建议直接解压到当前文件夹
./extract_sdk.sh如果要解压到指定目录,则输入命令格式:
./extract_sdk.sh 要解压的目录例如解压到 /home/liguoyi/Desktop 下,则运行 ./extract_sdk.sh /home/liguoyi/Desktop。
本文章将解压到上一层目录的 tspi-1f-android13-sdk。如果没有这个文件夹就会自动创建。
../表示返回上一层文件夹,./表示当前文件夹。
./extract_sdk.sh ../tspi-1f-android13-sdk在脚本执行时,会进行文件校验,校验时所有文件都显示 OK,则说明文件完整,可以安全解压。如果有文件校验失败,需要重新下载对应的压缩包。
![]() |
|---|
手动解压方法
如果不想用自动解压脚本,也可以手动解压。
先校验下载下来的文件是否正常完整。
sha256sum -c sdk_parts_checksums.sha256校验通过后,开始解压。
# 先合并所有分卷
cat rk3566_android13_sdk_*.tar.xz.part.* > combined.tar.xz
# 解压
xz -d combined.tar.xz
tar -xf combined.tar
# 根据情况清理SDK压缩包
rm combined.tar2
3
4
5
6
7
8
9
extract_sdk.sh 脚本源码
#!/bin/bash
# RK3566 SDK 智能解压工具
# 自动验证完整性并解压
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 默认输出目录
OUTPUT_DIR="${1:-./extracted_sdk}"
SDK_PATTERN="rk3566_android13_sdk_*.tar.xz.part.*"
echo -e "${GREEN}RK3566 SDK 解压工具${NC}"
echo "================================"
# 检查文件是否存在
check_files_exist() {
if ! ls $SDK_PATTERN >/dev/null 2>&1; then
echo -e "${RED}错误: 未找到SDK分卷文件${NC}"
echo "请确保以下文件存在:"
echo " - rk3566_android13_sdk_YYYYMMDD.tar.xz.part.* (分卷)"
exit 1
fi
return 0
}
# 验证文件完整性
verify_integrity() {
echo -e "${YELLOW}[1/4] 验证文件完整性...${NC}"
if [ -f "sdk_parts_checksums.sha256" ]; then
echo "使用SHA256验证分卷文件..."
if sha256sum -c sdk_parts_checksums.sha256; then
echo -e "${GREEN}✓ 所有分卷验证通过${NC}"
else
echo -e "${RED}✗ 分卷文件损坏,请重新下载${NC}"
exit 1
fi
else
echo -e "${YELLOW}⚠ 未找到校验文件,跳过完整性验证${NC}"
fi
}
# 检查磁盘空间
check_disk_space() {
echo -e "${YELLOW}[2/4] 检查磁盘空间...${NC}"
local total_size=0
for f in $SDK_PATTERN; do
if [ -f "$f" ]; then
size=$(stat -c%s "$f" 2>/dev/null || du -b "$f" | cut -f1)
total_size=$((total_size + size))
fi
done
local required_space=$((total_size * 3)) # 解压需要2-3倍空间
local available_space=$(df . | awk 'NR==2 {print $4 * 1024}')
if [ "$available_space" -lt "$required_space" ]; then
echo -e "${RED}✗ 磁盘空间不足${NC}"
echo "需要: $(echo "scale=2; $required_space/1024/1024/1024" | bc) GB"
echo "可用: $(echo "scale=2; $available_space/1024/1024/1024" | bc) GB"
exit 1
fi
echo -e "${GREEN}✓ 磁盘空间充足${NC}"
}
# 解压文件
extract_files() {
echo -e "${YELLOW}[3/4] 解压SDK...${NC}"
# 创建输出目录
mkdir -p "$OUTPUT_DIR"
echo "合并分卷文件..."
cat $SDK_PATTERN > "$OUTPUT_DIR/combined.tar.xz"
echo "解压xz压缩包..."
cd "$OUTPUT_DIR"
xz -d combined.tar.xz
echo "解压tar包..."
tar -xf combined.tar
rm -f combined.tar
cd ..
echo -e "${GREEN}✓ 解压完成${NC}"
}
# 验证解压结果
verify_extraction() {
echo -e "${YELLOW}[4/4] 验证解压结果...${NC}"
if [ -f "file_checksums.sha256" ]; then
echo "验证解压文件完整性..."
cd "$OUTPUT_DIR"
if sha256sum -c ../file_checksums.sha256; then
echo -e "${GREEN}✓ 所有文件验证通过${NC}"
else
echo -e "${YELLOW}⚠ 部分文件验证失败${NC}"
fi
cd ..
else
echo -e "${YELLOW}⚠ 未找到文件校验信息,跳过验证${NC}"
fi
}
# 主流程
main() {
echo -e "${BLUE}输出目录: $OUTPUT_DIR${NC}"
check_files_exist
verify_integrity
check_disk_space
extract_files
verify_extraction
echo ""
echo -e "${GREEN}================================"
echo "SDK安装完成!"
echo "解压位置: $OUTPUT_DIR"
echo "================================"
echo -e "${NC}"
}
main "$@"2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
脚本方法同步 SDK 源码
我们之前解压出来后是一个 .repo 的隐藏文件夹。
隐藏文件夹可以通过
ls -all查看。
![]() |
|---|
所有的源码都被记录在了 .repo 这个文件夹中,各个 git 项目都是通过 repo 进行管理的。现在我们需要使用命令将源码同步出来。
我们提供了一个快速同步 SDK 脚本 tspi-sdk-init.sh,其会自动执行配置软件源、安装依赖工具、系统配置、检查环境、同步 SDK 等操作。
此脚本会自动安装编译 Android13 这个 SDK 所需要所有工具和依赖,所以运行这个工具,不出错之后就可以直接开始进行编译了。
#执行脚本
./tspi-sdk-init.sh2
tspi-sdk-init.sh 脚本源码
#!/bin/bash
###############################################################################
# TaishanPi-1F SDK 宿主机环境初始化脚本
# 适用于: Ubuntu 22.04 LTS (Jammy Jellyfish)
# 功能: 自动配置编译所需的完整开发环境
###############################################################################
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'
# 日志函数
log_info() { echo -e "${GREEN}✓ $* ${NC}"; }
log_warn() { echo -e "${YELLOW}⚠ $* ${NC}"; }
log_error() { echo -e "${RED}✗ $* ${NC}"; }
log_step() { echo -e "${CYAN}${BOLD}▶ $* ${NC}"; }
log_debug() { echo -e "${DIM} → $* ${NC}"; }
# 进度条函数
show_progress() {
local current=$1
local total=$2
local message=$3
local width=50
local percentage=$((current * 100 / total))
local completed=$((current * width / total))
local remaining=$((width - completed))
printf "\r${CYAN}[${NC}"
printf "${GREEN}%${completed}s${NC}" | tr ' ' '█'
printf "${DIM}%${remaining}s${NC}" | tr ' ' '░'
printf "${CYAN}]${NC} ${BOLD}${percentage}%%${NC} ${message}"
if [ $current -eq $total ]; then
echo ""
fi
}
# 旋转加载动画
show_spinner() {
local pid=$1
local message=$2
local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local i=0
while kill -0 $pid 2>/dev/null; do
local temp=${spinstr:i++%${#spinstr}:1}
printf "\r${CYAN}${temp}${NC} ${message}..."
sleep 0.1
done
printf "\r${GREEN}✓${NC} ${message}... ${GREEN}完成${NC}\n"
}
# 打印分隔线
# print_separator() {
# local char="${1:-═}"
# local color="${2:-$CYAN}"
# printf "${color}"
# printf '%*s' "${COLUMNS:-80}" '' | tr ' ' "$char"
# printf "${NC}\n"
# }
# 打印标题框
print_box() {
local message="$1"
local color="${2:-$CYAN}"
local length=${#message}
local padding=4
local total_length=$((length + padding * 2))
echo ""
printf "${color}╔"
printf '%*s' "$total_length" '' | tr ' ' '═'
printf "╗${NC}\n"
printf "${color}║"
printf "%*s" $padding ''
printf "${BOLD}${WHITE}%s${NC}" "$message"
printf "%*s" $padding ''
printf "${color}║${NC}\n"
printf "${color}╚"
printf '%*s' "$total_length" '' | tr ' ' '═'
printf "╝${NC}\n"
echo ""
}
# 初始化检测结果变量
ALL_CHECKS_PASS=true
# 检查是否通过sudo运行
check_sudo_privilege() {
if [[ $EUID -ne 0 ]]; then
log_error "必须使用 sudo 运行此脚本!"
echo -e "请执行:\n ${GREEN}sudo $0 $@${NC}"
exit 1
fi
log_info "权限检查通过"
}
# 配置APT镜像源
configure_apt_mirror() {
log_step "配置 APT 镜像源"
echo ""
# 备份原有源列表
if [[ ! -f /etc/apt/sources.list.bak ]]; then
cp /etc/apt/sources.list /etc/apt/sources.list.bak
log_debug "已备份原有源列表"
fi
# 写入新的镜像源配置
cat > /etc/apt/sources.list <<'EOF'
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.cernet.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src http://mirrors.cernet.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.cernet.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src http://mirrors.cernet.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.cernet.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src http://mirrors.cernet.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# 安全更新源(保留官方源以确保及时获取安全补丁)
deb http://mirrors.cernet.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://mirrors.cernet.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
EOF
log_debug "镜像源配置写入完成"
# 清理旧的软件包缓存
log_debug "清理 APT 缓存"
apt-get autoremove -y >/dev/null 2>&1 &
show_spinner $! "清理旧软件包"
apt-get clean
rm -rf /var/lib/apt/lists/*
# 更新软件包列表
log_debug "更新软件包索引"
apt-get update -o Acquire::http::No-Cache=True >/dev/null 2>&1 &
show_spinner $! "同步软件包列表"
apt-get update >/dev/null 2>&1 && apt-get install -f -y >/dev/null 2>&1
log_info "APT 源配置完成"
echo ""
}
# 系统版本检查函数: 必须是 Ubuntu 22.04 LTS (Jammy Jellyfish)
check_ubuntu_version() {
local required_version="22.04"
local required_codename="jammy"
local is_supported=0
log_step "检查系统版本"
echo ""
# 通过LSB信息检查版本
if command -v lsb_release &> /dev/null; then
local os_id=$(lsb_release -si)
local os_release=$(lsb_release -sr)
local os_codename=$(lsb_release -sc)
if [[ "$os_id" == "Ubuntu" && "$os_release" == "$required_version" && "$os_codename" == "$required_codename" ]]; then
is_supported=1
fi
# 备用方案:通过os-release文件检查
elif [[ -f /etc/os-release ]]; then
source /etc/os-release
if [[ "$ID" == "ubuntu" && "$VERSION_ID" == "$required_version" && "$UBUNTU_CODENAME" == "$required_codename" ]]; then
is_supported=1
fi
fi
if [[ $is_supported -eq 1 ]]; then
log_info "系统版本: Ubuntu ${required_version} LTS"
echo ""
return 0
else
log_error "不兼容的系统版本!"
log_debug "需要: Ubuntu ${required_version} LTS (Jammy Jellyfish)"
log_debug "当前: $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d'"' -f2)"
echo ""
ALL_CHECKS_PASS=false
return 1
fi
}
# 检查CPU架构支持
check_cpu() {
log_step "检查 CPU 架构"
echo ""
local arch_support=0
grep -q -E 'vmx|svm' /proc/cpuinfo && arch_support=1
if [[ $(uname -m) != "x86_64" ]]; then
log_error "仅支持 x86_64 架构"
echo ""
ALL_CHECKS_PASS=false
return 1
elif [[ $arch_support -eq 0 ]]; then
log_warn "CPU 虚拟化未启用 (可能影响性能)"
else
log_info "CPU 架构: x86_64 (VT-x/AMD-V)"
fi
echo ""
return 0
}
# 加载必要的内核模块
load_kernel_modules() {
log_step "加载内核模块"
echo ""
declare -a required_modules=("overlay" "veth" "bridge")
local total=${#required_modules[@]}
local current=0
for module in "${required_modules[@]}"; do
((current++))
if ! lsmod | grep -q "^$module"; then
if modprobe "$module" 2>/dev/null; then
show_progress $current $total "加载模块: $module"
else
show_progress $current $total "跳过模块: $module (已内置)"
fi
else
show_progress $current $total "检查模块: $module"
fi
done
log_info "内核模块加载完成"
echo ""
}
# 网络连接检查
check_network() {
log_step "检查网络连接"
echo ""
local check_passed=true
local tests=("CERNET镜像" "Ubuntu CDN")
local current=0
local total=2
# 测试镜像源
((current++))
local MIRROR_URL="http://mirrors.cernet.edu.cn/ubuntu/"
if curl --output /dev/null --silent --head --fail --connect-timeout 10 "$MIRROR_URL" 2>/dev/null; then
show_progress $current $total "${tests[0]}"
else
show_progress $current $total "${tests[0]} (跳过)"
check_passed=false
fi
if $check_passed; then
log_info "网络连接正常"
else
log_error "网络连接异常,请检查网络设置"
fi
echo ""
return 0
}
# 存储空间检查
check_storage() {
log_step "检查磁盘空间"
echo ""
local min_disk=300 # 最小磁盘空间(GB) - SDK编译需要大量空间
local available=$(df -BG / | awk 'NR==2 {print $4}' | tr -d 'G')
local used=$(df -BG / | awk 'NR==2 {print $3}' | tr -d 'G')
local total=$(df -BG / | awk 'NR==2 {print $2}' | tr -d 'G')
local percentage=$((used * 100 / total))
# 显示磁盘使用情况
show_progress $used $total "磁盘使用率 (${available}GB 可用)"
if [[ $available -lt $min_disk ]]; then
log_error "磁盘空间不足 (需要 ${min_disk}GB)"
echo ""
return 1
else
log_info "存储空间充足 (${available}GB)"
fi
echo ""
return 0
}
# 安装核心开发工具和依赖
install_dependencies() {
log_step "安装开发工具和依赖包"
echo ""
# 核心工具包列表
local BASIC_TOOLS="mount util-linux bash-completion vim sudo locales tzdata time rsync bc"
local PYTHON_TOOLS="python3 python3-pip python2 whiptail"
local BUILD_TOOLS="build-essential crossbuild-essential-arm64 ccache"
local DEV_TOOLS="git ssh make gcc g++"
local LIBS="libssl-dev liblz4-tool expect patchelf chrpath gawk texinfo diffstat"
local CROSS_TOOLS="binfmt-support qemu-user-static bison flex fakeroot cmake"
local UTILS="unzip device-tree-compiler ncurses-dev net-tools u-boot-tools dpkg-dev"
local EXTRA_LIBS="libgmp-dev libmpc-dev binutils libelf-dev curl pv"
local DEV_UTILS="devscripts equivs software-properties-common linux-headers-generic"
local CROSS_COMPILER="gcc-aarch64-linux-gnu g++-aarch64-linux-gnu"
local SYSTEM_TOOLS="debootstrap cpio iputils-ping pigz tar aria2"
local EXTERN_TOOLS="libncurses5 zip libgtk2.0-dev libxxf86vm1 less repo"
# 合并所有包
local ALL_PACKAGES="$BASIC_TOOLS $PYTHON_TOOLS $BUILD_TOOLS $DEV_TOOLS $LIBS $CROSS_TOOLS $UTILS $EXTRA_LIBS $DEV_UTILS $CROSS_COMPILER $SYSTEM_TOOLS $EXTERN_TOOLS"
log_debug "准备安装软件包 (这可能需要几分钟)"
# 批量安装(减少apt调用次数)
(
apt-get install -y --no-install-recommends $ALL_PACKAGES > /tmp/apt-install.log 2>&1
) &
show_spinner $! "安装系统依赖包"
if [ $? -eq 0 ]; then
log_info "系统依赖包安装完成"
else
log_error "部分软件包安装失败"
log_debug "详细日志: /tmp/apt-install.log"
echo ""
ALL_CHECKS_PASS=false
return 1
fi
# 安装 Python 依赖
(
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir pyelftools >/dev/null 2>&1
) &
show_spinner $! "安装 Python 依赖包"
log_info "Python 依赖安装完成"
# 配置 Python2 符号链接
if [ -x /usr/bin/python2 ] && [ ! -e /usr/bin/python ]; then
ln -sf /usr/bin/python2 /usr/bin/python
log_debug "Python2 符号链接已创建"
fi
echo ""
return 0
}
# 安装和配置 live-build (Debian 系统构建工具)
install_live_build() {
log_step "安装 live-build 工具"
echo ""
if command -v lb &> /dev/null; then
log_debug "live-build 已安装"
echo ""
return 0
fi
local TMP_DIR="/tmp/live-build-install"
mkdir -p "$TMP_DIR"
(
cd "$TMP_DIR"
git clone https://salsa.debian.org/live-team/live-build.git --depth 1 -b debian/1%20230131 >/dev/null 2>&1
cd live-build
rm -rf manpages/po/
make install >/dev/null 2>&1
cd /
rm -rf "$TMP_DIR"
) &
show_spinner $! "编译安装 live-build"
if [ $? -eq 0 ] && command -v lb &> /dev/null; then
log_info "live-build 安装完成"
log_debug "版本: $(lb --version 2>&1 | head -1)"
else
log_error "live-build 安装失败"
ALL_CHECKS_PASS=false
return 1
fi
echo ""
return 0
}
# 配置 QEMU 和 binfmt 支持
configure_qemu() {
log_step "配置 QEMU ARM64 支持"
echo ""
# 确保 binfmt-support 已安装
if ! dpkg -l | grep -q binfmt-support; then
apt-get install -y --no-install-recommends binfmt-support >/dev/null 2>&1
fi
local steps=("启用 binfmt" "注册 qemu-aarch64" "验证配置")
local current=0
local total=3
# 启用 QEMU aarch64 支持
((current++))
update-binfmts --enable qemu-aarch64 >/dev/null 2>&1
show_progress $current $total "${steps[0]}"
# 注册处理器
((current++))
sleep 0.3
show_progress $current $total "${steps[1]}"
# 验证状态
((current++))
if update-binfmts --display qemu-aarch64 2>&1 | grep -q "enabled"; then
show_progress $current $total "${steps[2]}"
log_info "QEMU ARM64 支持配置完成"
else
show_progress $current $total "${steps[2]} (警告)"
log_warn "QEMU 配置可能不完整"
fi
echo ""
return 0
}
# 同步 SDK 源码
sync_Linux_sdk() {
log_step "同步 SDK 源码"
echo ""
local REPO_EXEC=".repo/repo/repo"
local SYNC_JOBS=$(nproc 2>/dev/null || echo 4)
# 检查 repo 命令
if [[ ! -x "$REPO_EXEC" ]]; then
log_error "repo 工具未找到"
echo ""
ALL_CHECKS_PASS=false
return 1
fi
# 获取真实用户信息
local REAL_USER="${SUDO_USER:-$USER}"
local REAL_UID=$(id -u "$REAL_USER" 2>/dev/null || echo "")
local REAL_GID=$(id -g "$REAL_USER" 2>/dev/null || echo "")
log_debug "同步参数: -l (本地) -j$SYNC_JOBS (并发)"
log_debug "这可能需要较长时间,请耐心等待..."
echo ""
# 执行同步
if $REPO_EXEC sync -l -j$SYNC_JOBS; then
echo ""
log_info "SDK 源码同步完成"
# 如果是通过 sudo 运行,恢复文件权限为普通用户
if [[ -n "$SUDO_USER" && -n "$REAL_UID" && -n "$REAL_GID" ]]; then
log_debug "恢复文件权限为用户: $REAL_USER"
(
chown -R "$REAL_UID:$REAL_GID" . 2>/dev/null
) &
show_spinner $! "修正文件权限"
log_info "文件权限已恢复"
fi
else
echo ""
log_error "SDK 同步失败"
log_debug "请检查网络连接或手动执行: $REPO_EXEC sync -l -j$SYNC_JOBS"
ALL_CHECKS_PASS=false
return 1
fi
echo ""
return 0
}
# 配置时区
configure_timezone() {
log_step "配置系统时区"
echo ""
if [ -f /usr/share/zoneinfo/Asia/Shanghai ]; then
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
log_info "时区: Asia/Shanghai"
else
log_warn "时区配置跳过"
fi
echo ""
return 0
}
# 检查QEMU支持(保留用于最终验证)
check_qemu() {
log_step "验证 QEMU 环境"
echo ""
local checks=("QEMU 二进制" "binfmt 注册")
local current=0
local total=2
((current++))
if which qemu-aarch64-static &> /dev/null; then
show_progress $current $total "${checks[0]}"
else
show_progress $current $total "${checks[0]} (失败)"
log_error "QEMU 静态二进制未找到"
echo ""
ALL_CHECKS_PASS=false
return 1
fi
((current++))
if [[ -f /proc/sys/fs/binfmt_misc/qemu-aarch64 ]]; then
show_progress $current $total "${checks[1]}"
else
show_progress $current $total "${checks[1]} (失败)"
log_error "aarch64 架构支持未启用"
echo ""
ALL_CHECKS_PASS=false
return 1
fi
log_info "QEMU 环境验证通过"
echo ""
return 0
}
# 主执行流程
main() {
clear
echo ""
print_box "TaishanPi-1F SDK 环境初始化" "$MAGENTA"
echo -e "${DIM}适用于: Ubuntu 22.04 LTS (Jammy Jellyfish)${NC}"
echo -e "${DIM}版本: v1.0 | 更新时间: 2025-11-18${NC}"
echo ""
# print_separator
# 阶段 1: 权限和基础检查
print_box "阶段 1/6: 系统环境检查" "$BLUE"
check_sudo_privilege "$@"
check_ubuntu_version || exit 1
check_cpu
check_storage
# 阶段 2: 配置软件源和网络
print_box "阶段 2/6: 配置系统环境" "$BLUE"
configure_apt_mirror
check_network
# 阶段 3: 安装依赖和工具
print_box "阶段 3/6: 安装开发工具" "$BLUE"
install_dependencies || exit 1
install_live_build || exit 1
# 阶段 4: 系统配置
print_box "阶段 4/6: 配置系统功能" "$BLUE"
load_kernel_modules
configure_qemu || exit 1
configure_timezone
# 阶段 5: Repo 配置检查
print_box "阶段 5/6: Repo 配置检查" "$BLUE"
log_step "检查 Repo 环境"
echo ""
if [[ ! -d ".repo" ]]; then
log_error "未找到 .repo 目录"
log_debug "请先执行: repo init -u <manifest_url>"
ALL_CHECKS_PASS=false
else
log_info "Repo 环境已就绪"
# 配置 manifest 仓库完全本地化(使用相对路径,可移植)
if [[ -d ".repo/manifests/.git" ]]; then
local MANIFEST_DIR=".repo/manifests"
# 确保在正确的分支上
local current_branch=$(cd "$MANIFEST_DIR" && git symbolic-ref --short HEAD 2>/dev/null || echo "")
if [[ -z "$current_branch" ]]; then
log_warn "manifest 处于 detached HEAD,切换到分支"
# 尝试切换到 taishanpi-1f-local 分支
if (cd "$MANIFEST_DIR" && git show-ref --verify --quiet refs/heads/taishanpi-1f-local); then
(cd "$MANIFEST_DIR" && git checkout taishanpi-1f-local >/dev/null 2>&1)
current_branch="taishanpi-1f-local"
log_info "已切换到 taishanpi-1f-local 分支"
fi
fi
# 配置分支跟踪本地(而非远程),防止 repo sync 切换分支
if [[ -n "$current_branch" ]]; then
(
cd "$MANIFEST_DIR"
# 使用相对路径配置 remote,确保可移植
git config remote.origin.url ".repo/manifests"
git config branch."$current_branch".remote "."
git config branch."$current_branch".merge "refs/heads/$current_branch"
# 同时配置 default 分支
if git show-ref --verify --quiet refs/heads/default; then
git config branch.default.remote "."
git config branch.default.merge "refs/heads/$current_branch"
fi
) >/dev/null 2>&1
log_debug "Manifest 分支: $current_branch (本地跟踪,可移植)"
fi
fi
# 显示当前 manifest 文件
if [[ -f ".repo/manifest.xml" ]]; then
local manifest_file=$(grep -oP '(?<=name=")[^"]+' .repo/manifest.xml 2>/dev/null | head -1)
if [[ -n "$manifest_file" ]]; then
log_debug "当前 Manifest: $manifest_file"
fi
fi
fi
echo ""
# 阶段 6: 最终验证
print_box "阶段 6/6: 环境验证" "$BLUE"
check_qemu || exit 1
# 询问是否同步 SDK
echo ""
echo -e "${YELLOW}${BOLD}是否立即同步 Linux SDK 源码?${NC}"
echo -e "${DIM}(同步需要较长时间,也可以稍后手动执行)${NC}"
echo ""
read -p "$(echo -e ${CYAN}是否继续? [Y/n]: ${NC})" -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then
echo ""
print_box "同步 Linux SDK" "$BLUE"
sync_Linux_sdk || {
log_warn "SDK 同步失败,但环境已配置完成"
log_debug "可稍后手动执行: .repo/repo/repo sync -l"
}
else
log_info "跳过 SDK 同步"
log_debug "可稍后手动执行: .repo/repo/repo sync -l"
echo ""
fi
# 确保所有文件权限正确(如果通过 sudo 运行)
if [[ -n "$SUDO_USER" ]]; then
local REAL_USER="$SUDO_USER"
local REAL_UID=$(id -u "$REAL_USER" 2>/dev/null)
local REAL_GID=$(id -g "$REAL_USER" 2>/dev/null)
if [[ -n "$REAL_UID" && -n "$REAL_GID" ]]; then
log_step "修正工作目录权限"
echo ""
(
chown -R "$REAL_UID:$REAL_GID" "$(pwd)" 2>/dev/null
) &
show_spinner $! "恢复用户权限: $REAL_USER"
log_info "工作目录权限已修正"
echo ""
fi
fi
# 最终结果汇总
if $ALL_CHECKS_PASS; then
print_box "✓ 环境初始化成功" "$GREEN"
print_box "✓ SDK同步完成" "$GREEN"
echo ""
else
print_box "✗ 环境初始化失败" "$RED"
echo -e "${BOLD}${WHITE}排查建议:${NC}"
echo -e " ${RED}1.${NC} 确认系统版本为 Ubuntu 22.04 LTS"
echo -e " ${RED}2.${NC} 检查网络连接是否正常"
echo -e " ${RED}3.${NC} 确保磁盘空间充足(建议 400GB+)"
echo -e " ${RED}4.${NC} 查看详细日志: ${YELLOW}/tmp/apt-install.log${NC}"
echo ""
exit 1
fi
}
# 脚本入口
ALL_CHECKS_PASS=true
main "$@"2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
同步完成后,就可以在目录下看到相关的源码了。
手动方法同步 SDK 源码
解压完成后只有 .repo 目录我们还需要通过 repo 命令把代码同步出来,运行 repo 命令需要我们 ubuntu 安装有 git 和 python 否则会报错。
更新软件包
sudo apt-get update安装git
sudo apt-get install git -y安装repo
sudo apt install repo -y安装python2
sudo apt-get install python2.7安装python3
sudo apt-get install python3python版本切换设置,为什么要切换呢因为有时候我们会用python2有时候会用python3
$设置 python2.7
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
$设置 python3.6
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 22
3
4
切换
sudo update-alternatives --config python切换到python2.7
$ sudo update-alternatives --config python
There are 2 choices for the alternative python (providing /usr/bin/python).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/python3.6 2 auto mode
1 /usr/bin/python2.7 1 manual mode
2 /usr/bin/python3.6 2 manual mode
Press <enter> to keep the current choice[*], or type selection number: 12
3
4
5
6
7
8
9
10
同步
.repo/repo/repo sync -l -j88同步成功



