×
单片机 > 单片机程序设计 > 详情

cortex-a8 uboot系列:第十六章 uboot移植-从三星官方移植

发布时间:2022-08-12 发布时间:
|

一、移植前的准备工作

三星移植过的uboot源代码准备

Ubuntu14.04重启网卡命令,ifdown eth0,ifup eth0

安装openssh,通过ssh远程登录linux


二、移植初体验

复制三星官方的uboot代码到linux下。

检查makefile中的交叉编译工具链是否正确

配置时使用:

makesmdkv210_single_config

然后直接make,得到u-boot.bin。


使用sd_fusing目录下的sd_fusing.sh脚本,将u-boot.bin烧录到SD中。因为sd_fusing目录下有两个文件是三星在64位系统上编译的,在32位机上是不能工作的。因此需要重新make以下生成32位下的这两个文件。

将SD卡插入到开发板中,启动电源。串口输出不正确。但是开发板供电锁存成功。

分析运行结果:

Uboot中串口最早的输出在”OK”,在lowlevel_init.S中初始化串口时打印出来的;串口无输出“OK”说明在打印“O”之前代码已经死掉了;开发板供电锁存在lowlevel_init.S中,开发板供电锁存成功说明这个代码之前的部分是没问题的。


因此,可以得出,错误是开发板供电锁存代码和串口初始化打印“O”代码之间

在lowlevel_init.S中,调用了PMIC_InitIp函数,这个函数是对外部的PMIC(电源管理芯片)进行设置,通过IIC接口。而开发板是没有PMIC的,因此这里要将这里的函数屏蔽掉。

修改为

修改后,重新编译,串口打印信息,uboot基本移植成功。但是有很多功能不能使用。

可以看到外部的SD/MMC卡初始化失败。因为没有识别到SD/MMC卡。还有DRAM的大小也不对。


三、Uboot的配置文件smdkv210single.h修改

更改config的打印信息

这样,就修改了uboot的打印信息。

更改网络相关的信息。打印的信息也随之修改。

从uboot显示看出时钟配置是正确的时钟,因此不用去设置时钟。

四、DRAM代码移植

DRAM显示信息不对,使用bdinfo打印具体信息。

看出DRAM0和DRAM1的size值不对,应该为0x1000_0000。

使用md命令进行内存数据查看。

看到0x2000_0000地址开始和0x3000_0000地址开始的数据是一样的。并且对0x20000000地址数据修改,0x30000000地址值也随之修改了。说明了地址0x30000000-0x3ffffff和0x20000000-0x2fffffff映射的DRAM区域是一样的。

修改SDRAM_BANK_SIZE为256,表示每一块内存大小为256M。并修改SDRAM_1和SDRAM_2的基地址为对应的宏。

添加这两个宏。

这样,更改了DRAM的大小。重新编译烧录,从uboot中可以看出DRAM的设置正确了。

下面要更改DRAM1的首地址,将之设置为0x3000_0000,因为开发板的DRAM的连接是这样的。这样,DRMA1和DRAM2的地址就连接起来了。

首先修改内存首地址的宏:

修改DRAM的MEMCONFIG_0寄存器的值。将DMC0_MEMCONFIG_0配置值的高16位设置为0x30F0。表示将DRAM0的基地址映射到0x30000000上。并且可用的地址范围为

0x3000_0000 – 0x3fff_ffff

修改lowlevel_init.S的MMU映射表,将597行的设置的_base的值为0x300。

定义256M空间。循环256次,建立256个表项。

虚拟地址范围:0xC000_0000-0xCFFF_FFFF

映射的物理地址: 0x3000_0000-0x3FFF_FFFF,(DMC0的有效区域,也就是外部DRAM1的区域)

开启cache,使用write buffer。

将内存的物理地址0x3000_0000-0x3FFF_FFFF映射到虚拟地址0xC000_0000-0xCFFF_FFFF

修改虚拟地址映射到物理地址的函数,将框中的数据修改为0x3000_0000。

编译下载,打印信息如下,将DRAM1的起始地址修改为0x30000000了。并且内存可以使用。

修改uboot打印的板子的信息。

五、SD/MMC移植

Uboot打印SD/MMC的信息错误,说明对对外部的SD/MMC初始化失败。

先查看这几句信息在什么地方打印出来的。

在mmc_startup函数(drivers/mmc/mmc.c),SDMMC初始化的调用的最后一个大函数。

查看打印问题,发现打印问题和EXT_CSD有关,所以查看mmc_read_ext_csd函数(drivers/mmc/mmc.c)

原来的代码如下,当ext_csd_struct值大于6,打印错误信息。而从uboot打印信息看出,这个时候的值为6。

修改为:

但是发现这个错误信息打印了两次,因为在对mmc的初始化,如果第一次初始化失败,那就再初始化一次。而第二次也会初始化失败,所以又打印了一次。

修改后,uboot执行MMC初始化成功,可以打印卡的容量大小。

扩展寄存器EXT_CSD为高版本的SDMMC卡使用。

判断卡的版本,如果低于4版本,说明都没有EXT_CSD_寄存器,就不用执行这函数,直接返回。

发送EXT_CSD命令,并将响应保存到ext_csd中。

在ext_csd有几位是表示卡的版本。对于uboot不处理MMC卡的版本大于5的情况,所以要将版本设置为大于6。

通过EXT_CSD可以获取卡的一些信息。

查看iNand的数据手册。

查看EXT_CSD_的第192字节,表示卡的版本,默认值是0x5。

在mmc_initialize函数(drivers/mmc/mmc.c)添加上述代码,对外部的SD卡进行初始化,并打印容量信息。

Uboot的效果如下。

在smdkv210single.h中,有如下一个宏,表示命令的提示符。这里修改为如下,

在uboot中的效果就是:

六、其他一些参数的修改

修改默认的串口端口。

Uboot默认使用的是串口2。可以修改为串口0。

将以下代码修改,即可将串口定向为串口0。

Uboot中定义了4个串口

CONFIG_SERIAL1表示串口0

CONFIG_SERIAL2表示串口1

CONFIG_SERIAL3表示串口2

CONFIG_SERIAL4表示串口3

配置这些宏,来配置串口的基地址是多少。

这样,就将uboot的串口定向为串口0。

将虚拟转物理地址函数修改为如下,当地址不需要转换时,不打印信息。

Uboot中有打印nand的信息,容量为0。但是开发板没有使用nand,所以要将这部分代码修改。

在start_armboot函数(lib_arm/board.c)中,初始化SDMMC后,就要去初始化NAND,可以看出NAND和宏CONFIG_CMD_NAND有关系的。

在smdkv210single.c中将宏CONFIG_CMD_NAND注释掉。表示对外部的NAND不配置。

但是编译会出错,提示和nand有关函数找不到,说明这个宏开关控制了一些nand函数的编译。

Uboot默认从nand启动,所以要将启动方式更改为SDMMC方式。

注释掉CFG_FASTBOOT_NANDBSP,表示启动介质不是nand,

定义CFG_FASTBOOT_SDMMCBSP宏,表示启动介质是SDMMC

编译成功,下载执行,打印如下信息,nand信息没有没有打印了,地址不需要虚拟转换的信息也不打印了。

以上就移植好了一个uboot。可以看出,从开发板的原厂商提供的uboot,进行移植,是相对比较容易的。


移植的关键,还是从打印信息入手。根据打印信息,去确认问题,然后解决问题。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ATMEGA16四线驱动LCD