【飞凌嵌入式FCU1501试用】在ARM开发板上安装完整Python环境

原创2026-07-08 14:46:36浏览0
0
Star

硬件:飞凌嵌入式 FCU1501(Rockchip RK3506,ARMv7l 架构) 系统:Buildroot 2024.02,glibc 2.38 自带 Python:3.11.8(但被大幅裁剪,缺少 zlib/ssl/xml 等核心模块)


一、问题背景

飞凌 FCU1501 是一款基于 Rockchip RK3506 的 ARMv7l 开发板,出厂自带 Buildroot 2024.02 系统和 Python 3.11.8。但实际使用中发现,这个 Python 被 Buildroot 裁剪得非常精简,大量核心 C 扩展模块缺失:

root@ok3506:~# python3 --version
Python 3.11.8

root@ok3506:~# python3 -c "import zlib"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'zlib'

root@ok3506:~# python3 -c "import ssl"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'ssl'

排查后发现缺失的模块清单如下:

模块

状态

影响

zlib

❌ 缺失

无法解压 wheel 包,pip 无法工作

ssl / _ssl

❌ 缺失

无法 HTTPS 连接 PyPI

xml / pyexpat

❌ 缺失

pip 内部依赖崩溃

hashlib

❌ 缺失

SSL 证书校验失败

sqlite3

❌ 缺失

无法使用 SQLite 数据库

bz2 / lzma

❌ 缺失

部分压缩格式不支持

最关键的是——厂家没有提供 Buildroot 源码,无法通过 make menuconfig 重新编译 Python 来开启这些模块。

这就陷入了一个死局:没有编译器(板子上没有 gcc),没有 Buildroot 源码,Python 又缺核心模块。pip 装不上,装上了也跑不起来。


二、失败的尝试

2.1 尝试 ensurepip

Python 自带的 ensurepip 模块可以引导安装 pip,但在这块板子上直接失败了:

root@ok3506:~# python3 -m ensurepip --default-pip
Traceback (most recent call last):
  ...
zipimport.ZipImportError: can't decompress data; zlib not available

原因很明确:Python 编译时没有链接 zlib,无法解压 ensurepip 内置的 wheel 包。

2.2 尝试手动解压 wheel

板子上有 unzip 命令,于是尝试手动解压 ensurepip 内置的 pip wheel:

cd /tmp
unzip -o /usr/lib/python3.11/ensurepip/_bundled/pip-24.0-py3-none-any.whl -d pip_extract
cp -r pip_extract/pip /usr/lib/python3.11/site-packages/

文件是放进去了,但运行时直接崩溃:

root@ok3506:~# pip3 --version
Traceback (most recent call last):
  ...
ImportError: libz.so.1: cannot open shared object file

pip 内部依赖 zlib 模块,不是简单放文件就能解决的。

2.3 尝试 zlib stub

甚至尝试写了一个 Python 纯实现的 zlib stub 模块来骗过 pip:

# /usr/lib/python3.11/site-packages/zlib.py
class decompressobj:
    def decompress(self, data):
        return data  # 直接返回原始数据

def decompress(data, wbits=15, bufsize=0):
    return data

pip --version 确实能跑了,但安装包时立刻报错——因为 wheel 内部的文件是真正用 zlib 压缩过的,假模块解不开。

结论:在裁剪过的 Buildroot Python 上硬装 pip,此路不通。


三、解决方案:借花献佛——使用 Debian 预编译包

3.1 思路

既然板子用的是 glibc 2.38,而 Debian Bookworm 的 armhf 架构(ARM Hard Float)与 ARMv7l 的 ABI 兼容,那 Debian 的 Python 二进制文件应该可以直接在这块板子上运行。

关键验证点:

root@ok3506:~# uname -m
armv7l

root@ok168.1.232:~# strings /lib/libc.so.6 | grep 'GNU C Library'
GNU C Library (glibc) stable release version 2.38.

root@ok3506:~# /lib/ld-linux-armhf.so.3 --version
# armhf 加载器存在,说明支持 hard-float ABI

3.2 下载 Debian Python 包

从 Debian 中国镜像下载 3 个 armhf 的 .deb 包:

mkdir -p /tmp/deb && cd /tmp/deb

# 核心三个包
curl -sL -o python3.11-minimal.deb \
  'http://ftp.cn.debian.org/debian/pool/main/p/python3.11/python3.11-minimal_3.11.2-6+deb12u7_armhf.deb'

curl -sL -o libpython3.11-minimal.deb \
  'http://ftp.cn.debian.org/debian/pool/main/p/python3.11/libpython3.11-minimal_3.11.2-6+deb12u7_armhf.deb'

curl -sL -o libpython3.11-stdlib.deb \
  'http://ftp.cn.debian.org/debian/pool/main/p/python3.11/libpython3.11-stdlib_3.11.2-6+deb12u7_armhf.deb'

3.3 提取并安装

Buildroot 系统没有 dpkg,但可以用 ar + tar 手动提取 .deb:

mkdir -p /tmp/python3.11_full && cd /tmp/python3.11_full

for deb in /tmp/deb/python3.11-minimal.deb \
           /tmp/deb/libpython3.11-minimal.deb \
           /tmp/deb/libpython3.11-stdlib.deb; do
    ar x "$deb"
    xz -d < data.tar.xz | tar xf -
    rm -f debian-binary control.tar.xz data.tar.xz
done

提取后的目录结构是标准的 usr/binusr/lib 等,直接复制到 /opt

rm -rf /opt/python3.11
mkdir -p /opt/python3.11
cp -a /tmp/python3.11_full/usr/* /opt/python3.11/

3.4 创建 wrapper 脚本

为了让新 Python 与原系统 Python 共存,创建一个 wrapper 脚本:

cat > /usr/bin/python3-full << 'EOF'
#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 "$@"
EOF
chmod +x /usr/bin/python3-full

验证:

root@ok3506:~# python3-full --version
Python 3.11.2

root@ok3506:~# python3-full -c "import zlib, ssl, xml, hashlib, sqlite3; print('All OK')"
All OK

所有缺失的模块全部恢复正常!


四、安装 pip

4.1 下载 get-pip.py

curl -sL -o /tmp/get-pip.py https://bootstrap.pypa.io/get-pip.py

4.2 安装

python3-full /tmp/get-pip.py \
  --no-warn-script-location \
  --break-system-packages \
  --trusted-host pypi.org \
  --trusted-host files.pythonhosted.org

安装成功后创建 pip wrapper:

cat > /usr/bin/pip3-full << 'EOF'
#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 -m pip "$@"
EOF
chmod +x /usr/bin/pip3-full

4.3 修复 SSL 证书

pip 能跑,但访问 PyPI 时 SSL 证书校验会失败(板子没有系统 CA 证书包)。安装 certifi 解决:

pip3-full install certifi

然后在 wrapper 脚本中加入证书路径:

export SSL_CERT_FILE=/opt/python3.11/local/lib/python3.11/dist-packages/certifi/cacert.pem

4.4 配置 pip

mkdir -p /opt/python3.11/etc
cat > /opt/python3.11/pip.conf << 'EOF'
[global]
trusted-host = pypi.org files.pythonhosted.org
break-system-packages = true
root-user-action = ignore
EOF

验证端到端:

root@ok3506:~# pip3-full --version
pip 26.1.2 from /opt/python3.11/local/lib/python3.11/dist-packages/pip (python 3.11)

root@ok3506:~# pip3-full install requests
Successfully installed requests-2.34.2

root@ok3506:~# python3-full -c "import requests; print(requests.get('https://pypi.org').status_code)"
200

五、安装 NumPy(可选)

嵌入式开发板上经常需要数值计算,但 PyPI 上没有 armv7l 的预编译 NumPy wheel,源码编译又没有 gcc。解决方案同样是借用 Debian armhf 的预编译包。

5.1 下载并提取

cd /tmp
curl -sLo python3-numpy.deb \
  'http://ftp.cn.debian.org/debian/pool/main/n/numpy/python3-numpy_1.24.2-1+deb12u1_armhf.deb'

mkdir -p /tmp/numpy_extract && cd /tmp/numpy_extract
ar x ../python3-numpy.deb
xz -d < data.tar.xz | tar xf -

cp -r usr/lib/python3.11/dist-packages/numpy* \
  /opt/python3.11/lib/python3.11/site-packages/

5.2 安装依赖库

NumPy 的 .so 文件依赖 BLAS/LAPACK 库,同样从 Debian 下载:

cd /tmp
curl -sLo libblas3.deb \
  'http://ftp.cn.debian.org/debian/pool/main/l/lapack/libblas3_3.11.0-2_armhf.deb'
curl -sLo liblapack3.deb \
  'http://ftp.cn.debian.org/debian/pool/main/l/lapack/liblapack3_3.11.0-2_armhf.deb'
curl -sLo libgfortran5.deb \
  'http://ftp.cn.debian.org/debian/pool/main/g/gcc-12/libgfortran5_12.2.0-14+deb12u1_armhf.deb'

mkdir -p /tmp/lib_extract && cd /tmp/lib_extract
for deb in /tmp/libblas3.deb /tmp/liblapack3.deb /tmp/libgfortran5.deb; do
    ar x "$deb"
    xz -d < data.tar.xz | tar xf -
    rm -f debian-binary control.tar.xz data.tar.xz
done

# 复制 .so 到系统库目录
cp $(find . -name '*.so*') /lib/

5.3 更新 PYTHONPATH

wrapper 脚本的 PYTHONPATH 需要包含 site-packages:

export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload:/opt/python3.11/lib/python3.11/site-packages:/opt/python3.11/local/lib/python3.11/dist-packages

5.4 测试

import numpy as np
import time

# 基本功能
a = np.array([1, 2, 3, 4, 5])
print(f"版本: {np.__version__}")
print(f"数组: {a}")
print(f"均值: {np.mean(a)}")

# 线性代数
m = np.array([[1, 2], [3, 4]])
print(f"行列式: {np.linalg.det(m)}")
print(f"特征值: {np.linalg.eig(m)[0]}")

# FFT
signal = np.array([1, 2, 1, -1, -2, -1])
print(f"FFT: {np.round(np.fft.fft(signal), 2)}")

# 性能
t0 = time.time()
result = np.dot(np.random.rand(1000, 1000), np.random.rand(1000, 1000))
print(f"1000x1000 矩阵乘法: {time.time()-t0:.1f}s")

输出:

版本: 1.24.2
数组: [1 2 3 4 5]
均值: 3.0
行列式: -2.0
特征值: [-0.37  5.37]
FFT: [0.+0.j  3.-5.2j  0.+0.j  0.+0.j  0.+0.j  3.+5.2j]
1000x1000 矩阵乘法: 20.1s

全部功能正常。1000×1000 矩阵乘法 20 秒,ARMv7l 无 NEON 优化的预期水平。


六、磁盘空间优化

嵌入式开发板存储空间有限(根分区 458M),安装 Python + pip 后空间紧张。以下是实际清理记录:

6.1 清理临时文件

# 安装过程中产生的临时文件
rm -rf /tmp/pip_extract /tmp/setuptools_extract
rm -f /root/get-pip.py
rm -rf /tmp/deb /tmp/deb_extract /tmp/python3.11_full /tmp/numpy_extract /tmp/lib_extract

6.2 清理 pip 缓存

rm -rf /root/.cache/pip

6.3 删除测试文件

# setuptools 自带的测试目录
rm -rf /opt/python3.11/local/lib/python3.11/dist-packages/setuptools/tests
rm -rf /opt/python3.11/local/lib/python3.11/dist-packages/setuptools/_distutils/tests

6.4 清理 .pyc 缓存

Python 运行时会自动生成 .pyc 字节码缓存文件,在嵌入式设备上意义不大:

find /opt/python3.11 -type d -name '__pycache__' -exec rm -rf {} +

在 wrapper 脚本中加入环境变量,防止 .pyc 自动重建:

export PYTHONDONTWRITEBYTECODE=1

6.5 清理效果

已用

可用

使用率

清理前

435M

0M

100%

清理后

296M

130M

70%

共释放 139M 空间。


七、最终环境概览

7.1 完整的 wrapper 脚本

/usr/bin/python3-full

#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload:/opt/python3.11/lib/python3.11/site-packages:/opt/python3.11/local/lib/python3.11/dist-packages
export SSL_CERT_FILE=/opt/python3.11/local/lib/python3.11/dist-packages/certifi/cacert.pem
export PYTHONDONTWRITEBYTECODE=1
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 "$@"

/usr/bin/pip3-full

#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload:/opt/python3.11/lib/python3.11/site-packages:/opt/python3.11/local/lib/python3.11/dist-packages
export SSL_CERT_FILE=/opt/python3.11/local/lib/python3.11/dist-packages/certifi/cacert.pem
export PYTHONDONTWRITEBYTECODE=1
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 -m pip "$@"

7.2 日常使用

# 查看版本
python3-full --version    # Python 3.11.2
pip3-full --version       # pip 26.1.2

# 安装第三方包
pip3-full install requests

# 原系统 Python 不受影响
python3 --version         # Python 3.11.8 (Buildroot 原始版)

7.3 安装其他 Debian 预编译包的通用方法

如果某个包在 PyPI 上没有 armv7l 的 wheel(很常见),可以用同样的方法从 Debian armhf 仓库安装:

  1. https://packages.debian.org/bookworm/armhf/ 搜索包名

  2. 下载 .deb 文件

  3. ar x + xz -d | tar xf 提取

  4. 将 Python 包复制到 /opt/python3.11/lib/python3.11/site-packages/

  5. .so 依赖库复制到 /lib/


八、总结

方案

可行性

说明

Buildroot 重新编译

✅ 最佳

需要源码,厂家未提供

板上源码编译

❌ 不可行

板上无 gcc,无 Python dev headers

ensurepip 引导

❌ 不可行

Python 缺 zlib,无法解压 wheel

zlib stub 绕过

❌ 不可行

ssl、xml 也缺失,pip 无法正常工作

Debian armhf 预编译包

可行

glibc 兼容,ABI 匹配,完美运行

核心原理:飞凌 FCU1501 使用 glibc 2.38,与 Debian Bookworm armhf 的 ABI 完全兼容。通过提取 Debian 预编译的 Python 二进制和标准库,可以在不重新编译的情况下获得完整的 Python 环境。

这套方案的优点:

  • 零编译:不需要 gcc,不需要源码

  • 零冲突:与原系统 Python 隔离运行,互不干扰

  • 完整功能:zlib、ssl、xml、sqlite3 等模块全部可用

  • pip 可用:可以正常从 PyPI 安装纯 Python 包

局限:

  • 需要联网下载

  • 根分区空间有限(458M),需精打细算

  • 需要编译的包(如 NumPy)需额外从 Debian 仓库获取预编译版本


本文记录了在飞凌 FCU1501 开发板上从零搭建完整 Python 环境的全过程,希望能帮助到同样受困于 Buildroot 裁剪 Python 的嵌入式开发者。如果你有 Buildroot 源码,还是建议通过 make menuconfig 开启 Python 的 zlib/ssl/xml 模块重新编译,那才是最干净的方案。