2. R-Car硬件基础
说实话,R-Car 开发的第一步,往往就把不少人卡住了。不是芯片有多难,而是环境没搭对。我见过太多工程师拿着开发板,却连一个 Hello World 都跑不起来——问题全出在工具链和构建系统上。
这一章,咱们就把这三件事彻底搞定:交叉编译工具链、Yocto/Buildroot 构建系统、NFS/TFTP 网络调试环境。这三板斧抡好了,后面的驱动开发才能顺风顺水。
2.1 交叉编译工具链:GCC for ARM
R-Car 用的是 ARM Cortex-A 系列核心(比如 A57、A53、A76)。你的 PC 是 x86 架构,没法直接在 PC 上编译出 ARM 能跑的二进制。所以,我们需要交叉编译工具链。
说白了,就是在 x86 的 PC 上,用一套专门的 GCC,编译出 ARM 架构的代码。
2.1.1 工具链的选择
我个人习惯用 Linaro 提供的 GCC 工具链,稳定且社区支持好。瑞萨官方 BSP 也推荐这个。
| 工具链名称 | 适用场景 | 下载来源 |
|---|---|---|
| gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf | 32位用户空间 + 内核 | Linaro 官方 Release |
| gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu | 64位用户空间 + 内核 | Linaro 官方 Release |
| R-Car BSP 自带工具链 | 与 BSP 严格匹配 | 瑞萨官网 / Yocto SDK |
2.1.2 安装步骤
安装其实很简单,解压、加路径就行。但有个坑——路径里不要有中文或空格,否则编译时你会哭的。
# 下载 aarch64 工具链
wget https://releases.linaro.org/components/toolchain/binaries/8.3-2019.03/aarch64-linux-gnu/gcc-linaro-8.3.1-2019.03-x86_64_aarch64-linux-gnu.tar.xz
# 解压到 /opt
sudo tar -xvf gcc-linaro-8.3.1-2019.03-x86_64_aarch64-linux-gnu.tar.xz -C /opt/
# 添加环境变量(建议写到 ~/.bashrc 里)
export PATH=/opt/gcc-linaro-8.3.1-2019.03-x86_64_aarch64-linux-gnu/bin:$PATH
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64
# 验证
aarch64-linux-gnu-gcc --version
2.2 构建系统:Yocto vs Buildroot
R-Car 的 BSP 官方推荐 Yocto。但如果你只是做驱动验证,Buildroot 更轻量。我两个都用过,说说我的感受。
2.2.1 Yocto:全功能但重
Yocto 能生成完整的 Linux 发行版,包括内核、文件系统、各种库。瑞萨的 R-Car BSP 就是基于 Yocto 的。
但 Yocto 的学习曲线……嗯,确实陡。我第一次配 Yocto 环境,光下载源码就花了大半天。
# 以 R-Car BSP 为例
mkdir rcar-yocto && cd rcar-yocto
repo init -u https://github.com/renesas-rcar/rcar-bsp.git -b v5.1.0
repo sync
# 设置构建环境
source poky/oe-init-build-env build
# 编译目标(以 H3ULCB 为例)
bitbake core-image-minimal
Yocto 的优点是可定制性强,缺点就是慢。第一次全量编译,4 核 CPU 大概要 2-3 小时。
2.2.2 Buildroot:轻量快速
如果你只是想快速验证驱动,Buildroot 是更好的选择。它配置简单,编译快,20 分钟就能出一个可用的根文件系统。
# 下载 Buildroot
git clone git://git.buildroot.net/buildroot
cd buildroot
# 配置(选择 aarch64 目标)
make qemu_aarch64_virt_defconfig
make menuconfig
# 编译
make -j4
2.3 网络调试环境:NFS + TFTP
驱动开发最怕什么?每次改代码都要重新烧写整个系统。太慢了。所以我们需要网络启动:内核用 TFTP 加载,根文件系统用 NFS 挂载。
这样,你在 PC 上改完驱动,重新编译,重启开发板就能看到效果。效率提升不止一个量级。
2.3.1 TFTP 服务器搭建
TFTP 用来传输内核镜像(Image)和设备树(.dtb)。
# 安装 TFTP 服务器
sudo apt-get install tftpd-hpa
# 配置
sudo vim /etc/default/tftpd-hpa
# 内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"
# 创建目录并设置权限
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 重启服务
sudo systemctl restart tftpd-hpa
把编译好的 Image 和 .dtb 文件复制到 /srv/tftp 目录下。
2.3.2 NFS 服务器搭建
NFS 用来挂载根文件系统。这样开发板启动后,直接使用 PC 上的文件系统。
# 安装 NFS 服务器
sudo apt-get install nfs-kernel-server
# 配置导出目录
sudo vim /etc/exports
# 添加一行(假设根文件系统在 /srv/nfs/rootfs)
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
# 创建根文件系统目录
sudo mkdir -p /srv/nfs/rootfs
# 将 Buildroot 或 Yocto 生成的根文件系统解压到这里
sudo tar -xvf output/images/rootfs.tar -C /srv/nfs/rootfs
# 重启 NFS 服务
sudo systemctl restart nfs-kernel-server
2.3.3 U-Boot 启动参数配置
最后一步,在 U-Boot 里设置启动参数,让开发板从网络启动。
# 在 U-Boot 命令行中设置
setenv ipaddr 192.168.1.100 # 开发板 IP
setenv serverip 192.168.1.10 # PC(服务器)IP
setenv netmask 255.255.255.0
# 设置 TFTP 加载内核和设备树
setenv bootcmd 'tftp 0x48080000 Image; tftp 0x48000000 r8a77951-h3ulcb.dtb; booti 0x48080000 - 0x48000000'
# 设置 NFS 根文件系统
setenv bootargs 'console=ttySC0,115200 root=/dev/nfs nfsroot=192.168.1.10:/srv/nfs/rootfs rw ip=192.168.1.100'
# 保存并启动
saveenv
boot
2.4 整体环境架构图
下面这张图,把整个开发环境的流程串起来了。建议你保存下来,搭建环境时对照着看。
2.5 验证环境是否搭建成功
环境搭好了,怎么知道对不对?我一般用三步验证法:
- 编译验证:写一个简单的 Hello World,用交叉编译器编译,确认能生成 ARM 可执行文件。
- 网络验证:开发板通过 TFTP 加载内核,能进入内核启动日志。
- 文件系统验证:内核启动后,能正常挂载 NFS 根文件系统,进入 shell。
# 第一步:交叉编译 Hello World
cat > hello.c << EOF
#include <stdio.h>
int main() {
printf("Hello R-Car!\n");
return 0;
}
EOF
aarch64-linux-gnu-gcc -o hello hello.c
file hello
# 输出应包含:ELF 64-bit LSB executable, ARM aarch64
# 第二步:放到 NFS 根文件系统里
cp hello /srv/nfs/rootfs/home/root/
# 第三步:开发板启动后,在板子上运行
# 在开发板的 shell 中执行:
# /home/root/hello
# 输出:Hello R-Car!
sudo ufw disable。