第二章:嵌入式Linux开发环境搭建
好,咱们直接进入正题。这一章要解决的核心问题就一个——怎么让你的电脑和开发板“说上话”。
我刚开始做嵌入式那会儿,最头疼的就是环境搭建。明明照着教程一步步来,结果编译出来的程序就是跑不起来。后来才明白,不是代码的问题,是工具链没配好。所以这一章,咱们把交叉编译工具链、TFTP/NFS、SSH这三个东西彻底搞明白。
2.1 交叉编译工具链安装
先说说什么是交叉编译。你想想看,你的电脑是x86架构,车机座舱芯片通常是ARM架构。在x86上编译出ARM能跑的程序,这就是交叉编译。
工具链的选择,我个人习惯用Linaro提供的版本。为什么?因为它在ARM生态里最活跃,更新也及时。
2.1.1 下载与解压
# 以gcc-arm-9.2-2019.12为例
wget https://releases.linaro.org/components/toolchain/binaries/.../gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz
tar -xf gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz -C /opt/
解压到/opt/目录,这是Linux下的惯例。当然你也可以放别处,但路径别带中文和空格,否则后面有你哭的。
2.1.2 配置环境变量
这一步很多人会忘。你装好了工具链,但系统不知道它在哪。
export PATH=$PATH:/opt/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin
export CROSS_COMPILE=arm-none-linux-gnueabihf-
export ARCH=arm
我建议你把这三行加到~/.bashrc里。这样每次打开终端,环境自动就配好了。
arm-none-linux-gnueabihf-gcc --version 验证。如果显示版本信息,说明成了。
2.1.3 验证工具链
写个最简单的hello world试试:
#include <stdio.h>
int main() {
printf("Hello, 座舱系统!\n");
return 0;
}
arm-none-linux-gnueabihf-gcc -o hello hello.c
file hello
看到输出里有ARM字样,就对了。我曾经见过有人用x86的gcc编译,然后拷到开发板上跑,结果报Exec format error。嗯,这种低级错误我也犯过。
2.2 TFTP/NFS网络文件系统配置
开发阶段,你不可能每次改个代码就烧写一次Flash。太慢了。TFTP和NFS就是用来解决这个问题的。
2.2.1 TFTP服务器搭建
TFTP用于传输内核和设备树。说白了,就是开发板启动时从你的电脑上拉文件。
sudo apt-get install tftpd-hpa
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot
配置文件在/etc/default/tftpd-hpa:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
2.2.2 NFS服务器搭建
NFS用于挂载根文件系统。这样你的程序在开发板上运行,但实际文件存在电脑上。调试起来特别方便。
sudo apt-get install nfs-kernel-server
sudo mkdir -p /srv/nfs/rootfs
编辑/etc/exports:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
然后重启服务:
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
开发板启动时,uboot里设置:
setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/srv/nfs/rootfs rw ip=192.168.1.101'
这里192.168.1.100是你电脑的IP,192.168.1.101是开发板的IP。记得改成你自己的网段。
2.3 SSH远程调试
系统跑起来之后,你总不能一直插着串口线吧?SSH就是你的远程控制台。
2.3.1 开发板开启SSH服务
如果你的根文件系统是Buildroot或Yocto构建的,默认可能没带SSH。需要手动添加:
# 在Buildroot配置中选中
BR2_PACKAGE_OPENSSH=y
或者直接在开发板上安装:
apt-get install openssh-server # 如果用的是Debian系
2.3.2 配置网络连接
开发板和电脑要在同一个网段。我习惯用静态IP:
ifconfig eth0 192.168.1.101 netmask 255.255.255.0
route add default gw 192.168.1.1
然后从电脑上:
ssh root@192.168.1.101
第一次连接会提示确认指纹,输入yes就行。
2.3.3 避坑指南
我曾经在项目交付前一天,发现SSH死活连不上。查了半天,原来是开发板的hostname和另一台设备冲突了。所以建议你:
- 给每块开发板设置唯一hostname
- SSH端口别用默认的22,容易被扫描
- 密钥认证比密码认证更安全,也方便
# 生成密钥对
ssh-keygen -t rsa -b 4096
ssh-copy-id root@192.168.1.101
这样以后连SSH就不用输密码了。嗯,省事不少。
小结
这一章的内容,说白了就是三件事:
- 交叉编译工具链——让你能在电脑上编译ARM程序
- TFTP/NFS——让开发板能从电脑上加载内核和文件系统
- SSH——让你能远程操控开发板
这三样配好了,后面的开发工作才能顺畅进行。我见过太多人卡在环境搭建这一步,其实只要按顺序来,没那么复杂。
下一章,咱们聊聊uboot和内核的编译与启动流程。到时候你会看到,今天配的这些环境,全都能用上。