现在的位置: 首页 > 综合 > 正文

在Visual DSP下移植u-boot

2013年09月14日 ⁄ 综合 ⁄ 共 3423字 ⁄ 字号 评论关闭

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

  

本文适用于

ADSP-BF561

Vistual DSP 5.0update 5

u-boot-1.1.6

  

欢迎转载,但请保留作者信息

 

1.     前言

Boot Loader(内核引导程序)是在操作系统内核运行之前运行的一段自举程序,用于初始化硬件设备、改变处理器运行模式、重组中断向量和建立内存空间映射图,从而将系统的软硬件带到一个合适的状态或者用户定制的特定状态,以便为最终加载操作系统内核准备好正确的环境。

目前嵌入式Linux系统常用的Boot Loaderarm-bootredbootU-Boot等。U-Boot是当前比较流行的遵循GPL条件的开放源码项目[1]U-Boot具有源码公开的特点,开发人员可根据自身需要进行裁减;支持多种处理器和嵌入式操作系统内核;具有多种设备驱动源码:支持种引导方式;具有功能强大且成熟、稳定等诸多优点,故在嵌入式系统开发过程中广泛采用。

ADSP-BF561 处理器是ADI Blackfin 系列中的高性能产品,针对于多媒体和通信方面的各种应用。该器件的核心由两枚独立的Blackfin 处理器组成。它集成了一套通用的数字图像处理外围设备,为数字图像处理和多媒体应用创建了一个完整的系统级片上解决方案[2]

目前,在BF561上使用u-boot的一般方法是使用GNU Toolchain将其编译成BF561的目标代码,然后下载到目标板上运行。而VisualDSP++ADI公司推出的开发DSP程序的IDE,其界面友好,提供了几乎所有现代IDE的功能。目前尚未有人在VDSP下编译u-boot的。一方面是由于编译器技术的差异,另一方面也由于没有这样的需求。但是假如它能够在VDSP下编译,那么也就意味着可以通过仿真器单步执行调试,对于引导技术的学习和研究将可达到事半功倍的效果!

在整个移植过程中,主要涉及汇编器,C编译器和链接器的差异处理,下面进行详细的描述。

2.     程序结构

当在GNU Toolchain下进行u-boot的开发时,它使用Makefile对编译流程进行控制,逐一进入u-boot的每个子目录进行编译。但是在Visual Dsp++IDE环境下,如果将整个u-boot的代码做为一个工程来创建,有一个比较难以处理的问题:在不同的目录下有一些重名的文件,这些重名的文件将产生相同名称的目标文件,因此Visual Dsp无法支持在一个工程中使用同名的源文件,哪怕它们是放在不同的目录下也不行。

为了解决这个问题,可以将为每个不同的目录创建不同的dlb文件,这是VDSP使用的库文件,但是每个不同的库文件生成的目标文件将放在不同的目录下,因而就可以解决重名的问题。

3.     汇编器的差异

gcc的汇编器和VDSP的汇编器语法大部分相同,只有少量的语法差异,如下表所示:

问题描述

VDSP的解决方法

u-boot中,经常使用

#if (CONFIG_COMMANDS & CFG_CMD_xxx)

这样的定义,其中CONFIG_COMMANDS这个常量是做为一个64位整数来对待的。

VDSP不支持在#if中使用64位整数进行运算,因此只能自定义一个宏,进行如下修改:

#ifdef CONFIG_CMD_xxx

在这里,如果需要使用xxx指定的功能,就在工程选项中定义这个宏,否则不定义。

u-boot中,经常使用

.macro serial_early_init

#ifdef CONFIG_DEBUG_EARLY_SERIAL

       call _serial_initialize;

#endif

.endm

这样的定义。

VDSP不支持.macro,只能用#define来近似模拟,但是#define中不能再使用#ifdef这样的条件编译,因此只能修改为:

#ifdef CONFIG_DEBUG_EARLY_SERIAL

       #define serial_early_init  /

                     call _serial_initialize;

#else

       #define serial_early_init 

#endif

GCC的汇编支持在一行中仅使用一个分号,而没有其它语句。

VDSP不支持,必须去除分号。

GCC在汇编函数的末尾要使用

.size name, .-name

VDSP不支持.size,直接使用

.name.end:

GCC的嵌入汇编中可以使用

%0=b%2(z);

类似这样的语句。

VDSP下一解释就变成了r0 = bp0r0p0的使用可能与实际值不同),应该修改为

%0 = b[%2] (z)

GCC的汇编中可以使用”m”作为指示符。

VDSP中不支持”m”,相应地改为”a”或者”p”

对于( R7 : 0, P5 : 0) = [ SP ++ ];  这样的语句,GCC并不限制在R7和冒号之间插入空格。

VDSP下必须写成:

( R7:0, P5:0) = [ SP ++ ];

R7:0之间不允许有任何空格。

当然,还有其它的一些差异,如jump 1f等,但是在u-boot的移植过程中没有的遇到,因此不做介绍。

4.     C编译器的差异

VDSPC编译器和GCCC编译器兼容性不错,绝大部分代码不需要修改即可运行,主要有以下几个地方的差异:

问题描述

VDSP的解决方法

u-boot/include/asm/posix_type.h中有这样一个定义:

typedef enum { false = 0, true = 1 } bool;

VDSP直接将bool做为一个内置的数据类型来处理,因而对于这个定义可以直接注释掉。

u-boot-1.1.6-2008R1/cpu/blackfin/traps.c中定义了一个数组:

const struct memory_map const bfin_memory_map[] = {

VDSP不支持使用两个const的修饰,因而只能改为:

const struct memory_map bfin_memory_map[] = {

u-boot中使用了一个宏:

#define DECLARE_GLOBAL_DATA_PTR     register gd_t * volatile gd asm ("P5")

使用这个宏可以声明一个叫gd的局部指针变量,而这个指针的值是存放在P5这个寄存器中的。U-boot使用这种方式来进行程序的优化。

VDSP中,不支持此定义,因此可以这样修改:

#define DECLARE_GLOBAL_DATA_PTR     extern gd_t * volatile gd

然后在board.c中添加一个定义:

gd_t * volatile gd;

这样修改的结果是将gd这个指针放在了SDRAM中,性能略有下降,但是还是可以接受的。

lib_blackfin/board.c中有一个函数:

void init_cplbtables(void)

{

         void icplb_add(uint32_t addr, uint32_t data)

         {

                   *(ICPLB_ADDR + i) = addr;

                   *(ICPLB_DATA + i) = data;

         }

}

在这里它将icplb_add函数直接放到了init_cplbtables函数里面。

这在VDSP中是不允许的,应该将此函数的实现提取到外面来。

对于在u-boot移植过程中未出现的编译器差异,在此不做介绍。

5.     链接器的差异

u-boot的链接文件为u-boot-1.1.6-2008R1/board/bf561-ezkit/u-boot.lds.s,在其中定义了各段的布局,而VDSP5则使用u-boot.ldf做为链接文件,下面就是对它的移植。当然,我们可以根据自己的需要随时进行调整,在此只是尽可能与原文件保持一致。

问题描述

VDSP的解决方法

u-boot.lds.s中有这样的内存区定义:

     ram     : ORIGIN = CFG_MONITOR_BASE, LENGTH = CFG_MONITOR_LEN

在这里CFG_MONITOR_BASECFG_MONITOR_LEN是预先定义好的两个常数。

不能在LDF中直接使用START (CFG_MONITOR_BASE)这样的语句,但由于u-boot<

抱歉!评论已关闭.