uboot03到友善之臂mini2440开发板.docx
- 文档编号:9833902
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:52
- 大小:60.39KB
uboot03到友善之臂mini2440开发板.docx
《uboot03到友善之臂mini2440开发板.docx》由会员分享,可在线阅读,更多相关《uboot03到友善之臂mini2440开发板.docx(52页珍藏版)》请在冰豆网上搜索。
uboot03到友善之臂mini2440开发板
移植u-boot-2009.03到友善之臂mini2440开发板(实验成功)
第一篇uboot在RAM中执行
Step1
网上介绍U-Boot移植的文章已经有很多了,但大多数文章都只讲了在哪个地方修改什么东西,但并未讲明白如何知道要修改这个值,如何是正确的移步骤。
那么作者根据自身移植经历,通过三篇文章告诉你一般的U-Boot移植过程,本文主要讲解了移植的基本思路、方法。
很多嵌入式系统开发的初学者都有过这样的经历,买了ARM开发板,了解了基础的Bootloader相关知识,也知道U-Boot在这方面的应用相当广泛,希望自己也能移植成功。
接下来就是下载源码,照着网上教程做,结果大部分都失败了,但又不甘心,于是再找教程,东拼西凑还是不行,试了几次就失去信心,做不下去了;即使做成功了,但也不知道别人怎么知道要改哪个文件、哪个数据,这么多文件人家是怎么找出来的,下次自己遇到款新的芯片能不能也移植成功。
根据教程移植失败,原因是多方面的:
教程里的开发板、U-Boot版本与自身的不一致,细微的差别(比如LED、串口的引脚分配等)都有可能导致失败,即使全都一样的情况下,大家的知识水平也不一样,有些Makefile的更改等,作者未加以说明导致编译出错。
下面根据我的经历写一下移植过程,根据本文不能保证你一定能移植成功,本文重点讲解的是移植过程中的思路、方法。
在大三的时候买过一个S3C44B0的开发板,大四的时候用过一段时间的S3C2410的实验箱,都曾尝试在这两个平台上移植U-Boot,均以失败告终;最近买了一块性价比较高的友善之臂mini2440开发板,移植成功了。
个人觉得做移植必需要有一定的前导知识:
开发环境的配制,你可以使用Windows平台下的Cygwin,可以在Windows下使用虚拟机安装Linux,可以直接安装一个LinuxPC作开发;相应的你需要了解GCC编译工具的使用,交叉编译环境的设置,了解Makefile相关内容;一定的文档阅读能力,包括各种帮助文件、Readme、MCU数据手册等;根据数据手册编写一定的硬件驱动,如果没有以上知识准备建议照着开发板的实验手册,把所有例程都跑一遍。
在移植的过程中主要参考了以下两篇文章,感谢作者分享。
由于只是为了学习基本的移植方法、流程,下文只进行了LED的相关驱动和串口输出设置以及其它一些必要的更改,至于NorFlash、NandFlash、网卡、USB的移植并未涉及。
开发环境的设置可以参考mini2440的用户手册,写得相当详细。
买回来的开发板已经安装好了Bootloader,官方使用的是Supervivi,在下面的过程中我们尽量不搞破坏,用最简洁的方式,完成学习目标:
在PC是编译好U-Boot,生成Bin文件,将开发板与PC通过串口和USB口相连,把生成的Bin文件通过USB口下载到开发板上RAM里,从RAM里直接运行,查看串口是否按要求输出信息。
解压U-Boot,把里面的README好好看一下,里面已经基本介绍了整个移植过程和配置文件的选项,基本的移植步骤都包括以下三个步骤:
1、在U-Boot源码Board中找一款与目标开发板配置相近的文件夹,在这里我们进入board/samsung目录,把smdk2410复制一份并命名为mini2440,进入mini2440目录,将里面的smdk2410.c改成mini2440.c,同时Makefile中也要作相应的更改。
2、进入include/configs目录,将smdk2410.h复制一份并命名为mini2440.h。
3、打开U-Boot根目录下的Makefile文件,搜索smdk2410,定位到smdk2410_config:
unconfig处,对照该格式在下面加两行:
1
2
mini2440_config:
unconfig
@$(MKCONFIG)$(@:
_config=)armarm920tmini2440samsungs3c24x0
注意在@$(MKCONFIG)前要加入一个TAB这是Makefile文件规则规定的,在第二行的第一个arm表示MCU平台(包括:
i386、ppc、mips、nios、m68k等);第二个arm920t表示arm内核版本(包括:
arm7tdmi、arm10、arm11等);第三个mini2440对应开发板所在文件夹board/samsung/mini2440;第四个samsung对应开发板所在文件夹上层目录board/samsung,如果mini2440目录就直接放在board目录下,那么此处应写NULL;第五个s3c24×0对应MCU型号。
完成了上面三步,可以执行以下命令进行编译:
1
2
#makemini2440_config
#make
如果成功编译出u-boot.bin,那么恭喜你,迈出了成功的第一步。
总结一下,移植U-Boot基本步骤有三:
1、在board目录下创建开发板对应目录;2、在include/configs下创建开发板对应配置文件;3、在U-Boot根目录下的Makefile中加入开发板对应编译命令。
Step2
在《移植u-boot-2009.03到友善之臂mini2440开发板step1》一文中已经介绍了,移植U-Boot的基本步骤,并且编译出了一个Bin文件,当然这个文件烧写到板子上是无任何反应的。
眼见为实,在step2中将通过编写一个LED驱动来指示U-Boot的运行情况,以及宏定义的更改。
阅读本文你需要有以下基础知识:
C语言宏定义的基本规则、运用;S3C24X0系列MCU的I/O配置、操作方法。
说明一下《移植u-boot-2009.03到友善之臂mini2440开发板stepX》系列文章只是提供一个移植U-Boot的基本思路和方法,要求记者有一定的C语言基础和嵌入式开发经验。
编辑include/configs/mini2440.h,把CONFIG_S3C2410改成CONFIG_S3C2440;把CONFIG_SMDK2410改成CONFIG_MINI2440。
U-Boot里有些驱动根据处理的型号的不同,配置的方法、参数各不相同,那么就是通过这个CONFIG_XXXXX来定义区分的。
由于S3C2410和S3C2440的寄存器地址和参数设置基本是相同的,所以只需在定义CONFIG_S3C2410的地方加上CONFIG_S3C2440即可,CONFIG_MINI2440同理;如果处理器差异较大,那么在具体地置你就要根据该处的功能需要编写相应的驱动代码。
方法如下:
在U-Boot根目录下用grep命令搜索所有包含CONFIG_S3C2410的文件,一般为#ifdefined(CONFIG_S3C2410)改成#ifdefined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)。
可以看到很多地方S3C2410和S3C2440都是引用同一头文件s3c2410.h的,详细修改位置大家可以查看我的Patch文件。
grep"CONFIG_S3C2410"*-R//查找包含"CONFIG_S3C2410"的文件,*表示查找当前目录下的所有文件,-R表示递归查找它的所有子目录.
grep"CONFIG_MINI2410"*-R
common/serial.c:
#elifdefined(CONFIG_S3C2410)
common/serial.c:
#ifdefined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/usb_ohci.c:
#elifdefined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/speed.c:
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)
cpu/arm920t/s3c24x0/speed.c:
#elifdefined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/speed.c:
#endif/*defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)*/
cpu/arm920t/s3c24x0/interrupts.c:
#elifdefined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/timer.c:
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)
cpu/arm920t/s3c24x0/timer.c:
#elifdefined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/timer.c:
#endif/*defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)*/
cpu/arm920t/s3c24x0/usb.c:
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/usb.c:
#elifdefined(CONFIG_S3C2410)
cpu/arm920t/s3c24x0/usb.c:
#endif/*defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)*/
cpu/arm920t/start.S:
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)
cpu/arm920t/start.S:
#ifdefined(CONFIG_S3C2410)
cpu/arm920t/start.S:
#endif/*CONFIG_S3C2400||CONFIG_S3C2410*/
drivers/mtd/nand/s3c2410_nand.c:
#ifdefCONFIG_S3C2410_NAND_HWECC
drivers/mtd/nand/s3c2410_nand.c:
#ifdefCONFIG_S3C2410_NAND_HWECC
drivers/mtd/nand/s3c2410_nand.c:
#ifdefCONFIG_S3C2410_NAND_BBT
drivers/i2c/s3c24x0_i2c.c:
#elifdefined(CONFIG_S3C2410)
drivers/i2c/s3c24x0_i2c.c:
#ifdefCONFIG_S3C2410
drivers/i2c/s3c24x0_i2c.c:
#ifdefCONFIG_S3C2410
drivers/i2c/s3c24x0_i2c.c:
#ifdefCONFIG_S3C2410
drivers/i2c/s3c24x0_i2c.c:
#ifdefCONFIG_S3C2410
drivers/i2c/s3c24x0_i2c.c:
#ifdefCONFIG_S3C2410
drivers/serial/serial_s3c24x0.c:
#elifdefined(CONFIG_S3C2410)
drivers/rtc/s3c24x0_rtc.c:
#elifdefined(CONFIG_S3C2410)
drivers/usb/host/ohci-hcd.c:
defined(CONFIG_S3C2410)||\
include/configs/smdk2410.h:
#defineCONFIG_S3C24101/*inaSAMSUNGS3C2410SoC*/
include/configs/mini2440.h:
#defineCONFIG_S3C24101/*inaSAMSUNGS3C2410SoC*/
include/configs/VCMA9.h:
#defineCONFIG_S3C24101/*inaSAMSUNGS3C2410SoC*/
include/configs/sbc2410x.h:
#defineCONFIG_S3C24101/*inaSAMSUNGS3C2410SoC*/
include/configs/mini2440.h~:
#defineCONFIG_S3C24101/*inaSAMSUNGS3C2410SoC*/
include/common.h:
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||\
include/s3c24x0.h:
#ifdefCONFIG_S3C2410
include/s3c24x0.h:
#ifdefCONFIG_S3C2410
include/s3c24x0.h:
#ifdefCONFIG_S3C2410
include/s3c24x0.h:
#ifdefCONFIG_S3C2410
include/s3c24x0.h:
#ifdefCONFIG_S3C2410
include/s3c24x0.h:
#ifdefCONFIG_S3C2410
include/serial.h:
#ifdefined(CONFIG_S3C2410)
include/autoconf.mk:
CONFIG_S3C2410=y
gedit+编辑路径
如
920geditcommon/serial.c
921geditcpu/arm920t/s3c24x0/usb_ohci.c
922geditcpu/arm920t/s3c24x0/speed.c
923geditcpu/arm920t/s3c24x0/interrupts.c
924geditcpu/arm920t/s3c24x0/speed.c
925geditcpu/arm920t/s3c24x0/timer.c
926geditcpu/arm920t/s3c24x0/usb.c
927geditcpu/arm920t/start.S
928geditdrivers/i2c/s3c24x0_i2c.c
929geditdrivers/serial/serial_s3c24x0.c
930geditdrivers/rtc/s3c24x0_rtc.c
931geditdrivers/usb/host/ohci-hcd.c
932geditinclude/configs/mini2440.h
933geditinclude/common.h
934geditinclude/s3c24x0.h
Patch文件是我将修改后的代码与原始文件进行diff比较生成的补丁文件,增加了什么内容,删除了什么内容大家可以根据前导符“+”或“-”区别。
Patch可以用文本编辑器打开,里面的内容耐心看一看,基本上都能看懂的;当然也可以直接用patch命令打补丁到U-Boot源码里。
经过以上宏定义的修改,编译基本上是可以通过,如果有什么Error或Warning可以根据提示进行修改,最终是可以编译生成Bin文件的,此时的Bin文件下载到开发板还是没有任何反应的,下面我们就将LED代码加进去。
编辑cpu/arm920t/start.S,这个是U-Boot文件中第一个运行的程序,汇编格式,如何知道程序是从该文件开始运行的,还有从该文件哪一段代码开始运行的呢。
一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等如何分配等,这个文件就存在于board/samsung/mini2440/u-boot.lds,打开文件看到以下代码:
1
2
3
4
5
6
7
8
9
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.=0x00000000;
.=ALIGN(4);
.............
}
第1行定义了生成文件的目标平台,第2行定义了程序的入口点_start,下面就是定义了段分配。
回到start.S文件,找到_start如下:
1
2
.globl_start
_start:
bstart_code
一个简单跳转,继续找到start_code,那么此处就是启动代码的正式开始处了,加入以下LED驱动代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#defineGPBCON0x56000010
#defineGPBDAT0x56000014
#defineGPBUP0x56000018
ldrr0,=GPBUP
ldrr1,=0x7FF
strr1,[r0]
ldrr0,=GPBCON
ldrr1,=0x154FF
strr1,[r0]
ldrr0,=GPBDAT
ldrr1,=0x1C0
strr1,[r0]
在以上向行代码分别定义了操作PB口的寄存器地址,关闭PB口上拉,设置PB5、6、7、8口为输出口(对应mini2440开发板上的4个LED),设PB5为低电平,PB6、7、8设为高电平,对应LED1高,其余不亮。
关于此处寄存的设置请参考S3C2440用户手册第九章IOPorts,汇编代码可以参考上下文的写法依葫芦画瓢。
一般的Bootloader都有以下两个功能:
上电首先初始化RAM;然后将自身复制到RAM中运行,提高运行速度。
以上两点我们可以从start.S文件中start_code往下的两个宏看到:
1
2
#ifndefCONFIG_SKIP_LOWLEVEL_INIT初始化RAM
#ifndefCONFIG_SKIP_RELOCATE_UBOOT复制到RAM中运行
在前一篇文章中提到,我们直接通过现在Bootloader将U-Boot.bin文件下载到内存中运行,RAM初始化的动作已经由Supervivi做了,这里我们不需要再次进行初始化,而且如果进行初始化也会导致试验失败,因此一定要将LOWLEVEL_INIT功能关掉,你可以在这里把blcpu_init_crit注释掉,也可以在include/configs/mini2440.h中增加一个宏定义:
#ifndefCONFIG_SKIP_LOWLEVEL_INIT
blcpu_init_crit
#endif
1
#defineCONFIG_SKIP_LOWLEVEL_INIT1
我是采用的前一种方法。
如果你想在其它的C语言源文件中控制LED可以加入以下代码:
1
2
3
4
5
6
7
#include
S3C24X0_GPIO*constgpio=S3C24X0_GetBase_GPIO();
gpio->GPBCON=0x00295551;
gpio->GPBUP=0x000007FF;
gpio->GPBDAT=0x00000180;
将第1行加在文件头部,将下面几行加在你想控制LED亮灭的地方,这段代码会使LED1、LED2变亮。
执行
makedistclean
makemini2440_config
make
至此,将编译出的u-boot.bin文件下载到内存0×0处运行可以看到开发板上LED根据我们的要求亮了起来。
(现象:
LED1灯亮,蜂鸣器不停地叫)
Step3
在前面两篇文章中,介绍了U-Boot的基本移植过程、LED驱动及宏定义的修改等,本文主要在此基础上导入串口输出的设置方法及系统运行频率的设置等。
在串口移植成功后大家可根据自身需要修改NandFlash、Net等其它驱动模块。
请同时关注以下两文章:
移植u-boot-2009.03到友善之臂mini2440开发板step1
移植u-boot-2009.03到友善之臂mini2440开发板step2
U-Boot提供了一个简单的功能菜单,有点像一个微型的Shell,它可以接收用户命令,执行相应的操作。
默认情况下,菜单是通过第一个串口输出到上位机进行显示的,当然你也可以把菜单输出到其它串口或USB口或显示屏上,后面几种情况要求比较高,不在本文讨论之列。
在经过了Step2后,按理说应该能从串口正常输出了啦,再次确认了串口初始化和相关操作设置,主要是查看了cpu/arm920t/s3c24×0/serial.c文件,因为S3C2440的串口设置与S3C2410完全一致不需要作任何更改啊,在经过了多次试验之后还是无法正常输出。
在仔细阅读了别人的移植文章,结全提供的Patch补丁文件,找出来可能是原因是系统时钟频率问题,能影响串口正常工作的也正是时钟频率问题。
S3C2410在12MHz外部时钟的情况下,默认运行主频是200MHz左右,而S3C2440在正常情况下是运行在400MHz左右,这也是2440区别于2410的一个重点方面,另外2440在工业参数方面优于2410并且多了一个摄像头接口中。
目标明确,对系统时钟进行手工初始化,让它明明白白地按照我们的要求去运行。
在U-Boot里系统的初始化有两部分,在start.S中有CPU的初始化,还有就是在切换到C语言函数下,也有一部分通过C语言来进行系统初始化的函数,分别进行修改。
在汇编文件中增加时钟初始化。
打开cpu/arm920tstart.S,找到初始化系统中继的位置(注意,此时禁用中断相关代码也要做一定修改,参考数据手册),在其下方加入以下代码:
#ifdefined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)
ldrr1,=0x7fff
ldrr0,=INTSUBMSK
strr1,[r0]
#endif
#defineMPLLCON0x4C000004
#defineUPLLCON0x4C000008
#ifdefined(CONFIG_S3C2440)
/*FCLK:
HCLK:
PCLK=1:
4:
8*/
/*defaultFCLKis12MHz!
*/
ldrr0,=CLKDIVN
movr1,#5
strr1,[r0]
/**************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- uboot03 友善 mini2440 开发