weiqi7777

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

0
阅读(2650)

一、            移植前的准备工作

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

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

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

二、            移植初体验

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

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

配置时使用:

              make   smdkv210_single_config 

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

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

clip_image002

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

clip_image003

分析运行结果:

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

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

 

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

clip_image004

修改为

clip_image006

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

clip_image008

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

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

更改config的打印信息

clip_image010

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

clip_image012

 

clip_image014

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

clip_image015

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

四、            DRAM代码移植

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

clip_image016

看出DRAM0DRAM1size值不对,应该为0x1000_0000

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

clip_image018

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

clip_image020

 

clip_image022

修改SDRAM_BANK_SIZE256 表示每一块内存大小为256M。并修改SDRAM_1SDRAM_2的基地址为对应的宏。

添加这两个宏。

clip_image024

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

clip_image025

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

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

clip_image027

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

       0x3000_0000 – 0x3fff_ffff

clip_image029clip_image031

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

clip_image033

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

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

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

开启cache,使用write buffer

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

clip_image035

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

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

clip_image036

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

clip_image038

五、            SD/MMC移植

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

clip_image040

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

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

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

clip_image042

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

clip_image044

修改为:

clip_image046

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

clip_image048

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

clip_image050

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

clip_image052

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

clip_image054

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

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

clip_image056

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

clip_image058

查看iNand的数据手册。

clip_image060

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

clip_image062

clip_image064

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

Uboot的效果如下。

clip_image065

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

clip_image067

uboot中的效果就是:

clip_image069

六、            其他一些参数的修改

修改默认的串口端口。

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

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

clip_image071

Uboot中定义了4个串口

 CONFIG_SERIAL1       表示串口0

CONFIG_SERIAL2       表示串口1

CONFIG_SERIAL3       表示串口2

CONFIG_SERIAL4       表示串口3

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

clip_image073

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

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

clip_image075

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

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

clip_image077

 

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

clip_image079

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

clip_image081

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

clip_image083

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

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

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

clip_image084

 

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

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