2、开发环境搭建:Ubuntu虚拟机配置、交叉编译工具链安装、NFS/TFTP服务配置

好,咱们正式开始动手了。这一章要解决的是「工欲善其事,必先利其器」的问题。很多新手拿到海思的开发板,第一反应就是直接开干,结果编译报错、烧录失败、网络不通……折腾半天连个灯都点不亮。我当年也踩过这些坑,所以这一章咱们把环境彻底搭好,后面才能跑得顺畅。

2.1 Ubuntu虚拟机配置

我个人习惯用 Ubuntu 18.04 或 20.04 LTS 版本。为什么?因为海思官方的 SDK 对这两个版本支持最好。你非要用最新的 22.04 或 24.04,也不是不行,但可能会遇到一些库版本不兼容的问题,到时候还得自己折腾。嗯,这里要注意:稳定第一,版本别追新

虚拟机配置建议(以 VMware Workstation 为例):

  • 内存:至少 8GB,推荐 16GB。编译海思的 SDK 时,内存小了会卡死。
  • CPU:分配 4 核以上。交叉编译是并行任务,核越多越快。
  • 硬盘:至少 80GB,建议 120GB。SDK 解压后就有十几 G,加上编译中间文件,空间很快就满了。
  • 网络:选择「桥接模式」。这样开发板和虚拟机可以在同一个网段,方便 NFS 和 TFTP 通信。

安装完 Ubuntu 后,第一件事是换源。国内用默认源下载东西慢得让人抓狂。我建议换成清华或阿里的镜像源,速度能快几十倍。

# 备份原源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 替换为清华源(Ubuntu 20.04)
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

# 更新
sudo apt update
sudo apt upgrade -y

然后安装一些基础工具。这些是后面编译和调试的必需品:

sudo apt install -y build-essential git vim net-tools openssh-server \
    nfs-kernel-server tftpd-hpa xinetd

小技巧:安装完成后,建议拍一个虚拟机快照。万一后面搞坏了,直接恢复快照,省得重装系统。我在项目中至少靠快照救回过三次命。

2.2 交叉编译工具链安装

交叉编译,说白了就是在 PC 上编译出能在 ARM 开发板上运行的程序。你想想看,开发板的 CPU 那么弱,跑个编译得等到猴年马月?所以咱们用 PC 的强 CPU 来编译,生成 ARM 能识别的二进制文件。

海思官方提供的工具链一般是 arm-himix100-linuxaarch64-himix100-linux 系列。具体用哪个,取决于你的芯片是 ARMv7 还是 ARMv8。我以 Hi3516DV300 为例,它是 ARMv7 架构,所以用 32 位的工具链。

安装步骤其实很简单,但有几个坑要注意:

  1. 下载工具链:从海思官网或 SDK 包里的 toolchain 目录找到安装脚本。
  2. 执行安装:一般是一个 .sh 脚本,直接运行即可。
  3. 配置环境变量:安装完成后,工具链默认在 /opt/hisi-linux/x86-arm/ 下。需要把 bin 目录加到 PATH 里。
# 以 arm-himix100-linux 为例
tar -xzf arm-himix100-linux.tar.gz
cd arm-himix100-linux
sudo ./arm-himix100-linux.install

# 配置环境变量(写入 ~/.bashrc)
echo 'export PATH=/opt/hisi-linux/x86-arm/arm-himix100-linux/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

# 验证是否安装成功
arm-himix100-linux-gcc --version

我曾经踩过的坑:安装完工具链后,直接编译发现报错 cannot execute binary file。查了半天,原来是 64 位系统缺少 32 位库。解决方法:sudo apt install lib32z1 lib32ncurses5。嗯,这个坑几乎每个新手都会遇到。

验证工具链是否正常,可以写一个简单的 Hello World 程序:

// hello.c
#include <stdio.h>

int main() {
    printf("Hello, Hi3516!\n");
    return 0;
}

// 编译
arm-himix100-linux-gcc -o hello hello.c

// 查看文件信息
file hello
// 输出应该类似:ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)

看到 ARM 字样,说明编译成功了。这个文件不能在 PC 上直接运行,得拷到开发板上才能跑。

2.3 NFS/TFTP 服务配置

开发板和 PC 之间怎么传文件?最常用的两种方式:NFS 和 TFTP。我简单说说它们的区别:

  • NFS:网络文件系统。开发板可以直接挂载 PC 上的目录,像访问本地文件一样。适合调试阶段频繁修改代码的场景。
  • TFTP:简单文件传输协议。主要用于烧录内核和文件系统。速度比 NFS 快,但功能单一。

我个人习惯:调试用 NFS,烧录用 TFTP。两者配合,效率翻倍。

2.3.1 配置 NFS 服务

在 Ubuntu 上配置 NFS 服务端,其实就三步:

  1. 创建共享目录
  2. 修改配置文件
  3. 重启服务
# 创建共享目录
sudo mkdir -p /home/yourname/nfsroot
sudo chmod 777 /home/yourname/nfsroot

# 修改 /etc/exports 文件
sudo vim /etc/exports
# 添加以下内容:
/home/yourname/nfsroot *(rw,sync,no_root_squash,no_subtree_check)

# 重启 NFS 服务
sudo systemctl restart nfs-kernel-server

# 验证是否配置成功
showmount -e localhost

注意:no_root_squash 这个参数很重要。如果不加,开发板以 root 权限访问时会被映射成 nobody,导致权限不足。我在项目中遇到过文件写不进去的问题,就是少了这个参数。

开发板端挂载命令:

mount -t nfs -o nolock 192.168.1.100:/home/yourname/nfsroot /mnt

这里的 192.168.1.100 是 Ubuntu 虚拟机的 IP 地址。记得把开发板和虚拟机设成同一个网段。

2.3.2 配置 TFTP 服务

TFTP 配置更简单。我一般用它来传输内核镜像 uImage 和设备树文件 .dtb

# 安装 tftp 服务
sudo apt install tftpd-hpa

# 修改配置文件
sudo vim /etc/default/tftpd-hpa
# 内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/yourname/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"

# 创建 tftp 目录并设置权限
sudo mkdir -p /home/yourname/tftpboot
sudo chmod 777 /home/yourname/tftpboot

# 重启服务
sudo systemctl restart tftpd-hpa

# 验证服务是否启动
netstat -an | grep :69

把需要传输的文件放到 /home/yourname/tftpboot 目录下。开发板端用 tftp 命令下载:

tftp 192.168.1.100
tftp> get uImage
tftp> get hi3516dv300.dtb
tftp> quit

防火墙问题:如果开发板连不上 TFTP 服务,先检查 Ubuntu 的防火墙。我建议直接关掉防火墙,省得麻烦:sudo ufw disable。当然,生产环境别这么干。

2.4 环境验证

所有服务配置完成后,咱们做个简单的验证:

  1. 在 Ubuntu 上编译一个 Hello World 程序(交叉编译)。
  2. 把编译好的文件放到 NFS 共享目录。
  3. 开发板挂载 NFS,运行程序。
  4. 如果看到 Hello, Hi3516! 输出,说明环境搭建成功。

这一步走通了,后面的开发就顺了。我见过太多人卡在环境搭建上,一卡就是好几天。其实说白了,就是几个配置文件的事。按我上面的步骤来,半小时内肯定搞定。

总结一下这一章的核心:

  • 虚拟机配置:内存 8G+,硬盘 80G+,网络桥接。
  • 交叉工具链:注意 32 位库依赖,环境变量要配好。
  • NFS:调试利器,记得加 no_root_squash
  • TFTP:烧录专用,目录权限要开放。

下一章,咱们开始真正接触海思的 SDK,看看怎么编译一个能跑起来的系统。到时候你会发现,环境搭好了,后面全是水到渠成的事。