[文章]

【HarmonyOS HiSpark AI Camera试用连载 】初遇鸿蒙系统——3.烧录过程问题、uboot相关设置及移植前准备

2020-10-30 16:00:40  225 Hi3516DV300 Hi3516DV300开发板 HarmonyOS uboot Kernel
分享
前言
在前一篇 Hi3516DV300开发板——2.uboot、kernel、fs文件系统烧写:
https://blog.csdn.net/qq_30722795/article/details/109291349
之后,还是有很多坑的,比如 `uboot` 烧写进去后,如何根据自己手里不同的开发板,设置 `bootargs` 和 `bootcmd` 等选项。


同时最后会解决一些上一篇的小问题。




说明

bootargs:传递给内核的启动参数,告诉内核相关内容,决定内核启动后根文件系统如何挂载
bootcmd:用于实现内核的自启动的参数传递

这里有兴趣的同学,可以去看看韦东山老师的 `uboot` 的分析课程,可以结合实践去分析了解。




Uboot 启动


问题一:uboot无法启动kernel或者rootfs
说明:
其中很多人遇到的一个问题:就是当你 `uboot` 烧录进去没问题,但是去启动 Kernel 或者挂载rootfs的时候就会出现类似的错误:
## Error: "distro_bootcmd" not defined` 或者挂载根文件系统失败、uboot一直重启等。


原因:
这是因为你的bootargs和bootcmd设置和你的实际板卡外围芯片型号和硬件电路原理图不匹配,导致 Kernel启动失败。


解决:
这里用我的开发板举个例子:

  1. <div>
  2. </div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;"># HiSpark AI Camera Hi3516DV300 uboot printenv</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  3. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">arch=arm</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">baudrate=115200</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">board=hi3516dv300</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">board_name=hi3516dv300</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">bootargs=console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=15M rw</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">bootcmd=mmc read 0x0 0x80000000 0x800 0x4800; saveenv; go 0x80000000</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">bootdelay=2</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">cpu=armv7</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">ethact=eth0</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">ethaddr=7a:fb:28:6b:e7:60</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">gatewayip=192.168.1.1</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">ipaddr=192.168.1.15</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">netmask=255.255.255.0</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">serverip=192.168.1.5</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">soc=hi3516dv300</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">stderr=serial</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">stdin=serial</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">stdout=serial</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">vendor=hisilicon</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">verify=n</span></font></div><div></div>
复制代码






bootargs:主要是要告诉内核一些相关设置和 `rootfs文件系统` 的相关参数


参数分析:
  1. <div><span style="font-size: 18px; color: rgb(51, 51, 51); font-family: 微软雅黑;">console=ttyAMA0,115200n8   </span><span style="font-size: 18px; color: rgb(51, 51, 51); font-family: 微软雅黑; white-space: pre;">        </span></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">串口作为console终端,波特率为115200,8为数据,无校验</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  2. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">root=emmc <span style="white-space:pre">                                </span>   <span style="white-space:pre">        </span></span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">rootfs根文件系统挂载的介质为:eMMC </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  3. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">fstype=vfat</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">rootfs根文件挂载的文件系统类型为:vfat<span style="white-space:pre">                        </span> </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  4. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">rootaddr=10M rootsize=15M  </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">rootfs根文件系统储存的地址为10M的位置,大小为15M</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  5. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">rw<span style="white-space:pre">                                                </span>  </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">默认文件系统只读,需要在 bootargs 中加入rw 选项,文件系统才可读写</span></font></div><div></div>
复制代码



解释:


rootfs根文件系统挂载的介质一般有:
  • emmc
  • /dev/mmcblk0p3**
  • /dev/nfs(网络NFS)**
  • ...



fstype挂载的文件的类型一般有:(下一篇文章会细讲
  • vfat
  • jffs2 — SPI NOR
  • yaffs2 — SPI NAND
  • ext4  — eMMC



重要!!!!!

这里着重说明一下 rootaddr 和 rootsize,这里的addr对应上一篇 HiTools 烧录时 `rootfs` 根文件后面的开始地址和文件大小 (重要!!!!!)


如果自己编译了 内核和rootfs,这里rootaddr地址需要根据内核的实际大小去算,rootsize对应你实际文件的大小,一般向上取整!!!


比如这里uboot 大小1M,然后我自己编译的OHOS_Image.bin大小和18.6M,rootfs 大小为25.6M,这里就需要改了,修改命令为:
  1. setenv bootargs 'console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=20M rootsize=26M rw'
复制代码



计算过程如下:
文件 开始地址 文件大小
u-boot-hi3516dv300.bin 01M
OHOS_Image.bin 1M19M
useRFs.img 20M26M






bootcmd:

参数分析:
  1. <div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;"># mmc 按块儿读 一块大小是512字节</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  2. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">mmc read 0x0 0x80000000 0x800 0x4800; </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">读取emmc起始地址为0x800(单位为512B,即1MB)</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  3. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">saveenv; </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">保存uboot的环境变量设置</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  4. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">go 0x80000000</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">跳转到地址为0x80000000</span></font></div>
复制代码



解释:
  1. 命令:mmc read < device num > addr beg_addr SIZE
复制代码

参数:
  • device num: mmc的设备号,可以通过`mmc list`查询
  • addr:目标内存地址
  • beg_addr:读取的起始地址
  • SIZE:大小



这里先解释下这个读取的是 uboot的 mmc read 的作用:


简单来说,主要是内核启动的时候,把以beg_addr起始的位置读取SIZE大小 的内核文件,读到addr内存位置去,然后保存设置,跳转到addr内存位置去启动内核。


实质就是,把你烧录的OHOS_Image.bin内核文件读到内存去启动。




大小计算(!!!重要!!!)

包括我很多人开始看到这些这么多地址啊、大小的值,啥是啥啊,一脸懵逼,哪怕自己移植,也不会算,但后面细心看看不难,这里我计算一遍,看一遍,自己也算算。


这里前两个参数 `0x0 0x80000000` 是指:把内核从emmc(0x0)读出,放到0x80000000地址,所以第一个参数是设备号,第二个是设备的地址,我们不用管。


这里以我手里的板子和官方的镜像,内核,rootfs为例子:


文件 开始地址 文件大小
u-boot-hi3516dv300.bin 01M
OHOS_Image.bin 1M9M
userfs.img 10M15M



继续,后面的 0x800  是指读取的的起始地址,也就是内核( OHOS_Image.bin) ,实际就是你烧录进去emmc储存的实际物理地址,也就是那个开始的地址,但为什么是0x800


因为一个“块”为512字节:
  1. <div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">//起始地址</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">0x800(hex) ===> 2048(dec十进制)</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">2048 * 512 = 1048576 (字节)</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">1048576 / 1024 / 1024 = 1M</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  2. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">//所以0x800 = 1M</span></font></div>
复制代码



要把0x4800大小的内核文件移动到内存(0x8000000)中,计算如下:
复制代码



所以这样就很明显了,后面你的内核大小改变了,你这里的大小也就需要修改,不过是需要逆向的推回十六进制了。


修改uboot命令


如果你要修改相关命令,可以这样:
  1. <div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">setenv uboot_cmd 内容</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  2. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;"># eg:</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;"># 设置uboot 倒计时为10s</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">setenv bootdelay 10</span></font></div>
复制代码



要清除某个命令的操作:
  1. <div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">setenv uboot_cmd</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">
  2. </span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;"># eg:</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;"># 清除ipaddr</span></font></div><div><font color="#333333" face="微软雅黑"><span style="font-size: 18px;">setenv ippaddr</span></font></div>
复制代码





总结
bootcmd:设置了内核相关读取搬移和启动位置,如果内核编译大小变动了,这里的设置也就需要改变,不然无法启动内核!


bootargs :设置了 rootfs 根文件系统的相关参数,如果 rootfs变动了,这里的设置也需要改变,不然无法挂载根文件系统。


解决

最后,如果你的开发板参考我的上一篇成功的烧录了 uboot、内核 和 根文件系统,但是还无法启动,先进入 uboot`输入 pri 打印看看 bootargs 和 bootcmd 是否正确。


最后贴一张官方的 uboot 设置:


0
2020-10-30 16:00:40   评论 分享淘帖
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发表新帖