前言
之前一直是将ARM的Linux环境搭建在虚拟机中,然后在主机Windows中开启虚拟机来进行使用。而如今早已习惯Linux的使用,也已经完全适应在Linux下的日常使用了,所以本次打算将虚拟机中的嵌入式环境转移到主机Linux中,主机Linux使用的是Ubuntu 18.04,ARM CPU采用的是S5PV210。嵌入式开发环境搭建相对还是比较繁杂,故在此做个记录。
交叉编译工具链安装
由于三星官方在开发S5PV210时使用的交叉编译工具链是arm-2009q3这个版本,所以这里以安装arm-2009q3为例。
在/usr/local/目录下创建arm文件夹用来安装arm-2009q3,然后进入到/usr/local/arm
下,将arm-2009q3.tar.bz2复制到当前目录,最后解压arm-2009q3.tar.bz2到当前目录下。
sudo mkdir /usr/local/arm
cd /usr/local/arm
sudo cp ~/arm-2009q3.tar.bz2 ./
sudo tar jxvf arm-2009q3.tar.bz2
测试安装是否成功,进入到arm-2009q3/bin/目录下,执行./arm-none-linux-gnueabi-gcc -v后成功输出版本相关信息就表示安装成功。
代码语言:javascript复制cd arm-2009q3/bin/
./arm-none-linux-gnueabi-gcc -v
将交叉编译工具链导出到环境变量中,在~/.zshrc中添加以下命令(因为我用的shell是zsh,如果是bash shell则在~/.bashrc中添加)。
代码语言:javascript复制export PATH=/usr/local/arm/arm-2009q3/bin/:$PATH
一般情况下使用arm-linux-*来使用交叉编译工具链,而不是arm-none-linux-gnueabi-*,所以创建符号链接来简化命令为arm-linux-*。方便起见,将ln命令写入脚本后执行,在/usr/local/arm/arm-2009q3/bin/
下创建ln.sh,在其中写入以下代码
#!/bin/sh
var1=arm-none-linux-gnueabi-*
for i in $(ls $var1); do
var2=${i##*gnueabi-}
ln -s $i arm-linux-$var2
done
然后在当前目录下执行该脚本
代码语言:javascript复制sudo chmod 777 ln.sh
sudo ./ln.sh
至此交叉编译工具链安装彻底完成,随后在任意目录下皆可执行arm-linux-gcc
。
tftp服务器搭建
安装相关程序
代码语言:javascript复制sudo apt install tftp-hpa # tftp客户端
sudo apt install tftpd-hpa # tftp服务器
sudo apt install xinetd # xinetd服务器
配置xinetd,修改/etc/xinetd.conf
配置为以下内容 (一般情况无需修改,直接跳过该步即可)
# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/
defaults
{
# Please note that you need a log_type line to be able to use log_on_success
# and log_on_failure. The default is the following :
# log_type = SYSLOG daemon info
}
includedir /etc/xinetd.d
创建tftp服务器工作目录,并修改为合适的权限
代码语言:javascript复制# 该目录可以创建在任意地方,只需后续步骤中配置的路径正确即可
sudo mkdir /home/ifantsai/Embedded/tftpboot/
sudo chmod 777 /home/ifantsai/Embedded/tftpboot/
配置tftp服务器,修改/etc/default/tftpd-hpa
配置为以下内容
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
#TFTP_DIRECTORY="/var/lib/tftpboot"
# tftp服务器的工作目录,修改成自己需要使用的目录即可。注意该目录权限问题
TFTP_DIRECTORY="/home/ifantsai/Embedded/tftpboot/"
#TFTP_ADDRESS=":69"
TFTP_ADDRESS="0.0.0.0:69"
#TFTP_OPTIONS="--secure"
TFTP_OPTIONS="-l -c -s"
进入到/etc/xinetd.d
目录下,查看有没有tftp文件,如果没有则创建,修改/etc/xinetd.d/tftp
配置为以下内容
service tftp
{
socket_type = dgram
wait = yes
disable = no
user = root
protocol = udp
server = /usr/sbin/in.tftpd
# 同样修改成tftp服务器的工作目录
server_args = -s /home/ifantsai/Embedded/tftpboot/
#log_on_success = PID HOST DURATION
#log_on_failure = HOST
per_source = 11
cps = 100 2
flags = IPv4
}
重新启动服务
代码语言:javascript复制sudo service tftpd-hpa restart
sudo /etc/init.d/xinetd reload
sudo /etc/init.d/xinetd restart
nfs服务器搭建
安装nfs服务器
代码语言:javascript复制sudo apt install nfs-kernel-server
创建nfs服务器工作目录,并修改为合适的权限
代码语言:javascript复制# 该目录可以创建在任意地方
sudo mkdir /home/ifantsai/Embedded/nfs/
sudo chmod 777 /home/ifantsai/Embedded/nfs/
修改/etc/exports
配置文件,添加一下这行配置
# 注意nfs工作目录保证正确
/home/ifantsai/Embedded/nfs/ *(rw,sync,no_root_squash)
重新启动服务
代码语言:javascript复制sudo /etc/init.d/nfs-kernel-server restart
注意:笔者在配置完后,开发板挂载rootfs一直报错:VFS:Unable to mount root fs via NFS, trying floppy 然后尝试了各种方法也未解决 解决办法:最后查阅了各种资料才发现从Ubuntu17.04开始,nfs默认只支持协议3和协议4,而kernel中默认支持协议2,所以才会出现挂载失败,现有两种方法可解决该问题(推荐方法一):
- 1.配置nfs服务器支持协议2,在/etc/default/nfs-kernel-serverw文件末尾加入下面配置
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
- 2.如果开发板kernel版本较高的话,可以在Uboot的环境变量bootargs参数中加入’nfsvers=3’使之支持nfs协议3
Linux下串口调试工具minicom的安装及使用
在Windows下SecureCRT来进行串口调试,在Linux下可用minicom代替。
安装
代码语言:javascript复制sudo apt install minicom
将开发板串口与电脑的USB口相连,在Windwos下通过查看设备管理器即可知道开发板连接的是哪个COM口,在Linux下会自动安装驱动程序,通过dmesg
命令可查看安装驱动
从图中可以看出连接的是ttyUSB0,或者输入ls -l /dev/ttyUSB*
,同样可以看到是ttyUSB0
设置
代码语言:javascript复制sudo minicom -s
弹出下图的设置界面
通过方向键选择Serial Port setup,然后回车键进入设置界面
按每个配置项前的字母进入相应行进行设置,按回车键设置当前行完毕,比如输入a设置串口连接的是哪个COM口,按回车键设置完毕。将波特率配置为115200 8N1(波特率: 115200,数据位: 8,奇偶校验位: N 无,停止位: 1),将硬件控制流和软件控制流都设置为No。
都设置完后,再按回车返回到上一界面,选择Save setup asdfl将该配置保存为默认配置,再选择Exit,最后按Ctrl a后再按X键退出minicom。
下次使用的时候,如果仍然使用本次使用的USB口,则不需要重新配置即可使用
代码语言:javascript复制sudo minicom
注:在minicom中设置输出自动换行:先按Ctrl A 然后按Z 再按W 或者在启动minicom的时候加上-w参数
配置静态ip
打开网络配置文件/etc/network/interfaces
,在其中添加以下内容
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
# enp4s0f1为本机的有线网卡
auto enp4s0f1
iface enp4s0f1 inet static
#iface enp4s0f1 inet dhcp
# 配置的本机有线网卡的静态ip
address 192.168.1.10
netmask 255.255.255.0
#gateway 192.168.1.1
然后关闭网卡后开启网卡,使配置生效
代码语言:javascript复制sudo ifdown enp4s0f1
sudo ifup enp4s0f1
重启网卡后,通过ifconfig
查看静态ip是否设置上了,如果没有,可能需要重启一下Linux才会生效。
设置u-boot的参数
在主机Linux上将zImage和rootfs分别放置在tftpboot目录和nfs目录下,将开发板的串口和主机Linux连接好后,启动minicom进入u-boot的命令行,在命令行下进行设置bootargs环境变量
代码语言:javascript复制# 设置tftpboot方式启动Kernel和主机Linux的ip
set bootcmd 'tftpboot 0x30008000 zImage;bootm 0x30008000'
set serverip 192.168.1.10
set ipaddr 192.168.1.30
# nfsroot=192.168.1.10:/home/ifantsai/Embedded/nfs/rootfs为主机Linux上rootfs的ip和目录
# 192.168.1.30:192.168.1.10分别为主机Linux的ip和开发板的ip
set bootargs root=/dev/nfs nfsroot=192.168.1.10:/home/ifantsai/Embedded/nfs/rootfs ip=192.168.1.30:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC2,115200
# 保存环境变量
saveenv
然后重启开发板后成功引导Kernel的启动并成功挂载rootfs。
本文作者: Ifan Tsai (菜菜)
本文链接: https://cloud.tencent.com/developer/article/2164583
版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!