千家信息网

S5PV210-uboot移植-从三星官方uboot开始移植

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,11、1、uboot移植前的准备工作1、三星移植过的uboot源代码准备(1)三星对于S5PV210的官方开发板为SMDKV210,对应移植过的uboot是android_uboot_smdkv210
千家信息网最后更新 2026年11月01日S5PV210-uboot移植-从三星官方uboot开始移植



11、1、uboot移植前的准备工作

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

(1)三星对于S5PV210的官方开发板为SMDKV210,对应移植过的uboot是android_uboot_smdkv210.tar.bz2在资源下载中

(2)这个源代码网上是下载不到的,刚开始是下载不到的,三星官方是不会把这些东西放在官网上下载的。这些东西最初都是随着官方的开发板一起流出的。


2、SI的准备

(1)移植的时候,最重要的工作就是看代码,改代码,编译运行测试

(2)编译代码必须在Linux中进行编译(因为要创建符号链接,Windows共享文件夹中配置uboot是不行的),看代码和改代码可以在Linux中(vim)也可以在windows中(SI)。

(3)正确的方法,应该是,在windows中解压一份uboot源代码,在Linux也解压一份源代码,这两分开始时是一模一样的,然后我们移植的时候,是在windows中的这一份去看代码,改代码,然后在Linux中这一份去编译烧写。这种做法需要在windows中和Linux中两分代码之间保持一个同步,就是你windows中改过了后,要把改过后的源代码复制到Linux中那一份去覆盖Linux里面的同目录通文件

(4)问题来了,怎么在windows中和Linux中去同步代码?通过共享文件夹在Linux中进行复制,也可以通过一些专用的工具sshsecureshell


11、2、便捷文件传输工具sshsecureshell

1、windows中安装sshsecureshell客户端


在Ubuntu10.04版本中,重启网卡的命令是 /etc/init.d/networking/ restart

在Ubuntu14.04版本中,重启网卡的命令是 ifdown eth0 ifup eth0 校园网时发现NAT模式下好使


11、3、Ubuntu14.04上网及安装openssh

1、虚拟机上网要注意,你是用桥接上网的,还是NAT模式上网的。第二个要注意,Ubuntu中网络的配置文件中的,/etc/network/interfaces 这个文件中是配置网卡信息的,是静态IP还是dhcp静态IP是多少。第三个如果是桥接模式要注意,要注意桥接到哪个网卡上,一般笔记本有两个网卡,有限网卡和无线网卡。如果是NAT模式是没有关系的。

Ubuntu14.04中重启网卡的命令变了,ifdown eth0 ifup eth0。


如果用的校园网的话,你要想上网只能通过NAT模式,因为我们的电脑要连到校园网的dhcp服务器上,会自动给我们电脑和ubunut分配一个ip地址,所以/etc/network/interfaces 这个文件中的内容,要设置成dhcp自动获取IP地址的方式,同时网络中心中的虚拟机获取方式也要设置成自动获取ip地址的方式。


如果用wife的话,NAT模式也好时,桥接模式也好时。

如果你想让虚拟机Ping通windows,首先虚拟机要选择桥接模式上网,要桥接到有线网卡上,同时由于windows有bug,所以widows的网上口,必须用网线连接到一个有上网能力的地方。之后将,Ubuntu中的/etc/network/interfaces 文件中改成static静态模式,因为这样在每次开机的时候ip地址就不会变了。将里面的ip地址设置成和我们主机windows在同一个网段上。之后重启网卡ifdown eth0 ifup eth0 ,在Ubuntu终端下,ping主机,如果ping通了,就OK了,这时你的SSH通信就可以了。openssh类似的工具就可以使用了


2、搭建openssh环境

(1)、ubuntu上网

(2)、安装openssh-server。如果报错提示依赖错误,可以参考:http://www.cnblogs.com/mliudong/p/4094519.html


(3)securecrt登录

(4)sshsecretshell登录 两者都可以

如果ssh登录不上,要修改/etc/ssh/sshd_config,参考:http://blog.sina.com.cn/s/blog_5f435c130102v6pv.html。 修改完重启时如果/etc/init.d/ssh restart不起作用,可以使用:ps -e | grep ssh,看sshd的进程号,然后kill -9 进程号杀死ssh进程以达到重启的目的,或者直接重启ubuntu系统。





11、4、三星的uboot移植

0、先直接用三星移植过的uboot,看什么情况

1、将uboot复制到Linux的源生目录下,解压。

2、检查makefile中的交叉编译工具链

3、配置,我们配置的时候,因为三星的是smdkv210xxxx,所以我们先重第一个开始试,先用smdkv210single_config来配置一下试试,用这个的话,我们配置头文件是在include/config/smdkv210single.h

4、配置完成后,直接make编译,完了之后直接烧录到SD卡上,启动下试试。

5、在uboot/sd_fusing/sd_fusing.sh 这个脚本是用来烧录的。但有时这个脚本需要修改一些的东西,看脚本中的BL1的位置在哪里,还有整个uboot的大小分别放在了SD的哪个扇区。多少个扇区。应该是1和49,可以从uboot的源代码中找到那个计算公式,自己推到出来。在烧录的过程要看烧录运行时的打印出来的信息,分析看烧录没烧录成功,注意mkdbl1 和sd_fisk文件的属性位数是否和我们当前Ubuntu的位数一致。

6、烧录成功后,插到开发板上试一下。


11、5、 1、代码分析,问题查找

1、插到开发板上启动后,发现打印出来SD 检查错误(这个信息是IROM中做的)。但是电源自锁是工作的。

回想,uboot串口打印信息时,最早打印的是OK,是在start.S中的lowlevel_init中初始化时打印的。串口没有输出O,说明代码在没有执行到O之前,代码就已经死掉了。但是开发板的供电锁存是成功的,供电锁存也是在start.S中的lowlevel_init中,所以说在供电锁存的前面一部分代码是没有问题的。所以可以初步判断,错误在供电锁存之后和串口打印出来O之前这一段代码就有问题了。

2、接着就需要代码的分析了,在windows下建立SI工程。发现可能是lowlevel_init.S中调用PMIC的问题,因为我们开发板并没有这个电源管理芯片,所以当我们调用这个函数的时候,I2C向PMIC发送信息是得不到PMIC电源管理芯片的应答的,所以程序死在了这里。

将上面这个调用PMIC的函数屏蔽掉后,发现uboot可以启动了。但是很多的配置信息是有问题的,很多的功能应该也是不能用的,都要去查验。



3、更改开始打印的uboot版本号后们的值,在start_armboot函数中的调用的display_banner函数中的version_string对应的宏的值,也就是这个宏CONFIG_IDENT_STRING的值为for"xxx",这个宏在smdkv210single.h中,这是关键配置的头文件。改完后,同步到Linux源生目录下,之后在make distclean, make smdkv210single_config, make


4、时钟配置

时钟的代码是不用修改的,在lowlevel_init.S中,因为我们三星用的芯片也是这个芯片,我们用的芯片也是这个芯片,所以我们大多数关注的应该是开发板级别的移植,从串口打印的信息也可以看出来,时钟的配置确实是对的,如果想改时钟的配置,也只是需要在smdkv210single.h头文件中打开或者关闭一个宏即可。如果要改时钟的配置,不用改时钟函数中的代码,只需要改动配置头文件smdkv210single.h中的宏的配置就行。


5、DDR配置信息的更改

(1)因为三星的uboot运行时打印出来的DDR大小是1G,但是我们的DDR是512M的,所以有问题,DDR的相关信息是有问题的。可以在uboot运行的时候,用bdinfo命令看DDR等更多的信息。从bdinfo命令打印出来的信息可以看出来,DDR的起始地址三星配置为0X20000000和0X40000000,DDR的大小每片都配置成了0X20000000(512M大)。

(2)我们使用md命令和mw命令,分别读DDR的内存中的内容,和往内存中写东西,发现DDR是可以用的,所以说明DDR的初始化是成功的,只是配置的不对,我们在访问0X30000000地址时,发现访问的情况和访问0X20000000的情况是一样的,可以说明我们的DDR本身确实是没有512M大的,只有256M大小的,那为什么访问0X30000000和访问0X20000000内存地址处的情况一样呢,可能是内存本身的一些特性,也可能是代码中实现的。


6、DDR地址另外配置

(1)目标,将DDR端口0的起始地址配置为0X30000000,配置成30000000开头的地址就可以和我们板子上的bank1第二片DDR的40000000地址连起来了。因为我们的板子上的大小是256MB。

(2)DDR初始化的代码在lowlevel_init.S中,初始化的代码是不用我们改的,我们只需要改在include/configs/xxx.h中的宏配置就行。

(3)关于DDR相关参数的设置,要结合我们开发板的数据手册进行配置。

将配置头文件中的#define DMC0_MEMCONFIG_0 0x20E01323 改成 #define DMC0_MEMCONFIG_0 0x30E01323

这样的话,将来往那个DMC0CONTRL寄存器中写入的值就变了,寄存中的值变了,相应的硬件就会发生了变化,地址就真的映射到了3开头的地址去了,但是硬件变了,但是软件的配置还没有变,所以我们要把配置文件中的这个宏#define MEMORY_BASE_ADDRESS 0x20000000 内存的基地址也改成 0X30000000,这个是在软件架构成,我们告诉uboot内存的起始地址是从哪里开始的

(4)虚拟地址映射表中相应修改

uboot中开启了MMU对内存进行了段式映射,有一张内存映射表。

(5)怎么找这个虚拟地址映射表呢?

现在start.S中找_mmu_table_base:

.word mmu_table

找到mmu_table相关的符号,找到了mmu_table在去在SI中索引mmu_table处,最后找到是在lowlevel_init.s中。

怎么看呢?

.set __base,0

// Access for iRAM

.rept 0x100

FL_SECTION_ENTRY __base,3,0,0,0

.set __base,__base+1

.endr

意思是从0地址开始的地方到0X10000000地址的地方这256M的空间原样


.rept 0x200 - 0x100

.word 0x00000000

.endr

意思是0x20000000-0x10000000,这段地址映射到了0地址,应该是不可以访问的


.set __base,0x200

// should be accessed

.rept 0x600 - 0x200

FL_SECTION_ENTRY __base,3,0,1,1

.set __base,__base+1

.endr

意思是0x200开头的地址范围到0x600映射到0x200,开始的地址,原样映射


.rept 0x800 - 0x600

.word 0x00000000

.endr

意思是0x8000-0x600地址也是不可访问的


set __base,0x200

// 256MB for SDRAM with cacheable

.rept 0xD00 - 0xC00

FL_SECTION_ENTRY __base,3,0,1,1

.set __base,__base+1

.endr

意思是0x200开头的地址被映射到了0XC00到0XD00范围,一共是256M


(6)所以我们虚拟地址映射表中,应该把C0000000-D0000000地址空间映射到30000000-40000000这个256MB的地址中去

方法是:修改这样

set __base,0x300

// 256MB for SDRAM with cacheable

.rept 0xD00 - 0xC00

FL_SECTION_ENTRY __base,3,0,1,1

.set __base,__base+1

.endr

(7)修改完以后,在细细的检查一下配置头文件中的,关于内存的宏的配置是否正确,主要是看地址是否是我改过的。


(8)运行时,发现只打印出来了OK,经过分析,发现是DMC0_MEMCONFIG_0的问题,把这个宏的值改成0X30F01323,之后在编译烧录,运行,发现好了一部分了。但是到SD卡打印的那段就不运行了。

(9)经过分析是虚拟地址到物理地址的映射函数中的问题。将-0x20000000改成-0x30000000,在 uboot/board/samsung/smdkc110/smdkc110.c中。


(10)iNand驱动问题的解决

@1:先从现象定位问题。将打印出来的错误信息,找到关键字在SI中搜索,发现问题的所在地方,在看当前位置的上下文,来理解是什么原因造成的,最后发现是从mmc设备的扩展寄存器中读取到的版本号大于了我们代码中给的5版本号导致的。我们第一个解决方案是将大于5改成大于8,给一更大的版本号。

@2:其中还有一个事情,就是三星的uboot中,代码中,初始化打印的是mmc通道0的,也就inand,我们如果将这个设备号改成了1,可能就会给外部的SD卡发送读取到SD卡的版本号,inand的版本比SD卡的版本高,虽然两者很类似,所以改了这个通道,可能也会解决问题,就是在初始化mmc设备时的传递的参数。


(11)修改输出到控制台的串口号 ,从三星默认的串口2,修改到串口0,

@1:只需要改动,smdkv210single.h中的关于串口的那一个宏就行。串口初始化的代码是在lowlevel_init.S中,跟标准输入输出绑定的是在seriver.c中。总宏定义决定初始化哪个串口的宏是在smdkv110.h中


(12)修改网络的配置信息,也是在smdkv210single.h中的关于网络配置的宏中修改就行。


(13)在我们uboot刚开始运行的时候,如果你用的mmc设备是0,用的是板子上的inand的话,你的环境变量刚开始用的是uboot内部自带的环境变量的值,但是当你改过了以后你在saveenv后,如果你选择的mmc设备是0的话,那么就会保存到你mmc设备0通道对应的设备中,我们的板子对应的是inand,所以就保存到了inand中了,并不是保存到了你的mmc设备通道1对应的那个sd卡通道2,我们的sd卡,

(14)所以如果我们要破坏inand中的那一份环境变量的值,而想用uboot源码中自带的环境变量的值的话,就需要先破坏掉inand中被从DDR中的环境变量分区保存到了inand中环境变量分区的那一份环境变量,破坏方法就在用mmc writer 0 30000000 11# 32 因为我的环境变量保存时,是放在了第17个扇区,分区大小是32个扇区。意思就是将内存中0x30000000中的开始的环境变量分区到整个环境变量分区的大小,全部写成0,完了之后保存到了mmc设备通道0对应的设备中。所以这个时候,mmc设备中对应的环境变量分区的值就是不对了,将来在校验的时候,就会发现这个设备中没有环境变量可以用,所以用的时候就会用uboot源码中自带的环境变量的值了。



(15)网卡驱动的移植1

@1:srom是sram/rom,是一个统称,SOC内部的srom controller控制器就是SOC对外提供的一种总线式连接sram/rom的一种接口,如果我们的SOC要外部连接一个sram或这rom存储芯片,或者一些伪装成srom接口的芯片(如网卡芯片,DM9000),就需要用到SOC的这个srom controller来连接进行外部扩展。总线式访问的好处就是可以直接用地址的方式来进行访问,不需要通过什么发命令啊什么的,时序好什么的去访问。当网卡芯片通过srom接口接在了soc上的时候,我们的主机soc去访问网卡芯片内部的寄存器时,就可以直接通过总线来用寻址的方式来直接放问网卡芯片。我们的板子上,网卡芯片是接在soc的srom中的一个bank上。

@2:网卡芯片内部有很多个寄存器,既然网卡芯片和我们的soc是通过srom接口进行链接的,我们就可以总线式的寻址去访问网卡芯片,由于网卡芯片内部的寄存器相对于网卡来说,是从0开始编址的,所以我们的soc要想通过地址去访问到网卡芯片内部的寄存器的时候,就要用一个相对地址去访问网卡芯片,就是起始地址+网卡芯片本身寄存器的地址。

起始地址指的就是网卡芯片接在soc的srom的bank上的那个bank对应的地址。也就是用soc访问网卡芯片内部寄存器的时候,要用网卡芯片接在srom bank上的那个基地址加上一个网卡芯片内部地址的。相当于用基地址加偏移量的方式去访问,很好理解。

@3:主机soc要想上网,就要对网卡芯片内部寄存器进行操作和网卡芯片内部的缓冲区(可以理解为内存)来进行上网,所以主机soc是通过网卡芯片来实现间接上网的。

@4:所以,如果连上了网以后,如果主机要通过网络来接受数据的话,网卡芯片硬件会自动的将从网络来的数据放到自己内部的缓冲区中,我们的主机soc只要去这个网卡芯片内部的缓冲区中读取数据就可以了,如果我们的主机soc想通过网路来发送数据的话,就只需要将我们想要发送的数据丢到网卡芯片内部的缓冲区中,就行,网卡芯片硬件也会自动从自己的缓冲区中把数据通过网络发送出去。

@5:通过看我们开发板的原理图,可以知道,我们网卡芯片有16根数据线和我们的soc相连接了,所以说明我们的soc的srom控制器用的16bit接口模式的。

@6:网线有8根线,但是有用的只有四根线,其他四根线是跟抗干扰有管的,这四根有用的线中,两根发,两根收。因为网线中传输的差分信号。差分信号传输的距离相对较远,抗干扰能力也较强

@7:网卡芯片有一个CS引脚:chip selcte,片选信号,意思就是主机向CS发送有效信号,则我们的从机芯片工作,主机向CS发送无效信号,则从机芯片不工作。这个引脚要接到我们soc中的srom bank中的片选信号。我们的每一个srom bank中都有一个片选信号端CSn,从原理图中可以看出来,我们DM9000的片选信号端接在soc中的srom bank1上,因为是cs1,所以我们DM9000相对我们主机soc的总线基地址就是我们主机soc中的sromc bank1的基地址(0x88000000)。

@8:DM9000的CMD引脚接到了soc的addr2引脚上,这个引脚也很重要。DM9000为了减少芯片的引脚数,数据线和地址线是复用的。DATA0-DATA15这16根线是有时做数据线传输数据的,有时做地址线传输地址的,当DM9000的CMD引脚的接受到高电平的时候,代表这时复用的是数据线,当CMD为低电平的时候传输的是地址,在DM9000中叫index,索引的意思,也就是相对于主机的地址的索引地址。这是查DM9000的数据手册时知道的。

@9:这些引脚上面的电平变化都是我们soc中的sromc控制器做的,我们只需要在配置寄存器的值时,充分考虑到硬件电路的接法,给我们相应的寄存器配置正确的值就行。



(15)网卡驱动的移植2

@1:uboot程序中本身就有很多网卡芯片驱动的程序,在uboot/drivers/net文件夹下,有很多个关于不同网卡芯片的驱动程序,大多数都是来自于Linux内核,我们网卡芯片是DM9000,所以我们应该看这个net文件夹下的dm9000.c和dm9000.h

,这两个文件我们目前就不用看了,因为会越看越糊涂的,因为还没有开始学习驱动,对驱动,对Linux内核对网络驱动这块的框架不是很熟悉。

@2:我们可以不用看这个网卡驱动DM9000的代码,因为驱动是做好的,数据和代码是分离开的,这里只是驱动代码,数据是由我们开发板中的接法决定的,数据由一定的数据结构提供,所以驱动具有可移植性,所以这里的代码我们我可以不用动,我们要动的是数据,数据就在smdkc210single.h中关于网卡配置的那些宏

@3:网卡移植的关键:初始化。在uboot的第二阶段,start_armboot中那个函数指针数组中,里面就有一个board_init,这个函数指针指向的那个函数中,就有网卡的初始化,这个初始化才是网卡移植的关键,这个初始化只要把网卡芯片初始化好了,网卡芯片就可以工作(意思是网卡驱动dm9000x.c和dm9000x.h依赖于这里的初始化而工作。)

@4:dm9000_pre_init这个函数就是移植网卡芯片的关键。这个初始化函数和我们开发板上的DM9000硬件连接有关,必须要结合我们开发板的原理图来分析,然后了决定这个函数怎么编程,所以我们要根据自己的开发板的硬件接法去修改这个初始化函数,来让我们的网卡芯片工作

@5:DM9000_16BIT_DATA这个宏用来表示DM9000工作在16位模式下,我们的开发板上的DM9000也是工作在16位模式下的

@6:SROM_BW_REG,从三星的源码中和对应数据手册,可以看出三星将网卡芯片DM9000接在了SOC中的sromc中的bank5上,而我们的开发板DM9000网卡芯片是接在SOC中的srom中的bank1上的,所以根据手册我们要操作这个寄存的bit4-bit7,这里四个bit位表示的是bank1的。

@7:我们是工作在16位模式的,所以这个SROM_BW_REG寄存中的bit4是1,因为我们数据线是一一对齐的,所以bit5是1,其他两位,按照模式来的话,按照别人的经验配置成1,非必须情况可以不用弄清楚这两个位。

@8:所以根据数据手册和实际情况,我们应该修改的寄存有三个SROM_BC5_REG SROM_BW_REG MP01CON_REG,最后一个是在GPIO中。

@8:基地址的配置:修改完上面那个初始化函数后,因为驱动分为两个部分:代码和数据,代码不用动,所以我们还要修改一些数据,在配置头文件中,关于网卡的那些宏。

CONFIG_DM9000_BASE 是DM9000网卡通过srom bank 映射到SOC的地址空间的地址,因为我们用的是srom中的bank1 所以根据数据手册中的内存图,可以知道,我们的基地址应该是0X88000000。

#define DM9000_IO (CONFIG_DM9000_BASE) 这个表示访问我们网卡芯片IO的基地址,寻找芯片内部寄存器等的时候。

#define DM9000_DATA (CONFIG_DM9000_BASE+4) 还有这个宏,我们要改成4,这个宏是来决定我们当前发送的是数据的,当我们要发送数据的时候,由原理图知道,我们的CMD引脚接在了ADDR2,也就第二根地址线上,4的就100,所以就是让第二根地址线保持高电平,这样就表示复用发送数据。

@9:改完这些,网卡实际上不可以直接工作的,还要修改CONFIG_DM9000_BASE 将这个地址的0X88000000改成0X88000300,为什么改成这个呢,猜想可能是因为网卡芯片由于版本的问题,自身有了一个偏移量,在以前的时候,可以用这个0X88000000地址,也就是这个srom bank的地址直接就能找到DM9000本身内部的那些寄存器的起始地址,但是可能由于版本问题,现在DM9000本身的寄存器的地址是从300H开始的。


@10:内核启动不起来,将串口改到串口2,因为三星提供的Linux内核用的是串口2,看配置头文件中有没有这两个宏,

#define CONFIG_SETUP_MEMORY_TAGS

#define CONFIG_CMDLINE_TAG

这两个宏,确保传参的
















网卡 地址 芯片 配置 代码 数据 文件 时候 问题 开发 三星 移植 函数 寄存器 就是 模式 环境 驱动 主机 信息 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州紫鲸互联网科技有限公司 科技互联网龙头 互联网电商科技 互联网和科技创新 科技互联网政务服务 金融科技创新监管互联网金融 互联网科技与金融科技 金融科技 互联网金融 狮子座互联网科技培训 互联网巨头投资的硬核科技 北京大学互联网科技怎么样 千方科技属于互联网企业吗 哈尔滨屹滨互联网科技有限公司 中和天地互联网科技有限公司 元气玛特互联网科技公司是外包吗 互联网金融科技公司的优势 宇信科技在杭州互联网排第几 广州有谷有贝互联网科技有限公司 科技互联网经济论坛 互联网大会出现的黑科技 瑰夏咖啡 百单网互联网科技有限公司怎么样 中国互联网科技工作委员会毛军 平安科技 互联网 凡科互联网科技 北京互联网络科技有限公司 互联网经济与金融科技 互联网保险科技创业 怎样加入科技互联网 科技互联网专业工作会议发言稿
0