1 嵌入式Linux移植环境搭建
1.1 搭建交叉编译环境
所谓搭建交叉编译环境,就是安装,配置交叉编译工具链。
交叉编译工具链是为了编译链接处理和调试跨平台体系结构的程序代码。gcc是X86架构的C语言编译器,arm-linux-gcc是跨平台的C语言编译器,编译出来的程序在 目标机上执行。
本次使用4.4.3版本的arm-linux-gcc,来自广州友善电子计算机科技有限公司 (friendlyelec.com.cn)http://www.friendlyelec.com.cn/download.asp,下面为步骤:
- 进入压缩包目录,执行解压命令,将该工具链解压到/usr/local/arm目录中。
- 配置系统环境变量,将交叉编译工具链的路径添加到环境变量PATH中,可以在"~/.bashrc"中添加一行“export PATH=$PATH:/usr/local/arm/FriendlyARM/toolschain/4.4.3”,这个路径就是arm-linux-gcc命令的位置。
- 使用命令source ~/.bashrc,使环境变量生效。
- 在终端输入命令arm-linux-,再按下table键,可以看到以下内容,说明环境变量设置成功。
lei@ubuntu:~$ arm-linux- arm-linux-addr2line arm-linux-g++ arm-linux-objcopy arm-linux-ar arm-linux-gcc arm-linux-objdump arm-linux-as arm-linux-gcc-4.4.3 arm-linux-populate arm-linux-c++ arm-linux-gccbug arm-linux-ranlib arm-linux-cc arm-linux-gcov arm-linux-readelf arm-linux-c++filt arm-linux-gprof arm-linux-size arm-linux-cpp arm-linux-ld arm-linux-strings arm-linux-ct-ng.config arm-linux-nm
- 使用命令arm-linux-gcc -v,查看软件配置和版本信息,出现以下问题是因为,工具是32位的,系统是64位的,需要安装32位的库
lei@ubuntu:~$ arm-linux-gcc -v /usr/local/arm/FriendlyARM/toolschain/4.4.3/bin/arm-linux-gcc: 15: exec: /usr/local/arm/FriendlyARM/toolschain/4.4.3/bin/.arm-none-linux-gnueabi-gcc: not found
可以看到以下内容,说明程序安装成功。lei@ubuntu:~$ sudo apt install lib32ncurses5 lib32z1
lei@ubuntu:~$ arm-linux-gcc -v Using built-in specs. Target: arm-none-linux-gnueabi Configured with: /opt/FriendlyARM/mini2440/build-toolschain/working/src/gcc-4.4.3/configure --build=i386-build_redhat-linux-gnu --host=i386-build_redhat-linux-gnu --target=arm-none-linux-gnueabi --prefix=/opt/FriendlyARM/toolschain/4.4.3 --with-sysroot=/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi//sys-root --enable-languages=c,c++ --disable-multilib --with-arch=armv4t --with-cpu=arm920t --with-tune=arm920t --with-float=soft --with-pkgversion=ctng-1.6.1 --disable-sjlj-exceptions --enable-__cxa_atexit --with-gmp=/opt/FriendlyARM/toolschain/4.4.3 --with-mpfr=/opt/FriendlyARM/toolschain/4.4.3 --with-ppl=/opt/FriendlyARM/toolschain/4.4.3 --with-cloog=/opt/FriendlyARM/toolschain/4.4.3 --with-mpc=/opt/FriendlyARM/toolschain/4.4.3 --with-local-prefix=/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi//sys-root --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-c99 --enable-long-long --enable-target-optspace Thread model: posix gcc version 4.4.3 (ctng-1.6.1)
1.2 获取内核
内核官方主页 The Linux Kernel Archiveshttps://www.kernel.org/
1.3 获取启动加载器(BootLoader)
启动加载器的工作是为内核准备好合适的工作环境并加载内核,我们使用德国DENX小组开发的u-bootIndex of /pub/u-boot/ (denx.de)https://ftp.denx.de/pub/u-boot/
1.4 配置必要服务
1.4.1 网络配置
系统移植是网络服务要使用桥接模式,也就是主机和虚拟机通信,虚拟机和主板通信。其中,尤其要注意网卡选择有线网卡(以太网),但是如果主机网络服务使用的是wifi,那么虚拟机使用有线网卡后不可上网,需要切换为wifi网卡后方可上网,同时虚拟机会和主板失去连接。
1.4.2 配置TFTP服务
在Ubuntu系统中,安装TFTP服务器和客户端步骤如下:
使用如下命令
1.4.3 配置NFS服务
NFS 是 Network File System 的缩写,它可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。
NFS 服务器可以让 PC 将网络中的 NFS 服务器共享的目录挂载到本地端的文件系统中,而在本地端的系统中来看,那个远程主机的目录就好像是自己的一个磁盘分区一样,在使用上相当便利;
NFS 服务器我们一般是在 ubuntu 上搭建的。这里的客户端我们使用的是开发板,我们可以使用开发板A,挂载开发板 B,挂载开发板 C,我们可以挂载好几个客户端。
(1)nfs服务端搭建
(2)创建名为nfs共享目录
(3)打开配置文件 vim /etc/exports,添加nfs共享目录
其中: /home/nfs/ 是 nfs 服务器要共享的目录
rw:是可读写权限
sync:是资料同步写入内存和硬盘
no_root_squash:当登录 NFS 主机使用共享目录的使用者是 root 时,其权限将被转换成为一名使用者,通常它的 UID 与 GID 都会变成 nobody 身份。
(4)重启nfs服务
/etc/init.d/nfs-kernal-server restart
nfs服务器的使用
(1)开发板烧写文件系统,有线网口通过网线连接,ifconfig查看开发板ip
(2)虚拟机ifconfig查看nfs服务器的ip
(3)二者同一网段,反之重新配
(4)ping通
(5)挂载nfs服务器的共享目录,mount -t nfs -o nolock,nfsvers=3,vers=192.168.1.9:/home/nfs /mnt/,这句话代码的意思是使用 nfs3 版本挂载 IP 为 192.168.1.9 中的 /home/nfs 到 mnt 文件夹下,IP 为ubuntu 的 IP.把这个 ip 改成自己 ubuntu 的 ip 就可以了。
2 u-boot移植
2.1 u-boot工程与编译系统
2.1.1 u-boot介绍
2.1.2 u-boot常用命令与测试
2.1.3 u-boot编译过程分析
2.2 u-boot启动流程分析
u-boot启动流程是指从上电开机执行到u-boot,到u-boot加载操作系统的过程。
分为两段:
第一阶段功能:
- 硬件初始化
- 加载u-boot第二段代码到RAM空间
- 设置好栈
- 跳转到第二阶段代码入口
第二阶段功能:
- 初始化本阶段使用的硬件设备
- 检测系统内存映射
- 将内核从FLASH读取到RAM中
- 为内核设置启动参数
- 调用内核
2.2.1 u-boot启动第一阶段流程
u-boot入口代码的对应源文件cpu/arm920t/start.S中
2.2.1.1 设置异常向量
2.2.1.2 CPU进入SVC模式
2.2.1.3 设置控制寄存器地址
2.2.1.4 关闭看门狗
1.5 屏蔽中断
1.6 设置EPLLCON UPLLCON和CLKDIVN
1.7 关闭MMU和cache
1.8 初始化存储控制器
1.9 复制u-boot第二段代码到RAM
1.10 设置栈
1.11 清除BSS段
1.12 跳转到第二阶段代码
2.2.2 u-boot启动第二阶段代码分析
start_armboot函数在lib_arm/board.c中定义,是第二阶段代码的入口。