什么是系统移植?
将操作系统移植到对应的硬件平台
linux系统移植到FS6818开发板
- 学习系统移植的目的?
1》浅图:为后面的驱动开发学习搭建一个系统环境
2》钱途:就业、工作的需要(公司新的硬件平台---》移植linux系统到硬件)
3》前途:嵌入式(软+硬)开发离不开操作系统
在众多嵌入式操作系统中,Linux目前发展最快、应用最为广泛。性能优良、源码开放的Linux具有体积小、内核可裁减、网络功能完善、可移植性强等诸多优点,非常适合作为嵌入式操作系统。
根据产品需求-----》软硬件可裁剪
- 如何学习系统移植?
在最短的时间内学会最有用的东西
学习移植的流程、思想和解决问题的方法即可
- 系统移植过程
Linux系统移植:
- 准备Linux内核镜像、SD卡启动盘
- 通过拨码开关选择启动方式(SD启动)
- 通过SD卡中的引导程序安装系统
- 安装Linux驱动程序
- 安装Linux应用程序
- 开发板启动的过程
- 开发板上电后首先运行SoC(6818)内部ROM中固化的代码(BL0),这段代码先对基本的软硬件环境(时钟等...)进行初始化
- 然后再检测拨码开关位置获取启动方式,然后再将对应存储器中的uboot搬移到内存,然后跳转到uboot运行
- uboot开始运行后首先对开发板上的软硬件环境做进一步初始化
- 然后将linux内核、设备树(dtb)、根文件系统(rootfs)从外部存储器(或网络)搬移到内存,然后跳转到linux运行
- Linux开始运行后先对系统环境做初始化,当系统启动完成后
- Linux再从内存中(或网络)挂载根文件系统
- 课程内容
- 环境搭建
- Uboot移植
uboot(Universal Boot Loader)通用引导加载程序,是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,其主要作用为:引导系统的启动!
最主要的功能有以下几点
1)初始化一些硬件为后续做准备(裸机代码)
2)引导和加载内核
3)给内核传参
4)执行用户命令
- Linux内核移植
内核是硬件与软件之间的一个中间层。向上提供接口,向下可控制硬件。
内核就像一个库,提供了一组面向系统的命令。系统调用对于应用程序来说,就像调用普通函数一样。
- 根文件系统移植
windows C盘系统相关的,Linux是一颗倒置的树
Uboot概述
Bootloader简介
Bootloader是在操作系统运行之前执行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。在嵌入式系统中,Bootloader是基于特定硬件平台来实现的,不同的处理器架构都有不同的Bootloader。例如,U-Boot就同时支持PowerPC、ARM、MIPS和X86等体系结构。其本质为一段裸机程序不是操作系统本身
Bootloader基本功能
- 初始化软硬件环境
- 引导加载linux内核
- 给linux内核传参
- 执行用户命令
注:bootloader是启动引导程序的统称,嵌入式linux常用的bootloader是uboot。
常见的Bootloader
bootloader就相当于类,uboot(Universal Boot Loader)就相当于对象。嵌入式领域常用的bootloader就是uboot
为什么使用Uboot
Uboot是一种开源的引导加载程序,它的作用是在嵌入式系统启动时加载内核并启动系统。使用Uboot的好处在于它可以提供很多功能,例如支持多种文件系统、网络启动、远程更新等。此外,Uboot还可以提供一些调试功能,例如通过串口输出调试信息等。因此,使用Uboot可以使嵌入式系统的开发和调试更加方便和高效。
Uboot的工作方式
- Uboot首先被加载到内存中,并开始执行。
- 初始化硬件设备,例如CPU、内存、串口等。
- 读取存储设备(例如Flash)中的内核镜像,并将其加载到内存中。
- 设置内核启动参数,例如根文件系统的位置、内存大小等。
- 跳转到内核的入口点,启动内核。
- 一旦内核启动成功,Uboot的使命就完成了,它的生命周期也就结束了。
扩展
根据自身情况观看视频
【嵌入式】我提着鞋带拎自己?嵌入式芯片启动过程全解析,彻底理解bootloader【蛋饼嵌入式】我提着鞋带拎自己?嵌入式芯片启动过程全解析,彻底理解bootloader_哔哩哔哩_bilibili
交叉开发环境搭建
安装交叉编译工具链
咱们前面已经安装了,不需要再安装。要知道有这一步,如果忘记了可以看文档 安装交叉编译环境
本地开发和交叉开发
本地开发:PC端编写代码,编译代码,运行代码
交叉开发:PC端编写代码,编译代码,Target(目标板)运行代码
学生疑问:不是已经将系统移植到目标板上了吗?为什么要使用交叉开发,不能直接在目标板上面编写和编译代码嘛?
PC ——》 X86/64架构
Target ——》 arm架构
使用交叉编译工具链将源码编译成支持ARM架构的可执行程序,再将可执行程序拷贝到目标板上运行。
PC:gcc
交叉编译工具链:arm-none-linux-gnueabi-gcc
arm-none-linux-gnueabi-:交叉编译工具链的名字,名字就是一个代号
(在工作中用的不一定是这个,不同的公司做的交叉编译工具链的名字不同)
PC和开发板如何进行硬件连接
串口线的作用
打印各种调试信息到串口工具上
网线的作用
用于下载uboot和内核的镜像(可执行程序)
通过网络去挂载根文件系统
通过网线下载文件---》tftp服务
通过网线挂载根文件系统(板子(路径))---》nfs服务
tftp安装配置
TFTP是一个传输文件的简单协议,它基于UDP协议而实现,此协议设计的时候是进行小文件传输的。因此它不具备通常的FTP的许多功能,它只能从文件服务器上获得或写入文件,不能列出目录,不进行认证,它传输8位数据。
通过网线下载文件---》tftp服务
具体实验步骤可查看实验手册的实验二 系统移植实验手册
1. 检查ubuntu是否安装了tftp服务
dpkg -s tftpd-hpa
打印以下内容表示安装了tftp服务:
Architecture: i386
Source: tftp-hpa
Version: 5.2-7ubuntu3.1
2. 安装tftp服务
(前提:ubuntu必须能连接外网)
sudo apt-get update 更新源
sudo apt-get install -f 更新依赖
sudo apt-get install tftpd-hpa tftp-hpa
3. 配置tftp服务
1. 在根目录下创建一个tftpboot文件夹
mkdir /tftpboot
目的:/tftpboot目录下存放的是你要下载到开发板上的可执行文件
2. 修改tftpboot的权限
sudo chmod 777 tftpboot
3. 配置tftp服务的环境变量
打开sudo vi /etc/default/tftpd-hpa
修改以下内容:
1 # /etc/default/tftpd-hpa
2
3 TFTP_USERNAME="tftp"
tftp用户名,不需要修改
4 TFTP_DIRECTORY="/tftpboot"
tftp服务下载文件的存放的路径,需要修改
改成自己的对应的tftpboot的路径
5 TFTP_ADDRESS="0.0.0.0:69"
tftp服务默认使用的69端口号
6 TFTP_OPTIONS="-c -s -l"
tftp服务的参数,这个需要修改
4. 重启tftp服务
1. sudo service tftpd-hpa start 启动TFTP服务
2. sudo service tftpd-hpa restart 重启TFTP服务
5. 本地测试tftp服务是否安装成功
(ping 其它机器过程:本机网卡驱动,到内核,内核处理这个驱动,发送ping的包到另一个系统的网卡,处理这个包,把包的内容放到协议站(在内核里面),识别到ping的包,然后通过网卡驱动,到网卡,返回一个包(都会到真正物理硬件))
$ tftp 127.0.0.1
tftp> get 1.txt # 从tftpboot目录下下载
# 1.txt文件到当前目录 (本例子就是,
在tftpboot下面touch 1.TXT,然后在家目录下面运行)
tftp 127.0.0.1;然后get 1.txt,就把tftpboot下面的1.TXT下载到家目录下面了)
tftp> put 2.txt # 把当前目录中的2.txt文件,上传到tftpboot文件夹中
tftp> q <回车> 退出
6. 可能出现的问题
下载或上传是,一直卡
原因:
tftp服务安装成功,需要重启tftp服务
tftp服务安装不成功
关闭windows和ubuntu的防火墙(防火墙会阻碍数据传输)
nfs安装配置
NFS是基于UDP/IP协议的应用,其实现主要是采用远程过程调用RPC机制,RPC提供了一组与机器、操作系统以及底层传送协议无关的存取远程文件的操作。
通过网线挂载根文件系统---》nfs服务
详细步骤可参考实验手册中的实验三 系统移植实验手册
1. 检查nfs服务是否安装
dpkg -s nfs-kernel-server
2. 安装nfs服务(前提:可以上网)
sudo apt-get install nfs-kernel-server
3. 配置nfs服务
1》在根目录下创建文件夹
sudo mkdir -p /opt/6818/rootfs
2》设置文件夹的权限最大
sudo chmod -R 777 /opt/*
3》配置nfs服务的环境变量
sudo vi /etc/exports
在文件的最后一行添加以下内容:
****************************************
/opt/6818/rootfs/ *(rw,sync,no_subtree_check,no_root_squash)
****************************
解析:
/opt/6818/rootfs/:自己的根文件系统的路径
*:所有的用户,注:*和后边的左括号"("之间不可以出现空格.
rw:可读可写的权限
sync:同步文件
no_subtree_check:不对子目录检查文件的权限
no_root_squash:如果客户端为root用户,那么他对整个文件具有root的权限
注意:这段话前边不要加#,#号是这个文件中的注释符号
4. 重启nfs服务
1. sudo service nfs-kernel-server start 启动nfs服务
2. sudo service nfs-kernel-server restart 重启nfs服务
5. 本地测试nfs服务是否安装成功
1》回到家目录下
cd ~
2》sudo mount -t nfs localhost:/opt/6818/rootfs /mnt
(本机IP地址:ubuntu 的IP)
nfs:使用nfs服务,将本机IP地址:/opt/6818/rootfs/
文件挂载到/mnt目录下
3》检查/mnt目录下是否挂载成功
cd /mnt
ls (此时mnt下面的东西就和rootfs下面一样)
4》卸载挂载的文件
sudo umount /mnt
注意:不可以在/mnt目录下执行卸载的命令
Uboot烧写及使用
SD卡启动盘制作
SD卡的存储以扇区为单位,每个扇区的大小为512Byte, 其中零扇区存储分区表(即分区信息),后续的扇区可自行分区和格式化;若选择SD卡启动,处理器上电后从第一个扇区开始将其中的内容搬移到内存,所以我们把uboot放到从第一个扇区开始之后的空间根据个人需求可进行分区和格式化
具体制作步骤详情看实验手册-》实验四 系统移植实验手册
uboot的使用
uboot模式
自启动模式
uboot启动后若没有用户介入,倒计时结束后会自动执行自启动环境变量(bootcmd)中设置的命令(一般作加载和启动内核)
交互模式
倒计时结束之前按下任意按键uboot会进入交互模式,交互模式下用户可输入uboot命令
uboot帮助命令
help 查看uboot支持的所有命令
help+命令 查看当前命令的使用方法
uboot环境变量命令
printenv 打印uboot中所有的环境变量
setenv 设置指定的环境变量(保存在RAM中)
setenv 环境变量 环境变量的值
saveenv 保存所有环境变量到EMMC中
常用环境变量
ipaddr uboot的IP地址
serverip 服务器的IP地址(即ubuntu的IP)
bootdelay 进入自启动模式之前倒计时的秒数
网络传输命令
loadb 通过Kermit协议下载文件到指定的内存地址( loadb 地址)
tftp 通过tftp协议下载文件到指定的内存地址( tftp 地址 文件名 )
存储器访问命令
mmc read 将EMMC中指定扇区中的内容读取到内存中指定的地址
mmc read <addr> <blk#> <cnt>
addr: 内存地址
blk#: EMMC中的扇区编号
cnt: 读取的扇区的个数
mmc write 将内存中指定地址中的内容写入到EMMC中指定的扇区
mmc write <addr> <blk#> <cnt>
addr:对应着内存的地址
blk#:mmc设备的块号
cnt:mmc设备块的个数
mmc erase 将mmc的起始块号为blk#,cnt块大小的数据,进行擦除
mmc erase <blk#> <cnt>
blk#:mmc设备的块号
cnt:mmc设备块的个数
擦除的时间,受cnt块的个数有影响
自启动环境变量(bootcmd)
该环境变量可以设置成一到多个uboot命令的集合(若有多个使用\;分割),自启动模式下uboot就会按照bootcmd中命令的顺序逐条执行
把printenv命令写进去,开机之后不做干预,倒计时结束就会自动打印环境
例如:
setenv bootcmd tftp 40008000 interface.bin\;go 40008000
saveenv