在《移植u-boot-2009.03到友善之臂mini2440开发板step1》一文中已经介绍了,移植U-Boot的基本步骤,并且编译出了一个Bin文件,当然这个文件烧写到板子上是无任何反应的。眼见为实,在step2中将通过编写一个LED驱动来指示U-Boot的运行情况,以及宏定义的更改。
请同时关注以下两文章:
移植u-boot-2009.03到友善之臂mini2440开发板step1
http://www.stars625.com/portinguboottomini2440step1.html移植u-boot-2009.03到友善之臂mini2440开发板step3
http://www.stars625.com/portinguboottomini2440step3.html阅读本文你需要有以下基础知识: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的文件,一般为#if defined (CONFIG_S3C2410)改成#if defined (CONFIG_S3C2410) || defined (CONFIG_S3C2440)。可以看到很多地方S3C2410和S3C2440都是引用同一头文件s3c2410.h的,详细修改位置大家可以查看我的Patch文件。
Patch文件是我将修改后的代码与原始文件进行diff比较生成的补丁文件,增加了什么内容,删除了什么内容大家可以根据前导符“+”或“-”区别。Patch可以用文本编辑器打开,里面的内容耐心看一看,基本上都能看懂的;当然也可以直接用patch命令打补丁到U-Boot源码里。
经过以上宏定义的修改,编译基本上是可以通过,如果有什么Error或Warning可以根据提示进行修改,最终是可以编译生成Bin文件的,此时的Bin文件下载到开发板还是没有任何反应的,下面我们就将LED代码加进去。
编辑cpu/arm920t/start.S,这个是U-Boot文件中第一个运行的程序,汇编格式,如何知道程序是从该文件开始运行的,还有从该文件哪一段代码开始运行的呢。一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等如何分配等,这个文件就存在于board/samsung/mini2440/u-boot.lds,打开文件看到以下代码:
复制代码- OUTPUT_ARCH(arm)
- ENTRY(_start)
- SECTIONS
- {
- . = 0x00000000;
-
- . = ALIGN(4);
- .............
- }
|
第1行定义了生成文件的目标平台,第2行定义了程序的内口点_start,下面就是定义了段分配。
回到start.S文件,找到_start如下:
复制代码- .globl _start
- _start: b start_code
|
一个简单跳转,继续找到start_code,那么此处就是启动代码的正式开始处了,加入以下LED驱动代码:
复制代码- #define GPBCON 0x56000010
- #define GPBDAT 0x56000014
- #define GPBUP 0x56000018
-
- ldr r0, =GPBUP
- ldr r1, =0x7FF
- str r1, [r0]
-
- ldr r0, =GPBCON
- ldr r1, =0x154FF
- str r1, [r0]
-
- ldr r0, =GPBDAT
- ldr r1, =0x1C0
- str r1, [r0]
|
在以上向行代码分别定义了操作PB口的寄存器地址,关闭PB口上拉,设置PB5、6、7、8口为输出口(对应mini2440开发板上的4个LED),设PB5为低电平,PB6、7、8设为高电平,对应LED1高,其余不亮。关于此处寄存的设置请参考S3C2440用户手册第九章IO Ports,汇编代码可以参考上下文的写法依葫芦画瓢。
一般的Bootloader都有以下两个功能:上电首先初始化RAM;然后将自身复制到RAM中运行,提高运行速度。以上两点我们可以从start.S文件中start_code往下的两个宏看到:
复制代码- #ifndef CONFIG_SKIP_LOWLEVEL_INIT
- #ifndef CONFIG_SKIP_RELOCATE_UBOOT
|
在前一篇文章中提到,我们直接通过现在Bootloader将U-Boot.bin文件下载到内存中运行,RAM初始化的动作已经由Supervivi做了,这里我们不需要再次进行初始化,而且如果进行初始化也会导致试验失败,因此一定要将LOWLEVEL_INIT功能关掉,你可以在这里把bl cpu_init_crit注释掉,也可以在include/configs/mini2440.h中增加一个宏定义:
复制代码- #define CONFIG_SKIP_LOWLEVEL_INIT 1
|
我是采用的后一种方法。
如果你想在其它的C语言源文件中控制LED可以加入以下代码:
复制代码- #include <s3c2410.h>
-
- S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
-
- gpio->GPBCON = 0x00295551;
- gpio->GPBUP = 0x000007FF;
- gpio->GPBDAT = 0x00000180;
|
将第1行加在文件头部,将下面几行加在你想控制LED亮灭的地方,这段代码会使LED1、LED2变亮。
至此,将编译出的u-boot.bin文件下载到内存0×0处运行可以看到开发板上LED根据我们的要求亮了起来。
下一篇我们将讨论,将U-Boot的调试信息从串口输出,关注《移植u-boot-2009.03到友善之臂mini2440开发板step3》。