基于迅为RK3399的开发板移植原厂 uboot ,记录 uboot 的移植的全过程,包括重点注意事项以及遇到的具体问题记录。
uboot的主要作用是引导和加载内核,芯片上电后,会先初始化硬件,例如DDR等,将Linux内核拷贝到DDR中,并启动它。
开发板:迅为rk3399;
DDR3:2GB;
EMMC:16GB;
显示屏:7寸 LVDS 电容屏,分辨率800*1280。
1. 获取一份RK官方的uboot 源码,通常我们移植的uboot并非uboot官方发布的源码,而是芯片厂家根据芯片已经移植好的uboot源码,然后针对厂家移植好的uboot源码根据自己的开发板进行二次开发。市面上的开发板基本都会参考芯片厂家的硬件设计,所以一般烧录芯片厂家提供的uboot镜像也是能跑起来的;
2. 配置好编译环境;
3. 准备好一份能在开发板上跑起来的linux镜像,证明板子是正常的。
RK不提供最新的bsp个人下载服务,可以在迅为提供的网盘中下载uboot源码,并解压,如下:
进入到u-boot文件夹里,这就是我们需要的uboot的源码了,后面就可以进行二次开发了;
u-boot文件夹下有个make.sh,它是个编译脚本,命令行输入 ./make.sh help ,查看具体编译指令,如下图:
第一次编译的时候,uboot目录下并没有 .config 配置文件,需要指定默认的配置文件;
要编译RK3399,使用的deconfig 文件为configs/rk3399_defconfig 下的默认配置文件,则可以
直接使用命令./make.sh rk3399 来编译3399 的uboot;
生成烧录两个镜像文件uboot.img和trust.img;
在烧写生成的两个镜像文件之前,先在开发板上烧写完整的 linux镜像,验证开发板能正常启动后再烧写uboot.img和trust.img;
打开调试终端,u-boot中默认的调试串口波特率是1.5M,重新启动开发板,查看打印信息,Linux是否能启动。
有很多的调试终端不支持1.5M的波特率,我们可以把波特率重新配置下,再u-boot文件夹下输入命令:make menuconfig配置;
配置完后,会生成一个 .config 配置文件,这时候直接使用命令 ./make.sh 编译,不需要重新指定默认配置文件了,编译成功后重新烧录镜像文件即可。
在调试终端查看打印,如下:
说明Linux内核已经启动了。
通常情况下,我们不对默认的配置文件进行修改,都是重新创建一个配置文件进行修改;
迅为的3399开发板参考了RK 官方的evk 开发板,所以我们可以CP 一份官方的evk 开发板的设备树文件,该设备树文件在 arch/arm/dts/下,
然后打开 itop-rk3399.dts 文件修改头文件;以后要修改uboot设备树都是在 itop-rk3399.dts文件下修改了;
创建了新的设备树文件,就需要把它添加的Makefile文件中,不然不会参与编译;
修改dts/下的Makefile文件,如下:
在u-boot/目录下创建一个名为 build.sh 的编译脚本,把编译需要用到的命令都写进去;
我们知道了rk3399的默认配置文件是rk3399_defconfig,
CROSS_COMPILE指定编译器路径;
make distclean:清空编译生成的文件;
make:编译uboot;
./make.sh uboot和 ./make.sh trust:调用make.sh打包镜像。
build.sh编译脚本适用于第一次编译或者需要重新配置uboot,如果u-boot下已经配置生成了.config文件,就不要使用make rk3399_defconfig命令了,不然就会使用默认的配置生成 .config,此时通过make menuconfig生成的 .config 就会被替换掉。
#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=/home/topeet/workspace/uboot_rk3399/rk3399_linux_v2.0_210520/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
make distclean
make rk3399_defconfig
make
./make.sh uboot
./make.sh trust
可以使用uboot命令查看信息,命令支持Tab键补全,输入指令:help 查看可以使用的指令;
u-boot目录下,使用 make menuconfig 命令修改延时时间,我修改为 3S ,就会延迟3秒再进行uboot启动,3S 内按下(ctrl+c)就可以进入到uboot模式使用uboot命令了。
bdinfo:用于查看板子信息;
printenv:用于输出环境变量信息;
version:用于查看 uboot的版本号;
setenv:用于创建或者修改环境变量的值;
saveenv:用于保存修改后的环境变量;
通常环境变量是存放在外部 flash中,uboot启动的时候会将环境变量读取到 DRAM中。
所以使用命令 setenv修改的是 DRAM中的环境变量值,修改以后要使用 saveenv命令将修改后的环境变量保存到 flash中,否则的话uboot下一次重启会继续使用以前的环境变量值。
修改的环境变量值可能会有空格,这个时候环境变量值就得用单引号括起来;
刚开始的时候指令集中没有saveenv指令,只有save指令,输入该指令显示如下,显然并没有保存环境变量;
没有saveenv指令,需要去make menuconfig配置uboot,把环境变量保存在MMC设备中,如下:
重新烧录,继续输入命令,保存成功;
格式跟修改环境变量一样;
要删除一个环境变量只需要给这个环境变量赋空值即可;
环境变量 描述
ipaddr 开发板ip地址,可以不设置,使用 dhcp命令来从路由器获取 IP地址。
ethaddr 开发板的MAC地址,一定要设置。
gatewayip 网关地址。
netmask 子网掩码。
serverip 服务器IP地址,也就是 Ubuntu主机 IP地址,用于调试代码。
验证开发板的网络能否使用,是否可以和服务器 (Ubuntu主机 )进行通信;
只能在 uboot中 ping其他的机器ip,其他机器不能 ping uboot;
因为 uboot没有对 ping命令做处理,如果用其他的机器 ping uboot的话是行不通的。
用于从路由器获取 IP地址,开发板是连接到路由器上的;
如果开发板是和电脑直连的,那么 dhcp命令就会失效。
bootz、 bootm和 boot 不祥说,用到再去查看使用方法;
重启开发板;