-
2009-06-07
[Blackfin笔记]移植U-Boot - [Blackfin]
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://tigerwang202.blogbus.com/logs/40631275.html
Bootloader就是启动加载程序的意思,uClinux启动离不开引导程序。Bootloader是在操作系统运行之前执行的一段自举程序。通过这段小程序,用以初始化硬件设备、改变处理器运行模式、重组中断向量表和建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。
U-Boot全称Das U-Boot-universal bootloader,是由DENX SoftwareEngineering的Wolfgang Denk维护一种通用的Bootloader。U-Boot被认为是功能最多、最具弹性以及开发最积极的开放源码bootloader,可以方便地移植到各种硬件平台上。
Blackfin uClinux网站上提供了U-Boot在Blackfin上的移植。(http://blackfin.uclinux.org/gf/project/u-boot/)。笔者从其网站上下载了u-boot-1.1.6-2008R1.5.tar.bz2的源码,并将其复制到/home/uclinux/bootldr目录,使用TAR命令将其解压到u-boot-1.1.6-2008R1.5文件夹(下文简称u-boot-1.1.6)。
在开始移植前请参考Blackfin Linux Docs章节的bootloader部分。该手册介绍的针对Blackfin移植的一般步骤。为了对硬件底层寄存器进行设置,还需要参考Blackfin的Hardware Reference Manual(可在ADI公司网站下载,笔者下载的是3.4版本,下文引用页码以这个版本为准)。针对特定版本的U-Boot,Readme文档也许是最好的参考资料,它位于u-boot源码文件夹下。U-Boot的官方网站也提供非常详尽的文档资料(http://www.denx.de/wiki/U-Boot/Documentation)。
U-Boot代码一般分为stage1和stage2两大部分、stage1依赖于CPU体系结构如设备初始化代码,常用汇编语言编写已达到短小精悍,提高系统运行效率的目的。它主要包括在u-boot-1.1.6/cpu/blackfin文件夹中的Start.s和Start1.s文件。Stage1的入口函数从Start.s开始,通常开始包含以下步骤:
(1) 基本硬件初始化,为随后执行kernel准备好基本的硬件环境。包括:屏蔽所有中断,引导装载程序的执行过程中不必执行任何中断,中断屏蔽可通过写cpu的终端屏蔽寄存器或状态寄存器实现;设置CPU速度和时钟频率,初始化pll;RAM初始化,初始化内存控制器的各个寄存器;初始化UART,向串口打印U-Boot的字符信息;关闭cpu内部指令,数据cache。
(2) 为加载U-Boot的stage2准备RAM空间,通常stage2置于整个RAM空间的最顶层1MB空间。
(3) 拷贝U-Boot的stage2到RAM。判断是否是FLASH运行,如果是就将stage2的代码拷贝至TEXT BASE处。将stage2安排到RAM空间的最顶层1MB是推荐的方法。
(4) 设置堆栈指针sp,为C语言代码执行做好准备。
(5) 跳转至cpu_init_f(在cpu.c文件中)的C语言代码入口点。
此阶段的程序流程图如下:
“在start.s的最后,CPU初始化已经完成,需要进入第二阶段的执行。它会将_cpu_init_f函数指针写入到INT15的向量表中,然后用raise 15进入下一阶段的运行,这是因为CPU复位之后处于RESET中断的状态,这是优先级很高的一个中断,在这种情况下,虽然可以对CPU进行完全的操作(Supervisor mode),但是却无法响应其它的中断请求。因此start.s将自身跳到中断15再运行,这样同时可以响应其它的中断,CPU也仍然处在Supervisor mode,可以进行完整的控制。”
Stage2主要包括lib-Blackfin/board.c 和cpu.c中cpu_init_f、board_init_f函数以及common/main.c中的main_loop函数。按照初始化顺序如下:
(1) 初始化中断、串口、RTC、定时器等
(2) 初始化Flash。
(3) 初始化用以动态分配heap的内存
(4) 初始化SPI、NAND FLASH。
(5) 初始化MAC Address、IP Address
(6) 设备初始化。
(7) 进入 mainloop() 函数循环。
主要设备初始化完成后,需要启动控制台,即命令行模式。由mainloop()函数解析输入命令、执行命令、输出信息。在默认情况下,mainloop()会等待bootcmd环境变量说设定的自动运行的命令(比如setenv bootcmd bootm 0x2000 0000),引导flash特定地址中的嵌入式操作系统。
移植过程中需要修改或创建下列文件或目录。
顶层Makefile、MAKEALL 和 MAINTAINERS 文件
目标板配置文件:include/config/mybf532.h
目标板目录:boards/mybf532/
1.顶层编译文件
Makefile
在顶层Makefile中添加你的板子,找到Blackfin设置,一般在设置文件结尾,仿照原有设置添加你的目标板设置,笔者将自己的目标板称作mybf532,设置如下:
mybf532_config : unconfig
@$(MKCONFIG) $(@:_config=) blackfin bf533 mybf532
2.电路板设置文件
将当前目录定位至U-Boot源码文件夹下的include/configs目录
cd include/configs
将bf533-stamp.h设置文件作为模板,复制一份为mybf532.h(文件名与你板的名称相同)
cp bf533-stamp.h mybf532.h
修改mybf532.h中设置。
将其中的_CONFIG_BF533_STAMP_H_改成_CONFIG_MYBF532_H_。
添加宏定义#define CONFIG_MYBF532 1
根据你板上时钟频率修改CONFIG_CLKIN_HZ,笔者板上使用27MHz有源晶振,设置如下:
#define CONFIG_CLKIN_HZ 27000000
设置PLL倍频因子,CCLK_DIV系统时钟分频因子、SCLK_DIV总线分频因子。笔者设置如下:
#define CONFIG_VCO_MULT 12
/* CONFIG_CCLK_DIV controls what the core clock divider is */
/* Values can be 1, 2, 4, or 8 ONLY */
#define CONFIG_CCLK_DIV 1
/* CONFIG_SCLK_DIV controls what the peripheral clock divider is */
/* Values can range from 1-15 */
#define CONFIG_SCLK_DIV 7
对应的PLL频率27MHz*12 = 324MHz, 内核频率324/1 = 324MHz, 外部总线频率324/7 = 46MHz
进行网络设置:网卡IP地址、子网掩码、网关IP、服务器IP(SERVERIP即你主机的IP地址)、目标板HOSTNAME、ROOTPATH
#define CONFIG_IPADDR 10.21.11.67
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_GATEWAYIP 10.21.11.254
#define CONFIG_SERVERIP 10.21.11.65
#define CONFIG_HOSTNAME HHBF532
#define CONFIG_ROOTPATH /bf1/rootfs
以上是笔者的设置。
由于BF1有两块网卡而笔者开发板只有一块,将#define CONFIG_NET_MULTI的值改为 0(即只有一块网卡)。
SDRAM设置:SIZE(SDRAM的大小MBYTE为单位)、ADD_WITH(地址线宽度)、CFG_MENTSET_START(存储器测试开始地址)、CFG_MEMTEST_END(存储器测试结束地址)、CFG_LOAD_ADDR(缺省内核加载地址)、CGF_SDRAM_BASE(SDRAM起始地址)、CFG_MAX_RAM_SIZE(SDRAM最高地址)。笔者设置如下:
#define CONFIG_MEM_SIZE 32
#define CONFIG_MEM_ADD_WDTH 9
#define CONFIG_MEM_MT48LC16M16A2TG_7E 1
#define CFG_MEMTEST_START 0x00000000
#define CFG_MEMTEST_END 0x01EFFFFF
#define CFG_LOAD_ADDR 0x01000000
#define CFG_SDRAM_BASE 0x00000000
#define CFG_MAX_RAM_SIZE 0x02000000
修改监视程序提示符:CFG_PROMPT
修改网卡物理地址使其与你的板子相符:
#define CONFIG_DM9000_BASE 0x20300000
修改网卡IO、DATA(状态控制寄存器)地址:
#define DM9000_IO CONFIG_DM9000_BASE
#define CONFIG_DM9000_IO 0x20300000
#define DM9000_DATA (CONFIG_DM9000_BASE+4)、
修改FLASH的基地址,为了从NOR FLASH引导,该地址必须从0x2000 0000开始(也就是NOR FLASH从Bank0开始编址)。
#define CFG_FLASH_BASE 0x20000000
修改FLASH的Sector(扇区),参见相关FLASH的datasheet。
#define CFG_MAX_FLASH_SECT 35
设置环境变量(U-Boot中的ENV变量)在FLASH中存放地址,必须以一个Sector的起始地址开始:
#define CFG_ENV_ADDR 0x201f0000
设置环境变量大小及存放环境变量的Sector空间大小:
#define CFG_ENV_SIZE 0x10000
#define CFG_ENV_SECT_SIZE 0x10000
设置软件I2C管脚,根据你的目标板而定:
#define PF_SCL PF9
#define PF_SDA PF8
3.电路板设置目录
将当前目录切换至U-boot源代码目录下board子目录,拷贝bf533-stamp目录为mybf532。将mybf532中以bf533-stamp.c开始的文件改名为mybf532。
修改mybf532.c文件。将包含头文件#include “bf1.h”该成include “mybf532.h”。
修改相应printf()函数输出信息。
移植DM9000A驱动程序,移植BF537 NAND驱动。
设置工作结束,依次执行
make clean
make mybf532_config
make
命令完成编译。如果编译不出错,会在u-boot源码目录下生成上面提到的7个以u-boot开头的文件。如果错误根据提示,根据提示作相应修改,知道编译通过为止。
将编译生成的U-Boot文件烧写至NOR FLASH芯片,复位开发板,如果一设置切正确,U-Boot将被引导,如图21所示:
点击下载本文pdf版本(TBD)
收藏到:Del.icio.us








