0
点赞
收藏
分享

微信扫一扫

uboot移植-将三星提供的uboot移植入开发板

十里一走马 2022-05-01 阅读 55

文章目录

前言

1、本次实验主要是将三星提供的uboot源码移植入当前开发板,芯片型号为s5pv210。
2、以下内容为作者边实验边记录得到,记录时较为匆忙,注意力主要放在操作上,因此一些语言上的细节可能不太严谨,而且语句比较啰嗦,文字量有点大。

一、环境搭建

第一步:检查开发板与电脑的USB驱动安装

USB驱动安装不成功,一开始以为是没有关闭数字签名,但后发现可能是Win10的版本问题,当前的驱动不适用于WIN10,于是搜索WIN10的驱动。当然,也不排除同样也要关闭数字签名,可能是我在下Win10驱动前已经做了关闭数字签名的操作,所以直接就可以了,这个问题没有继续试下去,后面有机会再看看

第二步:共享文件夹设置

1、ubuntu进入根用户

ubuntu中进入根用户,第一次需要先创建用户

sudo passwd root

创建根用户后,再输入(后面再次进入时,直接使用该命令即可

su root

2、共享文件夹

之前没有看到共享文件夹是因为没有输入这个指令

sudo vmhgfs-fuse .host:/ /mnt/hgfs/ -o allow_other -o uid=1000

注:这个指令不管是在普通用户下还是根用户下输都是一样的,但是最终只有进入到根用户下才可以看到共享文件夹,下面是共享文件夹路径

root@ubuntu:/mnt/hgfs/share_linux_windows/s5pv210/tar# 

第三步:安装交叉编译工具链

1、解压

首先在windows中将交叉编译工具链安装包放入共享文件夹,然后将共享文件夹下的交叉编译工具链解压至linux本地。

解压命令

tar -jxvf 

2、测试

在/bin目录下执行

arm-linux-gcc -v

测试中出现报错

bash: >./arm-none-linux-gnueabi-gcc: No such file or directory

经查询是32和64位不兼容造成的,找到解决方法

sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0

参考博客:

3、环境变量相关

打印环境变量

echo $PATH

就会出现这个

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

中间冒号就说明这是有好几个,而它只会搜索这些目录
新加一个路径进环境变量,这里就用到了export

export PATH=/usr/local/arm/arm-2009q3/bin:$PATH

这里后面的$PATH就是以前的PATH

在宿主目录下输入ls -a,就可以看到.bashrc, .bashrc的作用就是每一次打开终端都会执行一次.bashrc,所以把命令写进去,但是一开始刚加进去的时候是不能起作用的,因为没有打开另一个终端,这时可以用source .bashrc,也可以重新打开一个终端

注意:这个加,只在当前的用户下有用,如果切到了别的用户,也是没用的

4、给交叉编译工具链创建符号连接

下面要做符号链接了
我们下载的交叉编译链在这个目录下

/usr/local/arm/arm-2009q3/bin

创建符号连接的命令

ln arm-none-linux-gnueabi-gcc -s arm-linux-gcc

然后用ls -l 查看详细信息,执行脚本一般用source命令

写的脚本的位置

/mnt/hgfs/share_linux_windows/s5pv210/tar

5、解决共享文件夹下的Bug

使用source arm-linux.sh出现问题

command not found

执行完source命令之后,再用ls打开会发现写的东西后面多了

’$’\r’

这时先用

rm arm-linux-*

把这些全都删了

这个问题的原因在于windows里面的回车和linux里面的回车是不一样的,而这个问题在sh文件中尤为凸显,因为sh文件都是要读写的,不像txt一样只是用来看的,txt从windows转到Linux中,只是用来看的,所以发现不了,到了sh中就发现了。

解决方法:在linux新建一个vi,把windows里的复制粘贴进去就可以了。

二、uboot源码分析

1、Makefile文件解析

下面阅读uboot的Makefile代码

VERSION_FILE = $(obj)include/version_autogenerated.h
HOSTARCH := $(shell uname -m

=和:=的区别,=是叫你往后面找,比如这个$(obj)是叫你往后面找,后面有,而:=是叫你往前面找
这里有讲uname是干嘛的,uname就是和版本号有关,后面细看的时候再返回来看

HOSTARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/powerpc/ppc/ -e s/ppc64/ppc/ -e s/macppc/ppc/)

这个里面的这个|是管道,就是把前一个的输出作为输入

ifeq (,$(findstring s,$(MAKEFLAGS)))
 XECHO = echo
 else
 XECHO = :
 endif

这个是Makefile中的静默编译,使用方法就是make -s,-s会识别出来
然后还写了原地编译和单独编译的,提供了这两种方法,原地编译会污染源文件,但是单独编译不会,参考Makefile第76行,单独编译本质上就是你会多一个步骤,就是创建一个文件夹

config.mk第97行写了交叉编译工具链的细节

AS      = $(CROSS_COMPILE)as
LD      = $(CROSS_COMPILE)ld
CC      = $(CROSS_COMPILE)gcc
CPP     = $(CC) -E
AR      = $(CROSS_COMPILE)ar
NM      = $(CROSS_COMPILE)nm
LDR     = $(CROSS_COMPILE)ldr
STRIP   = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB  = $(CROSS_COMPILE)RANLIB

autuconfig.mk就是给一系列的宏赋y的,这个文件是配置后自动生成的,用来进行条件编译,影响编译走向的,这个文件是由include/configs/x210_sd.h中产生的

关于链接脚本的内容是在config.mk,而真正用到是在Makefile的2589行

而在config.mk的第129行,就把TEXT_BASE = 0xc3e00000给提取进来了

我们在之前写Makefile的时候,有一个-Tlink.lds 这个里面就指定链接地址,最早的时候还用了一种方法,-Ttext,然后我们在uboot里面两个都使用了
这里意思好像就是,在uboot中的uboot.lds中,写的链接地址是0地址,但是在Makefile中还写了一个-Ttext,那里还写了一个地址,然后用的是这里的地址,这个地址就是TEXT_BASE的地址,也就是0xc3e00000,而这个0xc3e00000其实也就是0x23e00000,因为做了一个内存映射

config.mk的第241行有一个自动推到规则,也就是说找不到那个就自动去找那个,找不到那个再自动推导那个,这里目前还不是重点,后面想细看再细看

真正用到TEXT_BASE的在config.mk的第156行

Makefile真正执行动作,用了all是在第291行

x210_sd_config :      unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

最后还有这个unconfig细节,这个是在Makefile最后定义的,然后我们在Makefile的每一个依赖里面都写了它,这个就是说我们就算配置过一次了,第二次配置的时候还是可以再配置一次,就是未配置文件,大概就是这个意思

然后这个里面做了两个动作,第二个动作比较简单,就是把

TEXT_BASE =0xc3e00000

字符串输出到那个文件里,所以到时候你在config.mk里就可以找到这句话,其实这一步你自己可以换一种方法,就是自己创建一个/config.mk,然后自己复制这句话进去,这样其实也就是这一步的动作

然后第一个动作,这个里面的MKCONFIG变量其实就是mkconfig脚本,然后后面的动作就是传参,传了6个参数
首先,第一个参数,

$(@:_config=)

这个参数是一个很有趣的参数,这个冒号本质上是一个替换功能,把等号前面的替换成等号后面的,也就是把_config替换成空,然后$@就是指目标,也就是x210_sd_config,所以最后就变成x210_sd,这就是第一个参数

KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲代表传参的个数,在这里#=6

2、mkconfig文件解析

这里面前面就用到了这个$#

while [ $# -gt 0 ] ; do

这个就是$#为6,然后大于0,成立,执行

while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*)  break ;;
esac
done

然后这时就去拿$1去匹配,$1是x210_sd,没有一个匹配上,所以是*),即只有break

注意,这里有一个细节,就是shell里面的case他是自带了break的,它自己执行完自己就会break,自己就会跳出case,所以我们写的break并不是跳出case,而直接跳出整个循环

然后这个是最难理解的

[ "${BOARD_NAME}" ] || BOARD_NAME="$1"

这是一个简易版的条件判断,如果第一个执行的结果是true,那么第二个就不会被执行,如果第一个执行的结果是false,那么第二个就会被执行,然后这个BOARD_NAME是我们在上面定义过的,定义的为空,即BOARD_NAME=,所以是false,所以第二个就会被执行

这个的理解也是一个难点

[ $# -lt 4 ] && exit 1

这个的意思就是如果第一个成立那么就要继续去执行第二个,而如果第一个不成立,那么就也不要再去执行第二个了

然后下面这个就是关键了,这个就是我们窥见的窗口了,就是这个就是我们在终端里面看到的打印信息,也就是说我们前面的是成功执行的,所以才能够看到这个打印信息

echo "Configuring for ${BOARD_NAME} board..."

从这里开始后面的内容就是创建一些符号链接文件,从第33行到第188行,至于这里为什么要创建符号链接,这里不是太理解,后面可能实际应用起来就理解了,大概的意思方便条件编译,跟可移植性有关。哦,后来理解了一下,懂了,就是符号链接后就提供了一个具体的名字,这个名字可能是大众都定义好的,就是在一般的不同的项目的文件里都叫这个名字,所以符号链接成这个名字后,条件编译就好执行,所以就好移植

链接脚本这里有一个细节,即使有两个地方可以写链接地址,一个是在链接脚本里面,直接写.0x23e00000,一个是在外面写-TEXT,然后第二种是可以覆盖掉第一种的
而uboot中的最终链接起始地址就是在Makefile中的-TEXT指定的,而这个Makefile中的-TEXT,又是从对应的make xxx_config得到的

竟然在里面没有u-boot.lds文件?

原来u-boot.lds在这里:

/root/x210v3_bsp/uboot/board/samsung/x210

一个最关键最关键最关键的地方,这个_TEXT_BASE出现在了lowlevelinit.S中的第112行

ldr     r2, _TEXT_BASE

加载链接地址到r2,然后相关位清零留下特定位,然后拿来和r1比较

pc指令就是我们当前指令运行的地址,

ldr     r0, =0xff000fff
bic     r1, pc, r0

我们把当前指令运行的地址放入r1,然后进行特定位清零
r1和r2比较
就是运行地址和链接地址比较
_TEXT_BASE本质上就是得到链接地址的开头地址,也就一定是0xc3e00000
这里为什么要特定位清零在进行比较,原因就是pc是绝对不可能和链接地址的开头地址一样的,肯定会有一部分的偏差,所以把细一点的地方去掉,得到一个大的位置,那这个大的位置去比,就可以了,相同了就行了
这个技巧很少用
这就是判断是否一样,不一样的话就是在SRAM中,一样的话就是在DDR中,从而决定是否进行下一步的时钟和DDR的初始化

真正的重定位是通过调用movi_bl2_copy函数完成的,在uboot/cpu/s5pc11x/movi.c中,在第19行

3、后面的汇编阶段和C语言阶段

在汇编阶段最后用串口打印了一个OK,还有就是用了远跳转跳到了start_armboot函数,这个跳转指令在start.S中的第411行

ldr     pc, _start_armboot

所以说uboot启动的第一阶段是汇编阶段,第二阶段是C语言阶段
start.S在这个路径下:

/root/x210v3_bsp/uboot/cpu/s5pc11x

这个远跳转指令可以从当前的SRAM阶段跳转到DDR阶段,我们在裸机阶段使用一个C语言函数进行跳转,那个不是太正规,这里这个跳转才是正规正常的。

至此,用了这个远跳转指令后,uboot就到了第二阶段,也就是C语言阶段,也就是DDR的阶段

在x210中Linux内核的镜像是放在DDR的0x30008000中

三、正式开始移植

环境配置好后,相关源码也解析完毕后,下面开始正式移植,移植过程中,一个问题一个问题去解决。

1、OK都没打印出来,说明串口没启动

先是这个这个SD checksum error,这个secure crt里面显示这个他连OK都没有打印出来,那就说明他连串口那里都没有出,没有初始化成功,因为是串口那里初始化他会打印的,OK。所以连O都没有打印出来的话,串口那也是没有成功的,但是他打印出来SD checkum error,所以说明它的开发版锁存成功了的,所以就把目标就把问题锁定在了那个开发板锁存到那个到那个串口初始化的那一段汇编的代码之间。

然后他那那一段汇编的代码是放在了board/cou/start.S,你找到那个start.S之后,它里面在在第70多行,有一个跳转,跳转到了lowlevelinit.S,在那里那个汇编文件里面就有一系列的初始化。然后那里的话,初始化的时候就是出现了开发版锁存的初始化,还有串口的初始化,然后发现在这个lowlevelinit.s里面,在那个那个开发板锁存初始化的函数,跟那个那个串口之间,串口初始化函数之间,第118行有一个PMIC的初始化,对比之后发现三星的和开发板uboot多了这个,然后正常工作的uboot并没有PMIC,PMIC是一个跟电源管理有关的一个模块,三星它的开发板是有这个模块的,所以它就写上了这个代码,但是我们的这开发板是没有这个模块的,所以它就没有这个代码,这个模块的初始化代码里面写了一些一些I2C的一些接口,就这个模块,它是用I2C跟那个cpu通信的。

因为你本身的开发版并没有那个模块,所以你再去调用这个函数的时候,他就会去用了I2C就会在找那个那个模块,找那个设备那个硬件,那个电源管理那个模块,但是他就他在那个函数里面就一直找不到,一直找不到就跳不出来,所以就一直卡死,所以在这里卡死,然后然后到后面后面的话才有那个串口,说实话所以他卡在了这里,就一直卡在这里啊,所以后面窗口都没有,所以OK都没有打印出来,所以问题是在这里。

所以你只要把三星的那个这个的这个代码这一段这一行话给他注释掉,然后再去进行配置编译,然后烧写,这个时候呢,开发板的uboot就会出现打印了,OK,串口打印成功了,而且显示了一系列的一些初始化的信息,比如说uboot版本什么什么的,就信息而言已经可以显示出很多了。但是现在启动还是没有成功的,还是后续还有一些问题需要解决。

不过现在已经把这个问题解决了,把这行的PMIC注释掉之后,已经从SD checksum error一行的一个报错,现在已经出现了很多行的一些信息出来了。

2、uboot的第二个打印信息

Uboot里面的第二个打印信息,也就是继他那个串口打印出来的OK之后的第二个打印信息,也就是那一个

U-Boot 1.3.4 (Apr 27 2022 - 06:45:37) for X210_210

这一个打印信息就是uboot里面第二个打印信息。这个打印信息是在那个board.c里面的第185行,有一个display_banner函数,那个函数里面的第一句,Printf里面有一个参数,Versionstring,那个versionstring是一个字符串,然后,那个字符串里面用了一个宏,那个宏是CONFIG_ID_ENT_STRING,然后可以打开那个宏,那个宏里面写的就是uboot第二行打印的信息里面的那个X210_210,所以你可以在这里把那个信息改掉,那么这样子uboot里面的打印信息就可以改掉了。

他的这个display_banner里面的versionstring,你去追这个函数,这个函数最后是在那个lib_arm里面的,所以你要找那个lib_arm里面的那一个versionstring的那个原型,然后在那个lib_arm的versionstring里面,他的那个打印的宏,CONFIG_ID_ENT_STRING内一个宏的定义,你去追他,他是在那个那个smdkv210single.h,它在那个头文件里。
然后你通过更改那一个宏里面的的值,那么uboot里面的第一行打印信息的值里面的那个名字就会被更改掉了。

在这里插入图片描述

在这里插入图片描述

3、uboot中第三段打印信息

uboot中的第三段打印信息是关于时钟的,这个时钟的地方我们不用改,因为这个三星的时钟配置基本都是相同的,所以这里是不用太改了,然后他的位置是在它的一些对于他的时钟的地址的一些配置,它是也是放在了那个smdkv210single.h这个头文件中,大概在第第284行到370多行之间。
其实时钟那一部分也是有可能出错的,就是你看这个SMDKB210SINGLE的H里面的,对于失踪的一些配置,比如说它的高频,低频的配置,就也是有可能会出错的,为什么?这个本质的原因是因为他可能后面的代码,它不是用那种计算的方式得到它的数字,而是直接用一个具体的数字在代码里面写死,所以你如果在这里呢,始终配置。你的频率配置错了,或者是改变了,有可能会导致后面的代码一些东西出问题,比如说你串口、串口,它可能它的代码里面写的很可能是已经写死了,就说他不是用一个红跟红之间的计算得到一个数值,而是他直接写死,比如说写了66M,这写死在里面,所以后面代码可能会出问题。

小细节(内存转化方面)

这里有一个细节,就是转换的问题,如果他的那个size写的是0X2000000的话,这个16进制你折合出来的话,它就是512M,如果是0X10000000的话,折合出来是256M。
现在那个uboot里面打印的信息中了,后面的那个DRAM,它写的是1GB,但实际上我们没有1GB,我们的DRAM只有512M,所以这里是打印出错了,这个他那个你可以去通过

bdinfo

这个命令去查看这个开发板,或者查看这个uboot的设置的一些。关于内存的一些信息,它里面写了一个start,还有一个那个size,它start写的是从0X2000000开始,这个后面是可以配的,就是0X2000跟0X3000是差不多的,然后后面主要是后面,它那个size, size写错了,它size写成了0x20000000写成了512M,实际上我们是0x1000000,应该是256M才对。总而言之就是一点,你通过bdinfo命令查看它的那个配置的东西,它的BANK0跟BANK1的大小设错了,就是size设错了。
然后现在我们是要检验一下他的那个内存初始化之后能不能工作,怎么检验呢?你通可以通过md命令去检验md,这个命令是查看内存东西的,所以你可以通过

MD 2000000 10

就是那个MD 200000000 10,这个MD命令用来读取内存里面的数据的,就是说你用MD 20000000 10,就是说你查看这个内存20000000这个地址里面的十,以十个字节为一个单位,然后去查看它的里面存的数据,真正要进行改内存里面的数据用的不是md命令,mw命令,也就是memory right,就是内存写入,一般都是用mw.l,比如说你要在20000000里面写222222,那你就是要输入命令

mw.l 20000000 2222222

然后这时你去再进行md命令,去查看那个地址里面的值,你会发现就已经改掉了。上面通过那个改那个smdkv210single.h里面的那一个内存的size,把他那个0X20000000改成0X1000000,就是在那个在那个smdkv210single.h里面的第469行。把它改完之后,你注意这里不能直接make,Make的话呢,是没有变的,你在那个securecrt里面看到的还是它低端,是1GB,你这个时候先是make先把清除,之后再配置一次,就是再配置,就是

make smdkv210single_config

这样配置一次之后,再makemake完之后再烧录,才能够把securecrt里面的SRAM从1g改成512M。

4、uboot DDR的移植

从前面那个串口的打印,还有那个内存DDR的一个参数更改总结出经验,虽然他的那些初始化函数代码都是放在那个lowlevelinit.S那个汇编文件里面,但是他在那个汇编文件里面用的宏一般都是定义在一个include/config里面的某某某点h中,实际上我们真正开始改参数的话,是在它那个include/config,什么什么点h里面的文件里去改它的宏的参数,其实lowlevelinit.S是不用改的。
在那个进行那个DDR的那个修改参数的时候,有一个问题,就是你在那个smdkv210single.h头文件的410行,你把他那个DMC0 memorconfig0,它的里面的0X200000改成0X30之后,你把它下载配置到开发板里面,你发现他那个CRT里面。它的正常的打印都打印不出来了,只打印那个checksum error,然后加上一个OK,意思就是说你如果改内存的话,只改那里是不行的,然后你要还要改一个地方,就是改到那个smdkv210single.h里面的第72行,你不要把那里的那个宏,把它也要对应改掉。
你要把那里的那个红对应改从0x2000也要改成0x3000,然后去要去配置,编译下载,然后这个时候呢,就是你也是会,你会发现他也是只是打一个OK,这也是没有正常启动u boot只打印了OK,串口成功,其他都没成功,也就说你DDR初始化除了这两步之外,还要有一步,你要去找他uboot里面那个MMU内存映射表的位置,他那个MMU内存映射那个表还要改一个地方,你要把那里改掉才行。

要找那个内存映射表,就是DDR那个MMU内存,映射表在哪里?你首先要跳回到那个start.S那个汇编文件里,在那里去找先。
然后你通过search,然后search去找 MMU的那个代码,然后发现大概是在367行,那里有个MMU
这里就是有一个,他把MMU_table_base放到了R0寄存器里,R0就是那个通用寄存器ARM的一个通用寄存器,他把那个MMU的那个,那个映射表内存映射表放到ARM的R0通用寄存器那里,在366行,那这个时候啊,我们就继续去追,追那个MMU_table_base这个东西,通过search,通过那reference去追它。

所以,DDR在smdkv210single.h的第597行,也要把他那个那个链接脚本链接里面的那个0X200改成0X300,除此之外还要在那个525行里面也要把他的23e00000改成33e00000,不过那个是在没有开启那个MMU的情况下,它才会进入这个选择,虽然我们目前已经开启了那个MMU,在目前这个阶段改不改都无所谓,但是如果你后面如果一旦一哪个时候关了MMU,你忘记改这个参数的话,那个时候的话,你的开发板uboot是启动不了的,所以保险起见,这里还是把它改成0x300000,以免后面出现uboot启动的时候,没有用到mmu的时候出现错误找不到原因。

然后这样改完之后还是不行,还是checksum error OK,后面检查问题,这个问题是一个非常底层的问题,就是你在那个smdkv210single.h的第408行,我们当时改的时候是把那个0X20e0e323改成了0X30e0e323,这里的话一个主要的问题是。前面的2改成3,这是对的,但是后面的E要改成F,你去查看后那个数据手册,那个数据手册里面关于DDR的那个描述,它的那个数据手册里面写的就是是一个取反来的,就是你如果是你的地址,如果是就是取反。
就是说你的配置寄存器的那个值是跟你的地址的范围的那个最大范围的一个取反。
如果你的地址是0X00000000到0X0FFFFFFF,那么这个时候呢,你的配置寄存器你就不能配E8了,这个时候你一个取反,那你发现它是零到到0xF0000000,所以是F0才对,不是E0。
然后这一步改完之后就不会只出现Checksum errer OK了,它还会它马上就打印出了第一行的那个命令,比如说之前写的那个我的名字的那个打印就打印出来了,然后他打印到了那个DRAM的大小512MB也打印出来了,但是就卡在了SD/MMC那里,就没有继续打印下去。

他最后打印出来的那个SD/MMC冒号,那个信息是在那个board.c的第481行打印出来的,也就是说他程序是卡在了那里
然后就就看就会想要看他的接下来的482行写的是什么,然后就卡在那里,那个是一个mmc_initialize的一个函数,那个函数肯定问题就肯定是出在这个函数上了,因为什么呢?因为这个函数里面有一个,他最后一行打印了一个信息,你没有打印出来,所以肯定是这个函数卡住了,所以你肯定是要去这个函数里面去找问题,然后这个函数里面又有三个函数。到底是哪一个函数呢?这个地方就很难搞,一般情况下的话,实在没办法,那就只能是加print f去打印,通过打印信息去调试,你在这三个函数的上下左右都加上print f,然后去打印调试,看它的问题出在哪里,然后一步一步来,这是最直接最肯定能解决的问题的方法。

这是一种解决问题的方法,但是很麻烦,然后你可以通过推断,因为我们前面的uboot已经启动成功了,所以,本质上这个问题因为我们改了某个参数,然后它变成了这样,所以从某种意义上来说,它应该还是属于配置方面的问题,就是我们在哪里配置的不对,还是哪个地方没有配对,所以我们应该还是问题还是锁定在之前的那个smdv210single.h那个头文件里面去,问题可能还是出在那里,哪个地方没有配对,因为什么呢?因为那个smdkv210single.h那个文件里面写的全是配置,所以配置出错,基本都是在那个文件里面出错,所以重点还是回归到看那个文件的配置哪个地方没有注意到。

然后根据经验去找到就会发现问题是锁定在那个MMU上,smdkv210single.h的第80行那里有一个CONFIG_ENABLE_MMU,就是说你把那个MMU使能了之后。他用的就已经不是物理地址了,他用的是虚拟地址,所以他在那个smdkv210single.h的第80行,他那个有一个虚拟地址到物理地址的一个转换,就是把mmu的那个虚拟虚拟地址转换成物理地址。

然后就重点去看那个宏,然后你进去看,进去看之后就会发现它这个文件是在smdkc110.c里面的一个函数,这个函数里面就就把他那个虚拟地址通过一个运算,先减去它的基地址,再加上他的偏移地址,就得到了他的物理地址,这一个算的话,我也没有太理清楚,总之就是他通过这个这函数算到了他的从虚拟地址得到了他的物理地址,然后这里他这里用的是0x20000000,所以我们改成应该是0x3000000,但是这样试了之后还是不行。

然后这一步不行的话,我试了一下,我一开始以为是他那个vi里面的那个大小写,我写错了,一开始以为是他那个C文件是小写的smdkc210.c,然后我写成了大写的Smdkc110.c,我以为是这个原因,所以我就把那个大写的那个S改成了小写的s,后来一式就可以了。但是我我怀疑可能不是这个原因,也有可能是我那个时候忘记复制了,忘记先执行脚本文件,所以根本就没有烧写成功,所以我在成功之后,我又试了一下,又把它那个小写s改回成大写的S,改回成大写S之后呢,正常的cp.sh之后,它也是可以工作的,所以说其实是跟那个大小写是没有关系的。

所以其实问题是出在我忘记复制了,其实是我忘记复制了,是我操作的时候有漏了一步,而不是他大小写的问题。

从这个时候起,uboot的DDR的移植就算是成功了。

5、 uboot SD/MMC移植

然后下一步是看他那个SD/MMC那里,他说他unrecognized,无法识别,SD/MMC那里还是有问题。现在重点就是看SD/MMC那里的问题。

然后你通过关键词搜索,把那个secureCRT里面的报错的那个信息复制到那个source insight里面,去找他那个打印的信息,最后发现他那个unrecognized的EXT_CSD的,定位到了他那个报打印的位置,就在mmc.c里面,所以他问题就是出在了这里,他打印出了这些信息,所以它就是出现问题的这一块。

然后那个SD/MMC那里就是有一个错误,这个错误是很难排查的,在那个drivers/mmc.c里面的第817行,你要把他那个EXT_CSD_struct的那个大于5改成大于8,就是使他能够兼容更高的版本.你把这个改完之后烧录进去,那么他整个uboot就完全启动起来了,跳到了去引导内核了,这个时候uboot已经完全启动成功了,内核的一些打印信息也出来了,内核也启动成功了。

四、后续细节移植

这个时候就只剩下uboot里面一些细节的修改了,就是比如说网卡那些打印的配置信息,uboot的串口修改等。整个uboot已经启动成功,下面的这些都是一些细节修改。

1、uboot 尝试更改串口

更改串口配置,在smdkc210single.h中的第147行,把3改成1,然后在s5pc110.h中的第1369就会走向那个条件里,随后在lowlevelinit.S的第374行就会选择串口0

尝试,发现连编译都没有编译成功,make报错说串口不对,所以怀疑是之前串口改错了,所以恢复回之前的串口代码。

后来发现问题,你把串口的参数改了,所以开发板的串口要插到另一个口了

尝试后还是不行

问题解决,犯了一个史诗级的低级错误,发现是自己serial1写成了serial11。改回来就成功了。总结,这一步主要是尝试能不能改变串口的位置,后面可能会改变串口位置,当要改变时就这样改就行。

1、uboot 网卡驱动移植(最终未解决)

三星的uboot里面用的是bank5,而我们的板子用的是bank1,所以在smdkc110.c中的第70行,把20改成4,也就是用bank1和不是bank5,然后把后面的或的值写入也是写4567,还有其他地方要改,具体看代码的注释地方

然后除此之外,还要在smdkc110single.h的第133行,把A8000000改成88000000,因为从数据手册看出,bank5的地址是A8000000,bank1的地址是88000000
还有就是#define DM9000_DATA (CONFIG_DM9000_BASE+4)
这里要把+2改成+4,这个地方很细节,前面的CONFIG_DM9000_BASE是二进制位的,而后面的4是十进制位的,也就是说,你需要把4转换位二进制位,也就是0100再去和前面的加,所以也就是说只是在第三位加了个1。而之前的+2则是加0010,也就是说只是在第二位加了个1
这里网卡是很麻烦的,本质原因就是复用,网卡的数据和地址是复用的。

使用自己移植的uboot ping 主机和虚拟机出现此报错:

operating at 100M full duplex mode
rx fifo error
rx length too big
DM9000 error: status check fail: 0x3

DM9000网卡驱动移植的关键,smdkc110.c中的

dm9000_pre_init

修改记录:
在smdkv21single.h的第434-460行,对DMC内存进行了参数更改

发现还是一样的报错

更改第435行

更改第517行

还是一样的报错

更改221行

还是一样的报错

更改220行

还一样的报错

更改624行

还是一样的报错

目前仍未解决…

五、总结

至此,三星的uboot移植整体上已成功,最终uboot可以运行,成功启动内核,但一些细节移植没有成功。鉴于后面还有一些更重要的工作,所以后面的细节问题暂时放一放,三星的uboot移植暂且告一段落。

举报

相关推荐

0 条评论