IMX6U U-BOOT移植

描述

正点原子开发板进行U-BOOT的移植和学习,记录一些过程
芯片上电后先运行一段bootloader,初始化DDR,然后将flash拷贝到DDR,最后启动LINUX内核。
这里先下载了正点原子提供的U-BOOT版本(百度网盘…)

编译U-BOOT

接着解压后使用以下命令编译U-BOOT

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- disclean //清理工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig //配置uboot 配置文件为mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 //编译

编译完成,没有报错

烧写与启动

编译完成后开始烧写
首先到正点原子的网盘上下载了Ubuntu下裸机烧写软件,据说是NXP提供的
拷贝到U-BOOT工程目录先

chmod 777 imxdownload
./imxdownload u-boot.bin /dev/sdc1 //通过sudo fdisk -l查到我的SD卡驱动名称是/dev/sdc1

烧写完成
将SD卡插入开发板
使用SecureCRT连接串口,启动,期待打印输出

什么都没有

CROSS_COMPILE版本

检查一下arm-linux-gnueabihf的版本
好吧…开发指南在交叉编译工具链安装着章上说使用7.3.1版本编译uboot后无法启动,不推荐使用,另给出4.9的版本
那么我的版本是

arm-linux-gnueabihf-gcc -v
gcc 版本 7.5.0(Linaro GCC 7.5-2019.12)

是的,我用的是之前交叉编译QT到树莓派的工具链,想要确认一下是否真的不能用,那么用4.9版本是否就可以使用呢,安装试一下看看,是不是问题出在工具链上,还是其他什么地方

重新安装交叉编译工具链

下载gcc-linaro-4.9.4版本 解压后放到~/imx/cross-compile-tool
然后设置环境变量

echo 'export PATH=$PATH:~/raspi/cross-compile-tool/' | sudo tee -a /etc/profile
source /etc/profile // 刷新环境变量

记得修改/etc/sudoers,来让你sudo的时候也能找到这个路径。不过你不能直接用编辑器修改这个文件,你必须

sudo visudo

然后在secure_path后面的路径中追加一串:~/imx/cross-compile-tool/bin
完成后
查看版本信息

arm-linux-gnueabihf-gcc -v
gcc 版本 4.9.4(Linaro GCC 4.9-2017.01)

使用管理员查看

sudo arm-linux-gnueabihf-gcc -v
gcc 版本 4.9.4(Linaro GCC 4.9-2017.01)

完成,那么后面再次编译uboot,然后没有输出,执行这条命令,之前可能把驱动名弄错了,改成/dev/sdc就可可以了,那么我们再把交叉编译工具改回7.5.0试一下

./imxdownload u-boot.bin /dev/sdc

改为7.5.0版本后也是可以运行的,上图,一个大乌龙
在这里插入图片描述
上图显示有一个错误
Net:FEC1
Error:FEC1 address not set.
FEC1是指网口1,指出网口地址没有设置
输入bdinfo 可以查看板子的信息,可以看到ethaddr = (not set)
在这里插入图片描述
这里设置网络相关环境变量 设置完成后重启
在这里插入图片描述
重启后网络报错消失
在这里插入图片描述
然后ping一下主机

ping 192.168.3.35

出现问题了,百度了一下说是和交叉编译器版本有关,难道真的不能用7.5的版本吗?
在这里插入图片描述
在一次把交叉编译器版本改到4.9,然后编译uboot,烧写。。。
这一次可以ping成功,那么为什么会出现编译器不兼容,有什么方法可以用7.5的交叉编译工具链,又不出现问题呢!据说是需要用高版本的UBOOT,而NXP所提供的uboot是低版本的。
在这里插入图片描述
那么UBOOT暂时使用4.9版本的交叉编译工具链。。。

NFS命令

将linux镜像和设备树放到主机上,uboot使用nfs命令将镜像和设备树下载到DRAM中。

主机操作

首先在主机上安装网络工具

sudo apt install net-tools

安装NFS服务

#以下命令在主机上运行
sudo apt install nfs-kernel-server

查看用户ID

#以下命令在主机上运行
id

查到本开发主机的用户uid和组gid均为1000

配置NFS

使用vim打开/etc/exports文件命令如下:

sudo vim /etc/exports

在/etc/exports文件末尾添加如下语句并保存

/home/xxxx/share 192.168.3.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000,no_subtree_check)

我选择的网段是192.168.3.0,主机的IP是192.168.3.35,开发板设置的IP是192.168.3.50,我事先在主机上新建了一个共享文件夹/share:

mkdir ~/share

更新exports配置

修改完成/etc/exports文件并保存后,可以使用exportfs命令更新配置

sudo exportfs -arv

该命令的参数说明如下:

-a:全部mount或umount文件/etc/exports中的内容。
-r:重新mount文件/etc/exports中的共享内容。
-u:umount目录。
-v:在exportfs的时候,将详细的信息输出到屏幕上。

至此,在主机上安装NFS服务完成。

将镜像文件放到share中

下载zimage到share文件夹中

将zimage下载到开发板的DRAM中

可以使用

nfs [loadAddress] [[hostIPaddr:]bootfilename]

loadAddress 是要保存的 DRAM 地址,[[hostIPaddr:]bootfilename]是要下载的文件地址。
这里把zimage放到开发板 DRAM 的 0x80800000这个地址处,使用命令是:

nfs 80800000 192.168.3.35:/home/shen/share/zImage

使用此命令后出现:

Loading: *** ERROR: File lookup file

导致此错误得原因是:uboot中使用得NFS版本为V2版本,而ubuntu中的NFS版本为V3,V4及以上版本,从而导致uboot不能再NFS服务器中找到文件。
解决办法为:让buntu中得NFS兼容V2。修改/etc/default/nfs-kernel-server 文件。

修改如图:
在这里插入图片描述这里修改完成后重启NFS服务器:

sudo service nfs-kernel-server restart

重新执行:

nfs 80800000 192.168.3.35:/home/shen/share/zImage

这次显示下载成功了。
使用以下命令查看前0x100字节的数据:

md.b 80800000 100

但是用winHex打开zImage文件后发现两边数据不一致。
检查一下问题出在哪里?
重新执行了一次

nfs 80800000 192.168.3.35:/home/shen/share/zImage

这一次对比后居然是一致的,十分奇怪。。。

使用NFS在UBOOT中更新UBOOT

UBOOT中支持EMMC和SD卡,提供了EMMC和SD卡的操作
在这里插入图片描述这里主要用到"mcc wirte"命令:

mcc write addr blk#cnt

addr 是要写入 MMC 中的数据在 DRAM 中的起始地址,blk 是要写入 MMC 的块起始地址
(十六进制),cnt 是要写入的块大小,一个块为 512 字节。我们可以使用命令“mmc write”来升
级 uboot,也就是在 uboot 中更新 uboot。
首先我们需要把mmc默认设备切换到SD卡

mmc dev 0
version		//查看版本号

通过version可以查看现在uboot的版本号
然后我们重新编译uboot,将编译出来的u-boot.imx拷贝到share文件夹中,然后使用命令:

nfs 80800000 192.168.3.35:/home/shen/share/u-boot.imx

将uboot下载到DRAM的0x80800000处,可以看到我这次下载的uboot的大小,我这部是384k字节,384000/512=750,所以本次要向SD卡中写入750个块,使用命令“mmc write”从 SD 卡分区 0 第 2 个块(扇区)开始烧写,一共烧写 750(0x2EE)个块,命令如下:

mmc dev 0 0
mmc write 80800000 2 2EE

输出:

MMC write:  dev # 0 , block # 2 , count 750 ... 750 block written: OK

然后我们重启开发板,查看版本号:

version

查看输出,可以看到uboot 的编译时间发生了变化。说明更新成功了,再也不用把SD卡拔出来烧写了。
千万不要写SD卡和EMMC的前两个扇区,里面保存着分区表

NAND操作

前面写了EMMC和SD卡的操作,那么NAND flash要怎么操作呢?
输入:

? nand

我手上现有这块核心板是EMMC的,编译uboot的时候使用的是emmc的配置,所以在这里使用nand命令会"unkown command ‘nand’"。
NAND也支持write写入,命令如下:

nand write addr off size

addr 是要写入的数据首地址,off 是 NAND 中的目的地址,size 是要写入的数据大小。
由于 I.MX6ULL 要求 NAND 对应的 uboot 可执行文件还需要另外包含 BCB 和 DBBT,因
此直接编译出来的 uboot.imx 不能直接烧写到 NAND 里面。关于 BCB 和 DBBT 的详细介绍请
参考《I.MX6ULL 参考手册》的 8.5.2.2 小节,笔者目前没有详细去研究 BCB 和 DBBT,因此我
们不能在 NAND 版的 uboot 里面更新 uboot 自身。除非大家去研究一下 I.MX6ULL 的 BCB 和
DBBT,然后在 u-boot.imx 前面加上相应的信息,否则即使将 uboot 烧进去了也不能运行。我们
使用 mfgtool 烧写系统到 NAND 里面的时候,mfgtool 会使用一个叫做“kogs-ng”的工具完成
BCB 和 DBBT 的添加。
但是我们可以在 uboot 里面使用“nand write”命令烧写 kernel 和 dtb。先编译出来 NAND
版本的 kernel 和 dtb 文件,在烧写之前要先对 NAND 进行分区,也就是规划好 uboot、linux
kernel、设备树和根文件系统的存储区域。

BOOT命令

uboot的主要工作是引导LINUX,所以BOOT命令是很重要的部分。

bootz命令

为了其的linux,我们需要将linux镜像文件拷贝到DRAM中,如果用到设备树,需要将设备树也拷贝到DRAM中。bootz命令用于自动zImage镜像,格式如下

bootz[addr[initrd[:size]] [fdt]]

命令 bootz 有三个参数,addr 是 Linux 镜像文件在 DRAM 中的位置,initrd 是 initrd 文件在
DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可,fdt 就是设备树文件在 DRAM 中
的地址。
通过nfs命令将zImage和设备树拷贝到DRAM,使用bootz启动linux

nfs 80800000 192.168.3.35:/home/shen/share/zImage
nfs 83000000 192.168.3.35:/home/shen/share/imx6ull-14x14-emmc-4.3-800x480-c.dtb
bootz 80800000 – 83000000

可以看到启动信息。
可以通过指令

fatls mmc 1:1

查看EMMC分区1里面的文件
上诉是通过网络启动,当然也可以使用EMMC启动,命令如下

fatload mmc 1:1 80800000 zImage
fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb
bootz 80800000 - 83000000

两种其的方式均启动了内核,查看打印的信息度可以看到最后出现了

Kernel panic - not syncing: VFS: unable to mount root fs on unknown-block(0,0)

这个错误是linux没有找到根文件系统,因为我们没有设置uboot的bootargs环境变量,后面会去解决这个问题。

bootm 命令

bootm和bootz功能相似,但是bootm用于启动uImage镜像文件

boot命令

boot命令是用来启动linux系统的,boot会读取环境变量bootcmd来启动linux系统,bootcmd这个环境变量保存着引导命令,可以将这个环境变量设置成我们想要的引导,这里将其设置为:

setenv bootcmd 'nfs 80800000 192.168.3.35:/home/shen/share/zImage; nfs 83000000 192.168.3.35:/home/shen/share/imx6ull-14x14-emmc-4.3-800x480-c.dtb;  bootz 80800000 – 83000000'
saveenv
boot

这样bootcmd设在为了从nfs中读取启动,每次开机后倒计时结束都会自动执行boot,尝试以下。
这样每次启动都会去主机读取镜像和设备树,然后启动,省去了每次下载到SD卡然后启动的时间。
完美。。。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值