uboot移植过程

uboot移植过程

 

1.修改Makefile

首先给要建立的S3C2410开发板取名为TE2410, 移植uboot时以smdk2410为模板,

修改Makefile

#tar xvjf u-boot-1.1.3.tar.bz2

#cd u-boot-1.1.3

#vi Makefile

scb9328_config    :   unconfig

    @./mkconfig $(@:_config=) arm arm920t scb9328 NULL imx

smdk2400_config   :   unconfig

    @./mkconfig $(@:_config=) arm arm920t smdk2400 NULL s3c24x0

smdk2410_config   :   unconfig

    @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

SX1_config :      unconfig

    @./mkconfig $(@:_config=) arm arm925t sx1

te2410_config :   unconfig

    @./mkconfig $(@:_config=) arm arm920t te2410 NULL s3c24x0

蓝色字体是添加的内容。其中,te2410_config   :   unconfig意思是为TE2410建立一个编译项,@./mkconfig $(@:_config=) arm arm920t te2410 NULL s3c24x0中的

arm表示CPU的架构是基于ARM体系结构的;arm920t表示CPU类型是arm920t;te2410是开发板的型号;NULL表示开发商或经销商的名称为空;s3c24x0表示是基于s3c24x0的片上系统。

 

 

2.ubootboard目录下建立te2410开发板子目录

#cp –fr board/smdk2410  /board/te2410

#cd board/te2410

#mv smdk2410.c  te2410.c

还要修改board/te2410/Makefile文件,

OBJS   := smdk2410.o flash.o --------à OBJS  := te2410.o flash.o

 

 

3.在include/configs目录下建立te2410.h头文件

#cd include/configs

#cp –fr smdk2410.h  te2410.h

 

4.指定交叉编译器的路径

选择支持softfloatpoint的交叉编译,etc/bashrc文件中添加一行

export PATH=/home/newdisk/toolchain/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin:$PATH

其中,/home/newdisk/toolchain/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin是交叉编译器路径

修改Makefile中的交叉编译器

ifeq ($(ARCH),arm)

CROSS_COMPILE = arm-softfloat-linux-gnu-

Endif

 

5.测试编译

#cd u-boot-1.1.3

#make te2410_config

#make

如果编译正确,将会在u-boot-1.1.3目录下生成u-boot、u-boot.bin、u-boot.srec 三个文件,其中u-boot是ELF格式二进制的image文件,u-boot.bin是原始的二进制image文件,u-boot.srec是Motorola S-Record格式的image文件。接下来的工作就是根据开发板的硬件配置来修改。

 

6.修改start.S文件

首先在  ldr pc, _start_armboot一行之前添加如下代码,将程序从Flash复制到DRAM中运行

 

#ifdef CONFIG_S3C2410_NAND_BOOT

    bl  copy_myself

 

    @jump to ram

    ldr r1, =on_the_ram

    add pc, r1, #0

    nop

    nop

      1:b  1b  @infinite loop

on_the_ram:

 

#endif

然后在_start_armboot: .word start_armboot一行之后添加下面内容

#ifdef CONFIG_S3C2410_NAND_BOOT

copy_myself:

    mov r10, lr

 

    @reset NAND

    mov r1, #NAND_CTL_BASE

    ldr r2, =0xF830       @initial value

    str r2, [r1, #oNFCONF]

    ldr r2, [r1, #oNFCONF]

    bic r2, r2, #0x800       @enable chip

    str r2, [r1, #oNFCONF]

    mov r2, #0xFF     @reset command

    strb   r2, [r1, #oNFCMD]

   

        mov r3, #0        @wait

      1:add r3, r3, #0x1

        cmp r3, #0xa

        blt 1b

      2:ldr r2, [r1,#oNFSTAT] @wait ready

         tst r2, #0x01

         beq 2b

         ldr r2, [r1, #oNFCONF]

         orr r2, r2, #0x800       @disable chip

         str r2, [r1, #oNFCONF]

 

         @get ready to call C functions(for nand_read())

         ldr sp, DW_STACK_START   @setup stack pointer

         mov fp, #0        @no previous frame,so fp=0

 

         @copy uboot to ram

         ldr r0, =UBOOT_RAM_BASE

         mov r1, #0

         mov r2, #0x30000

         bl  nand_read_ll

         tst r0, #0x0

         beq ok_nand_read

    #ifdef CONFIG_DEBUG_LL

    bad_nand_read:

 

    ldr r0, STR_FAIL

    ldr r1, SerBase

    bl  PrintWord

      1:b   1b     @infinite loop

    #endif

 

ok_nand_read:

    #ifdef CONFIG_DEBUG_LL  

    ldr r0, STR_OK

    ldr r1, SerBase

    bl  PrintWord

    #endif

 

    @verify

    mov r0, #0

    ldr r1, =UBOOT_RAM_BASE

    mov r2, #0x400

    go_next:

    ldr r3, [r0], #4

    ldr r4, [r1], #4

    teq r3, r4

    bne notmatch

    subs   r2, r2, #4

    beq done_nand_read

    bne go_next

 

notmatch:

    #ifdef CONFIG_DEBUG_LL  

    ldr r0, STR_FAIL

    ldr r1, SerBase

    bl  PrintWord

    #endif

  1:    b   1b

 

done_nand_read:

    #ifdef CONFIG_DEBUG_LL  

    ldr r0, STR_OK

    ldr r1, SerBase

    bl  PrintWord

    #endif

 

    mov pc, r10

   

@ clear memory

@ r0:start address

@ r1:length

mem_clear:

    mov    r2, #0

    mov r3, r2

    mov r4, r2

    mov r5, r2

    mov r6, r2

    mov r7, r2

    mov r8, r2

    mov r9, r2

  clear_loop:

    stmia  r0!,{r2-r9}

    subs   r1, r1, #(8*4)

    bne clear_loop

    mov pc, lr

 

 

#endif /*CONFIG_S3C2410_NAND_BOOT*/

start.S文件最后添加下面几行的内容,用于定义栈地址变量

#ifdef CONFIG_S3C2410_NAND_BOOT

    .align 2

    DW_STACK_START:

    .word  STACK_BASE+STACK_SIZE-4

#endif

 

7.添加nand_read.cnandflash.h源文件

start.S中调用了nand_read_ll函数,该函数用于NAND Flash读操作,在board/te2410目录下新建nand_read.c源文件,文件内容如下:

 

#include<config.h>

 

 

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

 

#define NF_BASE      0x4e000000

#define NFCONF       __REGi(NF_BASE+0x0)

#define NFCMD         __REGb(NF_BASE+0x4)

#define NFADDR       __REGb(NF_BASE+0x8)

#define NFDATA       __REGb(NF_BASE+0xc)

#define NFSTAT       __REGb(NF_BASE+0x10)

 

 

#define    BUSY   1

 

inline void wait_idle(void)

{

    int i;

    while(!(NFSTAT & BUSY))

       for(i=0;i<10;i++);

}

 

#define    NAND_SECTOR_SIZE  512

#define    NAND_BLOCK_MASK      (NAND_SECTOR_SIZE-1)

 

/*low level nand read function*/

 

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

{

    int i,j;

    if ((start_addr & NAND_BLOCK_MASK)||(size & NAND_BLOCK_MASK))

    {

       return -1; /*invalid alignment*/

    }

 

    /*chip enable*/

    NFCONF &= ~0x800;

    for(i=0; i<10; i++);

 

    for(i=start_addr; i<(start_addr+size);)

    {

       /*Read0*/

       NFCMD = 0;

 

       /*Write Address*/

       NFADDR = i& 0xFF;

       NFADDR = (i>>9) & 0xFF;

       NFADDR = (i>>17) & 0xFF;

       NFADDR = (i>>25) & 0xFF;

 

       wait_idle();

 

       for(j=0; j<NAND_SECTOR_SIZE; j++, i++)

       {

           *buf = (NFDATA & 0xFF);

           buf++;

       }

    }

    /*chip disable*/

    NFCONF |= 0x800;

    return 0;

 

}

修改board/te2410目录下的Makefile文件  

OBJS   := te2410.o flash.o  改为  OBJS  := te2410.o flash.o nand_read.o

board/te2410目录下添加nandflash.h文件,该文件主要定义了NAND Flash的一些芯片配置函数,代码如下:

 

 

#include<s3c2410.h>

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

 

typedef enum

{

    NFCE_LOW,

    NFCE_HIGH

}NFCE_STATE;

 

static inline void NF_Conf(u16 conf )

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCONF = conf;

}

 

static inline void NF_Cmd(u8 cmd)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCMD = cmd;

}

 

static inline void NF_CmdW(u8 cmd)

{

    NF_Cmd(cmd);

    udelay(1);

}

 

static inline void NF_Addr(u8 addr)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFADDR = addr;

}

 

static inline void NF_SetCE(NFCE_STATE s)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    switch(s)

    {

       case NFCE_LOW:

           nand->NFCONF &= ~(1<<11);

           break;

       case NFCE_HIGH:

           nand->NFCONF |= (1<<11);

           break;

    }

}

 

static inline void NF_WaitRB(void)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    while( !(nand->NFSTAT & (1<<0)) );

}

 

static inline void NF_Write(u8 data)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFDATA = data;

}

 

static inline u8 NF_Read(void)

{

    S3C2410_NAND *const nand = S3C2410_GetBase_NAND();

    return (nand->NFDATA);

}

 

static inline void NF_Init_ECC(void)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCONF |= (1<<12);

}

static inline u32 NF_Read_ECC(void)

{

    S3C2410_NAND *const nand = S3C2410_GetBase_NAND();

    return (nand->NFECC);

}

#endif

 

 

8.修改te2410文件

修改这个文件的目的有两个,一是初始化CPU相关的寄存器来支持USB主从设备,二是初始化NAND Flash设备。添加代码如下:

#include "nandflash.h"

 

int board_init(void)

{

...

    /*support usb function*/

    gpio->MISCCR |= (1<<3);

    gpio->MISCCR &= ~((1<<12)|(1<<13));

...

}

/*添加以下代码实现NAND Flash的初始化*/

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

extern ulong nand_probe(ulong physadr);

static inline void NF_Reset(void)

{

    int i;

    NF_SetCE(NFCE_LOW);

    NF_Cmd(0xFF); /*reset command*/

    for(i = 0; i < 10; i++);

    NF_WaitRB();

    NF_SetCE(NFCE_HIGH);

}

 

static inline void NF_Init(void)

{

#if 0

#define    TACLS  0

#define    TWRPH0 3

#define    TWRPH1 0

#else

#define    TACLS  0

#define    TWRPH0 4

#define    TWRPH1 2

 

#endif

 

 

    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));

    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));

}

 

void nand_init(void)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    NF_Init();

#if DEBUG

    printf("NAND flash probing at 0x%.8lX/n",(ulong)nand);

#endif

 

    printf("%ld MB/n",nand_probe((ulong)nand)>>20);

 

}

#endif

9.修改头文件te2410.h

修改include/configs/te2410.h文件,其中定义了栈的基地址和栈的大小、RAM的基地址以及NAND Flash设置参数等内容。

...

#define    CONFIG_CMDLINE_TAG   1

#define    CONFIG_SETUP_MEMORY_TAGS 1

#define    CONFIG_INITRD_TAG 1

...

#define CONFIG_COMMANDS /

           (CONFIG_CMD_DFL   | /

           CFG_CMD_CACHE | /

           CFG_CMD_ENV       | /

           CFG_CMD_PING     | /

           CFG_CMD_NAND  | /

           /*CFG_CMD_EEPROM |*/ /

           /*CFG_CMD_I2C |*/ /

           /*CFG_CMD_USB |*/ /

           CFG_CMD_REGINFO  | /

           CFG_CMD_DATE  | /

           CFG_CMD_ELF)

...

/*Nandflash Boot*/

#define    CONFIG_S3C2410_NAND_BOOT 1

#define    STACK_BASE    0x33FF8000

#define    STACK_SIZE    0x8000

#define    UBOOT_RAM_BASE    0x33F80000

/*Nandflash Controller*/

#define    NAND_CTL_BASE 0x4e000000

#define bINT_CTL(Nb) __REG(INT_CTL_BASE+(Nb))

/*Offset*/

#define    oNFCONF    0x00

#define    oNFCMD     0x04

#define    oNFADDR    0x08

#define    oNFDATA    0x0c

#define    oNFSTAT    0x10

#define    oNFECC     0x14

/*定义Nandflash设置参数*/

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

#define CFG_MAX_NAND_DEVICE 1  /*Max number of NAND devices*/

#define SECTORSIZE       512

 

#define ADDR_COLUMN      1

#define ADDR_PAGE        2

#define ADDR_COLUMN_PAGE    3

 

#define    NAND_ChipID_UNKNOWN      0x00

#define NAND_MAX_FLOORS         1

#define NAND_MAX_CHIPS          1

#define NAND_WAIT_READY(nand)   NF_WaitRB()

 

#define NAND_DISABLE_CE(nand)   NF_SetCE(NFCE_HIGH)

#define NAND_ENABLE_CE(nand)    NF_SetCE(NFCE_LOW)

#define WRITE_NAND_COMMAND(d,adr)  NF_Cmd(d)

#define WRITE_NAND_COMMANDW(d,adr) NF_CmdW(d)

#define WRITE_NAND_ADDRESS(d,adr)  NF_Addr(d)

#define WRITE_NAND(d,adr)   NF_Write(d)

#define READ_NAND(adr)   NF_Read()

 

#define NAND_CTL_CLRALE(nandptr)

#define NAND_CTL_SETALE(nandptr)

#define NAND_CTL_CLRCLE(nandptr)

#define NAND_CTL_SETCLE(nandptr)

 

#define CONFIG_MTD_NAND_VERIFY_WRITE   1

#define CONFIG_MTD_NAND_ECC_JFFS2      1

#define CONFIG_DEBUG_LL                 1

 

#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND)*/

 

修改以下各宏的值,内存相关地址、启动提示字母和网络的设置

#define CFG_MEMTEST_END     0x33F00000 /* 63 MB in DRAM  */

#define CFG_LOAD_ADDR       0x30008000 /*default load address*/

#define PHYS_SDRAM_1_SIZE   0x04000000 /*64 MB*/

#define CFG_PROMPT          ”TE2410”

#define CONFIG_IPADDR       192.168.1.10

#define CONFIG_SERVERIP     192.168.1.104

#define CFG_ENV_IS_IN_NAND  1

#define CFG_ENV_OFFSET        0x30000

#define UBOOT_RAM_BASE       0x33F80000

10.修改cmd_nand.c文件

添加包含nandflash.h的头文件   #include <nandflash.h>

nandflash.h复制到u-boot-1.1.3/include目录下

11.重新编译

以上参考<<ARM嵌入式Linux系统开发从入门到精通>>

编译中遇到一些问题,需要注意的是要选择支持软件浮点的交叉编译器,因为uboot使用软件浮点,我使用的arm-linux-gcc3.4.1不支持软件浮点,后来自己构建一个支持软件浮点的交叉编译器。

修改u-boot-1.1.3/cpu/arm920t/config.mk

PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 /

    -malignment-traps -msoft-float

改为

PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 /

    -mshort-load-bytes -msoft-float

板子已经有下载好的vivi,将uboot直接下载到RAM中运行,所以修改start.S和上面的修改说明不同,只需将start.S中的bl   lowlevel_init注释掉,其他不需要改动。

 

关于ubootbootmgo命令,bootmuImage对应,gozImage对应。uImagezImage添加64字节头信息得来,由这个头信息构成的结构体如下(IH_NMLEN=32)

typedef struct image_header {

    uint32_t   ih_magic;  /* Image Header Magic Number    */

    uint32_t   ih_hcrc;   /* Image Header CRC Checksum    */

    uint32_t   ih_time;   /* Image Creation Timestamp */

    uint32_t   ih_size;   /* Image Data Size       */

    uint32_t   ih_load;   /* Data    Load  Address    */

    uint32_t   ih_ep;     /* Entry Point Address      */

    uint32_t   ih_dcrc;   /* Image Data CRC Checksum  */

    uint8_t       ih_os;     /* Operating System      */

    uint8_t       ih_arch;   /* CPU architecture      */

    uint8_t        ih_type;   /* Image Type        */

    uint8_t       ih_comp;   /* Compression Type      */

    uint8_t       ih_name[IH_NMLEN];   /* Image Name     */

} image_header_t;

uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作uImage

mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么

mkimage -A arm -O Linux -T kernel -C none -a 0x30008000 -e 0x30008040 -n Linux-2.6.14 -d zImage uImage

-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)

你可能感兴趣的:(uboot移植过程)