1:什么是系统移植
1)系统移植是给开发板搭建一个Linux操作系统
2)从官方获取源码,进行配置和编译,生成板子需要的镜像
2:安装tftp服务器的作用
Tftp服务器:是基于UDP协议完成简单的文件传输
作用:通过网线下载程序到开发板中
3:安装nfs服务器的作用
nfs服务器:网络文件系统
作用:ubuntu通过网络的方式挂载文件到开发板中
4:gnu二进制工具集
1.gcc命令
2.ld链接器
3. objdump生成反汇编
4. objcopy生成二进制文件
5.nm查看符号表信息
命令:arm-linux-gnueabihf-nm asm-led.elf
6.size查看各个段大小
7.readelf查看文件头部信息
8. strip压缩文件体积
9.addr2line调试段错误信息
5:gcc编译流程
1.预处理
2.编译
3.汇编
4.链接
6:Makefile文件,目标,依赖
7:uboot概念,uboot特点?
8:常见的uboot命令有哪些?
1>help uboot--->查看uboot命令中的环境变量
2>help go
3>help gpio
4>help pri:打印环境变量信息-------->串口工具输入:pri
5>
bootargs参数功能:自启动参数,设置ubuntu挂载根文件系统到开发板上的路径和ip地址
bootcmd参数功能:自启动命令,倒计时时间进入0之前不按下enter键盘,进入自启动模式,并且执行自启动命令
6>run -------> 运行run后面的命令 格式:run uboot命令 run bootcmd
1)交互模式: 当uboot启动成功之后,在倒计时时间进入0之前,按下键盘enter键,进入交互模式,和uboot命令进行交互
2)自启动模式: 当uboot启动成功之后,在倒计时时间进入0之前,不按下键盘enter键,进入自启动模式,执行自启动命令(bootcmd)不可以使用uboot命令
3)设置bootcmd格式
setenv bootcmd uboot命令1\;uboot命令2\;...............
saveenv
4)在arm课程中,需要输入两条命令:loadb 0xc0008000 go 0xc0008000
5)在串口工具中,查看bootcmd环境变量信息
6)在串口工具中,执行run bootcmd命令,观察现象
7)在倒计时时间进入0之前,不按下键盘enter键,进入自启动模式,观察现象
7>ping命令 ------->测试开发板和ubuntu组网是否成功
8>tftp命令 ------->使用tftp命令将文件下载到开发板内存中,一定保证开发板和ubuntu组网成功
9:uboot配置和编译流程?
10:安装交叉工具编译链的作用?
交叉编译链就是为了编译跨平台体系结构的程序代码而形成的由多个子工具构成的一套完整的工具集。同时,它隐藏了预处理、编译、汇编、链接等细节,当我们指定了源文件(.c)时,它会自动按照编译流程调用不同的子工具,自动生成最终的二进制程序映像(.bin)。
11:TF-A是什么,为什么移植TF-A?
基于ARM的可信固件,简称TF-A,运行在一个硬件隔离的安全环境中并提供安全服务
目的:
①、验证开发环境搭建是否正确,比如交叉编译器设置是否正确,所依赖的第三方库有没有安装等。
②、观察编译结果,比如编译完成以后的可执行文件保存在哪个目录下,都有哪些可执行文件,其区别是啥等。
③、在自己的开发板上运行编译出来的可执行文件,所谓的移植就是改bug的过程,将编译出来的STM32MP157官方开发板可执行文件在自己的板子上运行,然后观察运行过程有没有错误,直到能在自己的开发板上正常运行。
12:TF-A配置编译流程?
1>解压源码
2>打补丁(打补丁打一次即可)
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
3>配置交叉编译工具链
进入tf-a源码顶层目录下,打开Makefile.sdk文件,搜索:CROSS_COMPILE,更改交叉编译工具链前缀
14 EXTRA_OEMAKE=CROSS_COMPILE=arm-linux-gnueabihf- DEBUG=1
注意事项:只更改交叉编译工具链前缀,其他的不要删除
4>复制相关设备树内容
1)进入tf-a源码目录下fdts目录下,复制设备树相关内容
2)进入tf-a源码目录下fdts目录下,更改复制完成后的FSMP1A相关设备树内容
5>更改Makefile文件,将对应的设备树进行添加
进入tf-a源码顶层目录下,打开Makefile.sdk文件,搜索TFA_DEVICETREE
6>编译源码(在tf-a源码目录下),生成镜像文件
make -f $PWD/../Makefile.sdk all
7>进行测试
13:给开发部署Linux操作系统(开发阶段)
1>准备文件
①:tf-a镜像文件(TF卡/EMMC)
②:uboot镜像文件(TF卡/EMMC)
③:内核镜像文件(使用tftp服务器进行下载)
④:根文件系统(使用nfs服务器实现挂载)
2>组网步骤(uboot环境变量参数:ippaddr serverip netmask gatewayip)
ums命令:
ums烧写:
1.开发板需要通过TF卡启动方式,进入到uboot界面中
2.在uboot界面中输入以下命令:
FSMP1A> ums 0 mmc 1 ------>当输入这个命令时,会在电脑中出现弹框,需要连接到虚拟机中
3.在ubuntu中,查看一下是否识别到设备: ls /dev/sd*
4.在uboot源码目录下执行烧写命令:./sdtools.sh /dev/sdb
5.测试:将开发板拨码开关拨到EMMC启动方式
6.如果可以进入到安全模式,代表uboot镜像文件,烧写到EMMC中成功
3>设置自启动参数和自启动命令
1.在串口工具,对uboot组网参数进行配置
FSMP1A> setenv serverip 192.168.1.250
FSMP1A> setenv ipaddr 192.168.1.100
FSMP1A> setenv netmask 255.255.255.0
FSMP1A> setenv gatewayip 192.168.1.1
FSMP1A> saveenv
2.测试开发板与ubuntu是否连接成功
FSMP1A> ping 192.168.1.250
4>查看挂载是否成功
①:流程图
1.在开发板中emmc设备或者TF卡设备中固化uboot镜像文件
2.在ubuntu中~/tftpboot目录下,准备好基于tfp服务器下载的文件(设备树文件和uImage镜像文件)
3.通过开发板的拨码开关,选择开发板的启动方式
4.开发板上电,uboot镜像文件加载到开发板内存中
5.在串口工具打印uboot信息,在倒计时时间进入0之前,按下enter键,进入交互模式
6.使用tftp命令通过网线下载镜像文件到开发板中,下载内容为设备树文件和uImage镜像文件
7.下载成功之后,linux内核进行启动,启动成功之后
8.通过网线实现从ubuntu挂载根文件系统到开发板中
9.挂载成功之后,在串口工具,可以查看到~/nfs/rootfs目录下相关内容
②:使用tftp命令下载镜像文件
1.将群里发的设备树文件和uImage镜像文件,拷贝到ubuntu中~/tftpboot目录下
2.在串口工具,将镜像文件(uImage)文件下载到开发板内存中
FSMP1A> tftp 0xc2000000 uImage
3.在串口工具,将设备树(stm32mp157a-fsmp1a.dtb)文件下载到开发板内存中
FSMP1A> tftp 0xc4000000 stm32mp157a-fsmp1a.dtb
③:设置bootargs参数
1.在串口工具,设置bootargs参数
FSMP1A> setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/ubuntu/nfs/rootfs,tcp,v4 rw console=ttySTM0,115200 init=/linuxrc ip=192.168.1.100
FSMP1A> saveenv
2.解释bootargs参数:
root=/dev/nfs:使用nfs服务器挂载
nfsroot=192.168.1.250:/home/ubuntu/nfs/rootfs:挂载的ip地址和路径,注意自己的路径和ip地址
tcp,v4:型号
rw :可读可写权限
console=ttySTM0:默认使用串口0
init=/linuxrc:默认启动1号进程
115200:波特率
ip=192.168.1.100 :板子的IP地址
3.启动内核
bootm 0xc2000000 - 0xc4000000
④:设置bootcmd参数
FSMP1A> setenv bootcmd tftp 0xc2000000 uImage\;tftp 0xc4000000 stm32mp157a-fsmp1a.dtb\;bootm 0xc2000000 - 0xc4000000
FSMP1A> saveenv
14:为什么移植内核
因为uboot是一个裸机程序,引导内核启动成功之后,生命周期就结束了,所以需要移植linux内核
内核五大功能
1.进程管理:进程创建/进程销毁/进程调度
2.内存管理:内存申请和释放
3.网络管理:通过网络协议栈,完成数据的收发
4.文件管理:通过文件系统管理ext2/ext3/ext4等格式来管理文件
5.设备管理:字符设备管理/块设备管理/网卡设备管理
linux内核特点
1.linux内核是开源的,内核源码是由C语言和汇编语言编写完成的
2.linux内核支持多种硬件架构平台(ARM架构/X86架构)
3.linux内核有很好的移植性和裁剪性,通过图形化界面进行选配
15:linux内核移植
1>分析README文件
2>linux内核配置编译流程
1>配置交叉编译工具链
2>打补丁
3>配置补丁文件
4>复制参考板设备树内容
5>更改设备树相关内容,头文件包含
6>添加编译设备树相关内容
7>编译内核,注意编译内核命令
8>找到对应的目录,查看是否生成对应镜像文件
16:Makefile/Kconfig/.config三个文件的关系
1.Makefile:内核源码编译和配置文件
2.Kconfig:存放基于执行make menuconfig命令时,生成图形化界面配置信息内容
3: .config:存放配置相关所有信息,给Makefile进行使用
关系图:
17:Kconfig语法
1.概念
主菜单:可以包含子菜单和菜单选项
子菜单:可以包含子子菜单和菜单选项
菜单选项:不可以包含子菜单,只可以包含菜单选项
2.打开linux内核源码目录下Kconfig文件,对Kconfig文件进行分析
1)mainmenu --------->主菜单
格式:mainmenu "主菜单名字"
2)source --------->导入子菜单
格式:source "路径/Kconfig"
3.打开linux内核源码进入drivers目录下打开Kconfig文件,对Kconfig文件进行分析
1)打开文件查看信息
menu "Device Drivers"
endmenu
2)menu ------ endmenu ------->菜单
格式:
menu
可以包含子菜单和菜单选项
endmenu
4. 打开linux内核源码进入drivers/char目录下打开Kconfig文件,对Kconfig文件进行分析
1)打开文件查看到信息
menu "Character devices"
endmenu
2)config----->菜单选项
格式:
config 配置菜单选项(一般大写)
3)depends on ---->依赖其他菜单选项
4)default ---->默认菜单选项
default y ---->默认菜单选项[*]
default n ---->默认菜单选项[ ]
default m ---->默认菜单选项<M>
5)bool / tristate
bool:菜单选项支持两态 [ ] *和空格
tristate:菜单选项支持三态 < > *和空格和M选项
6)help ------->编写帮助信息
格式:
help
帮助信息内容
18:在内核中如何添加自己的led灯驱动
1>准备led灯驱动代码
2>将led灯驱动代码拷贝到drivers/char目录下
3>编写自己的图形化界面信息(Kconfig语法)、
config LED_DRIVER
bool "led driver"
default y
help
this is DC22081 LED_DRIVER
4>在Makefile文件添加编译文件信息obj-$(CONFIG_LED_DRIVER) += fsmp157a_led.o
19:bool和tristate区别
1.bool-------->菜单选项支持两态
[*] -------->对应的驱动被编译到uImage镜像文件中
[ ] -------->对应的驱动不被编译到uImage镜像文件中
2. tristate:菜单选项支持三态 <*> 和空格和M选项
<*> -------->对应的驱动被编译到uImage镜像文件中
< > -------->对应的驱动不被编译到uImage镜像文件中
<M> -------->对应的驱动采用模块化方式进行编译,执行命令:make modules
20:内核启动流程
1.完成内核自解压(因为内核源码是经过gzip进行压缩的)
2.校验CPUID是否正确(确定使用哪个核)
3.读取内核传递过来的参数,需解析自启动参数和自启动命令(也就是uboot启动成功后,传递过来的两个参数bootcmd和bootargs)
4.创建页表,启动mmu内存管理单元,清除bss段
5.跳转到C函数入口(start_kernel)
6.完成大部分硬件初始化(串口/时钟/电源管理.......)
7.解析uImage镜像文件和设备树文件
8.调用对应驱动程序执行
9.启动内核一个init进程,挂载根文件系统,并执行应用程序
21:采用模块化方式编译驱动
1>编写自己的图形化界面信息(Kconfig语法)、
config LED_DRIVER
tristate "led driver"
default y
help
this is DC22081 LED_DRIVER
2>通过make menuconfig,将图形化界面信息配置为<M>
3>采用模块化方式编译命令:make modules
4>编译成功之后,会生成对应的*.ko
5>需要使用这个驱动时,执行安装insmod *.ko
6>不需要使用这个驱动时,执行卸载rmmod *.ko
22:为什么要制作根文件系统
1)内核启动成功之后,运行在3G~4G空间,用户不可以直接操作内核空间
2)内核启动成功之后,没有ls/cp/mv....相关命令,但是根文件系统中有相关命令
23:什么是根文件系统
根文件系统(rootfs):系统运行时,必须依赖的一些脚本文件,库相关文件 根文件系统镜像文件(ramdisk.img):根文件系统经过一种特殊的压缩格式文件
24:根文件目录
bin:命令文件(通过busybox工具制作)
dev:设备文件(被操作系统识别的设备才有对应的文件)
etc:配置相关文件(配置内核相关的一些信息)
lib:库文件目录 home:家目录
mnt :挂载目录
root:用户权限(板子本身就是以root用户运行)
sys:系统文件(系统运行时,系统加载后才会有的文件)
tmp:临时文件
usr:用户文件(通过busybox工具制作)
var:存放下载的文件和软件
proc:与进程相关的文件
sbin:超级用户命令
25:根文件系统制作过程
1.进入busybox-1.35.0 目录,打开Makefile文件,配置交叉编译工具链,搜索:CROSS_COMPILE
2.在busybox-1.35.0 源码目录下,清除中间文件
3.在busybox-1.35.0 源码目录下,配置图形化界面信息,执行命令 make menuconfig
1)使用静态库,不适用共享库,配置交叉编译工具链
2)支持vi风格编译器
3)设置根文件系统安装时名字
4)支持所有模块化命令
4.对busybox源码进行编译
5.执行安装命令
6.进入家目录下,将之前的rootfs进行备份
7.在busybox-1.35.0 源码目录下,将rootfs目录拷贝到~/nfs
8.开发板重新上电,观察现象
26:将根文件系统制作成ramdisk.img
1.进入到家目录
2.在家目录下,通过命令进行制作一个64M镜像文件
3.将ramdisk制作成ext4格式
4.将制作的ramdisk镜像文件挂载到/mnt目录下
5.查看~/nfs/rootfs大小
6.对~/nfs/rootfs/lib进行压缩
7. 将~/nfs/rootfs/所有内容,拷贝到/mnt目录下
8.取消挂载
9.压缩镜像文件
10.使用mkimage工具,添加64字节头部信息,制作成ramdisk.img
mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
-n:指定镜像文件名
-A:指定架构
-O:指定操作系统
-T:指定镜像文件类型
-C:指定镜像文件压缩方式
-d:指定镜像文件