• 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所示:

     

    clip_image002

    点击下载本文pdf版本(TBD)


    收藏到:Del.icio.us
    Tag: