u-boot-2010.03的移植

时间:2021-07-19 16:36:31
u-boot-2010.03的移植

【实验目的】

了解U-boot-2010.03的代码结构及移植方法。

【实验环境】

1、 Ubuntu 10.10发行版

2、 u-boot-2010.03

3、 FS2410平台

4、 交叉编译器arm-none-linux-gnueabi-gcc

【实验步骤】

说明:后面实验中的命令行提示符是($)则为主机命令(主机上执行)

1、 建立自己的平台

1、 下载源码

我们可以在下面这个网站上下载最新的和以前任一版本的uboot

ftp://ftp.denx.de/pub/u-boot/

我们这里使用的是u-boot-2010.03.tar.bz2

2、 解压uboot源码

$ tar jxvf u-boot-2010.03.tar.bz2

3、 进入到uboot源码

$ cd u-boot-2010.03

4、 添加FS2410平台信息

我们关心的班级相关内容文件或目录

u-boot-2010.03/Makefile

u-boot-2010.03/cpu/arm920t/start.S

u-boot-2010.03/board/Samsung/smdk2410

u-boot-2010.03/lib_arm

u-boot-2010.03/include/configs/smdk2410.h


smdk2410是s3c2410的标准板,我们在smdk2410的基础上做FS2410的移植

$ cd board/samsung/

$ cp smdk2410 fs2410 –a

$ cd fs2410

$ mv smdk2410.c fs2410.c

$ vim Makefile

修改

COBJS := smdk2410.o flash.o

COBJS := fs2410.o flash.o

$ cd include/configs

$ cp smdk2410.h fs2410.h

修改u-boot顶层目录下的Makefile,按照smdk2410的内容添加fs2410的内容

$ vim Makefile

smdk2410_config : unconfig

@$(MKCONFIG)  $(@:_config=) arm arm920t smdk2410 samsung s3c24x0

下添加:

fs2410_config : unconfig

@$(MKCONFIG)  $(@:_config=) arm arm920t fs2410 samsung s3c24x0

修改编译器

ifeq ($(HOSTARCH, $(ARCH))

CROSS_COMPILE ?=

endif

下添加:

ifeq (arm, $(ARCH))

CROSS_COMPILE ?= arm-none-linux-gnueabi-

endif

5、 编译u-boot-2010.03

$ make distclean

$ make fs2410_config

$ make

这个时候我们就可以得到一个u-boot.bin也就是我们的目标文件,但是这个文件通常情况下是不能够正常工作的,我们还需要对u-boot源代码进行进一步的修改。

2、 针对我们的FS2410平台进行进一步的修改

1、 u-boot源码中的中断屏蔽位

s3c2410中有11个子中断屏蔽位代码里只有10

修改cpu/arm920t/start.S

修改

# if defined(CONFIG_S3C2410)

ldr        r1, =0x3ff

ldr        r0, =INTSUBMSK

str        r1, [r0]

# endif

为:

# if defined(CONFIG_S3C2410)

ldr        r1, =0x7ff

ldr        r0, =INTSUBMSK

str        r1, [r0]

# endif

2、 修改配置文件include/configs/fs2410.h

1) 命令行提示符的修改:

#define    CONFIG_SYS_PROMPT        "SMDK2410 # "

改成:

#define    CONFIG_SYS_PROMPT        "fs2410 # "

2) 网络参数设置

修改

#define CONFIG_ETHADDR         08:00:3e:26:0a:5b 

#define CONFIG_NETMASK     255.255.255.0

#define CONFIG_IPADDR         10.0.0.110

#define CONFIG_SERVERIP         10.0.0.1

#define CONFIG_ETHADDR         11:22:33:44:55:66

#define CONFIG_NETMASK     255.255.255.0

#define CONFIG_IPADDR         192.168.7.222

#define CONFIG_SERVERIP         192.168.7.223

3) 内核加载地址的修改

修改

#define  CONFIG_SYS_LOAD_ADDR         0x33000000

改成:

#define  CONFIG_SYS_LOAD_ADDR         0x30008000

4) Nand功能添加

对照include/config_cmd_default.hinclude/config_cmd_all.h添加我们需要的相应功能。

Nand的功能的添加

#define CONFIG_CMD_NAND                /* NAND support*/

#if defined(CONFIG_CMD_NAND)

#define CONFIG_SYS_MAX_NAND_DEVICE  1

#define CONFIG_SYS_NAND_BASE  0x4E000000

#define CONFIG_NAND_S3C2410

#define STACK_BASE  0x33f00000

#define STACK_SIZE  0x8000

/* Nand Flash */

#define CONFIG_MTD_NAND_VERIFY_WRITE 1

#endif

5) 同时支持nand启动和nor启动

#if defined(CONFIG_S3C2410)

#define CONFIG_S3C2410_NAND_BOOT  1 //nand 启动

#define CONFIG_S3C2410_NOR_BOOT  1 //nor 启动

#endif

6) 环境变量保存位置

添加:

#ifdef  CONFIG_S3C2410_NOR_BOOT

#define    CONFIG_ENV_IS_IN_FLASH  1 /*common/env_flash.c */

#define CONFIG_ENV_ADDR  (CONFIG_SYS_FLASH_BASE + 0x30000)

#endif

#ifdef  CONFIG_S3C2410_NAND_BOOT

#define    CONFIG_ENV_IS_IN_NAND    1 /* common/env_nand.c */

#define  CONFIG_ENV_SIZE 0x10000

#define CONFIG_ENV_OFFSET  0x30000

#define NAND_CTL_BASE 0x4E000000

/* Offset */

#define oNFCONF  0x00

#define oNFCMD  0x04

#define oNFADDR  0x08

#define oNFDATA  0x0c

#define oNFSTAT  0x10

#define oNFECC  0x14

#endif

7) USB功能的添加

#define CONFIG_CMD_FAT                /* FAT support*/

#define CONFIG_CMD_USB                /* USB support*/

#if defined(CONFIG_CMD_USB)

#define CONFIG_DOS_PARTITION

#define CONFIG_USB_OHCI

#define CONFIG_USB_STORAGE

#define CONFIG_SUPPORT_VFAT

#define LITTLEENDIAN

#endif

Ping命令的添加

#define CONFIG_CMD_PING                /* ping support*/

8) Nor flash(sst39vf1601)Norflash相关内容的

注释掉

#define CONFIG_AMD_LV400        1        /* uncomment this if you have a LV400 flash */

添加

#define CONFIG_SST_39VF1601 1

添加

#ifdef CONFIG_SST_39VF1601

#define PHYS_FLASH_SIZE                0x00200000 /* 2M*/

#define CONFIG_SYS_MAX_FLASH_SECT        (512)        /* max number of sectors on one chip */

#endif

3、 添加Nand启动功能(修改cpu/arm920t/start.S)

u-boot默认情况下是nar启动,这里我们添加nand启动的内容:

1) 添加头文件

#include 

#include 

2) 添加nand启动标志位

/*add for env_nand.c*/

.extern  pbootflag

@pbootflag:                //1:NOR flash, 0:NAND flash

3) 添加BWSCON寄存器的定义(加粗字体为添加内容)

# if defined(CONFIG_S3C2400)

#  define pWTCON                0x15300000

#  define INTMSK                0x14400008        /* Interupt-Controller base addresses */

#  define CLKDIVN        0x14800014        /* clock divisor register */

#else

#  define pWTCON                0x53000000

#  define INTMSK                0x4A000008        /* Interupt-Controller base addresses */

#  define INTSUBMSK        0x4A00001C

#  define CLKDIVN        0x4C000014        /* clock divisor register */

#  define BWSCON        0x48000000

# endif

4)  添加启动模式判断Nor启动还是nand启动(加粗字体为添加内容)

/*czm add 2010-8-18*/

ldr r0,=BWSCON

ldr r0,[r0]

ands r0,r0,#6

beq nand_boot

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:                                /* relocate U-Boot to RAM            */

adr        r0, _start                /* r0 <- current position of code   */

ldr        r1, _TEXT_BASE                /* test if we run from flash or RAM */

cmp     r0, r1                  /* don't reloc during debug         */

beq     stack_setup

copy_loop:

ldmia        r0!, {r3-r10}                /* copy from source address [r0]    */

stmia        r1!, {r3-r10}                /* copy to   target address [r1]    */

cmp        r0, r2                        /* until source end addreee [r2]    */

ble        copy_loop

#endif        /* CONFIG_SKIP_RELOCATE_UBOOT */

#endif

/* add 2010-08-18 */

bl stack_setup

5)  添加NAND启动自搬移代码(在上一步代码下添加)

nand_boot:

#ifdef CONFIG_S3C2410_NAND_BOOT 

@ 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

nand1: 

  add r3, r3, #0x1

  cmp r3, #0xa

  blt nand1

nand2:

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

  tst r2, #0x1

  beq nand2

  ldr r2, [r1, #oNFCONF]

  orr r2, r2, #0x800 @ disable chip

  str r2, [r1, #oNFCONF]

@ get read 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 U-Boot to RAM

  ldr r0, =TEXT_BASE

  mov r1, #0x0

  mov r2, #0x30000

  bl nand_read_ll

  tst r0, #0x0

  beq ok_nand_read

bad_nand_read:

loop2: b loop2 @ infinite loop

ok_nand_read:

ldr  r0, =pbootflag

mov r1, #0x0

str  r1, [r0]

@ verify

  mov r0, #0

  ldr r1, =TEXT_BASE

  mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes

go_next:

  ldr r3, [r0], #4

  ldr r4, [r1], #4

  teq r3, r4

  bne notmatch

  subs r2, r2, #4

  beq stack_setup

  bne go_next

notmatch:

loop3: b loop3 @ infinite loop

#endif @ CONFIG_S3C2410_NAND_BOOT 

在_start_armboot: .word start_armboot下添加如下代码:

.align 2

DW_STACK_START: .word STACK_BASE + STACK_SIZE - 4

4、 添加nand_read.cnand启动做支持

board/samsung/fs2410下添加文件nand_read.c并在这个文件中添加如下内容:

#include 

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

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

#define NF_BASE 0x4e000000

# if defined(CONFIG_S3C2410) 

#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

#define NAND_SECTOR_SIZE 512

#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE – 1)

inline void wait_idle(void) {

    int i;

    while(!(NFSTAT & BUSY))

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

}

/* 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; /* chip disable */

    return 0;

}

# endif

并修改board/Samsung/fs2410/ Makefile

修改

COBJS        := fs2410.o flash.o

为:

COBJS        := fs2410.o flash.o nand_read.o

5、 修改board/samsung/fs2410/flash.c支持sst19lv1601 nor flash芯片

修改

#define MAIN_SECT_SIZE 0x10000   /*64KB*/

为:

#define MAIN_SECT_SIZE 0x1000   /*4KB for sst39lv1601*/

修改

#define CMD_UNLOCK_BYPASS        0x00000020

#define CMD_UNLOCK_BYPASS        0x000000A0

修改

#define MEM_FLASH_ADDR1                (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))

#define MEM_FLASH_ADDR2                (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))

#define MEM_FLASH_ADDR1                (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00005555 << 1)))

#define MEM_FLASH_ADDR2                (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00002AAA << 1)))

#elif defined(CONFIG_AMD_LV800)

                         (AMD_MANUFACT & FLASH_VENDMASK) |

                         (AMD_ID_LV800B & FLASH_TYPEMASK);

下添加

#elif defined(CONFIG_SST_39VF1601)

                        (SST_MANUFACT & FLASH_VENDMASK) |

                        (SST_ID_xF1601 & FLASH_TYPEMASK);

修改

for (j = 0; j < flash_info[i].sector_count; j++) {

        if (j <= 3) {

                /* 1st one is 16 KB */

                if (j == 0) {

                        flash_info[i].start[j] = flashbase + 0;

                        }

                                /* 2nd and 3rd are both 8 KB */

                        if ((j == 1) || (j == 2)) {

                                flash_info[i].start[j] =

                               flashbase + 0x4000 + (j -1) * 0x2000;

                        }

                                /* 4th 32 KB */

                        if (j == 3) {

                                flash_info[i].start[j] =

                                        flashbase + 0x8000;

                        }

                } else {

                        flash_info[i].start[j] =

                                flashbase + (j - 3)*MAIN_SECT_SIZE;

                        }

        }

替换为

for (j = 0; j < flash_info[i].sector_count; j++) {

        flash_info[i].start[j] =

                flashbase + j*MAIN_SECT_SIZE;

}

case (AMD_MANUFACT & FLASH_VENDMASK):

                 printf ("AMD: ");

                 break;

下添加

case (SST_MANUFACT & FLASH_VENDMASK):

                printf ("SST: ");

                break;

case (AMD_ID_LV800B & FLASH_TYPEMASK):

                printf ("1x Amd29LV800BB (8Mbit)\n");

                 break;

下添加

case ( SST_ID_xF1601 & FLASH_TYPEMASK):

                printf ("1x 39VF1601\n");

                break;

修改

if ((info->flash_id & FLASH_VENDMASK) !=

    (AMD_MANUFACT & FLASH_VENDMASK)) {

return ERR_UNKNOWN_FLASH_VENDOR;

}

if ((info->flash_id & FLASH_VENDMASK) !=

    (SST_MANUFACT & FLASH_VENDMASK)) {

return ERR_UNKNOWN_FLASH_VENDOR;

}

注释掉下面语句

if (!chip

  && (result & 0xFFFF) & BIT_PROGRAM_ERROR)

        chip = ERR;

   注释掉

*addr = CMD_PROGRAM;

6、 修改common/env_flash.c,为nor flash保存环境变量做准备

修改

char * env_name_spec = "Flash";

char * nor_env_name_spec = "Flash";

修改

env_t *env_ptr = (env_t *)(&environment[0]);

extern env_t *env_ptr = (env_t *)(&environment[0]);

修改

env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR;

extern env_t *env_ptr ;

添加

extern uchar env_get_char_spec (int index);

并注释掉下面语句

uchar env_get_char_spec (int index)

{

return ( *((uchar *)(gd->env_addr + index)) );

}

修改

int env_init(void)

int nor_env_init(void)

修改

int saveenv(void)

int nor_saveenv(void)

修改

void env_relocate_spec (void)

void nor_env_relocate_spec (void)

7、 修改common/env_nand.c添加nor flash环境变量烧写功能

添加

volatile int  pbootflag=1; //add by lht   1->nor  0->nand

extern int  nor_env_init(void);

修改int env_init(void)函数在函数开始添加如下内容:

 if(pbootflag==1) //by lht

{

                env_name_spec = "NOR";

                env_ptr=(env_t *)CONFIG_ENV_ADDR;

                return nor_env_init();

        }

修改int  saveenv(void)函数,在函数开始添加如下内容

 if(pbootflag==1) 

        {

                env_name_spec = "NOR";

                return nor_saveenv();

  }

修改void env_relocate_spec (void)函数,在函数开始添加如下内容

if(pbootflag==1) 

 {

         return nor_env_relocate_spec();

 }

8、 修改SDRAM刷新周期:board/samsung/fs2410/lowlevel_init.S

#define REFCNT  1113   /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */

改成:

#define REFCNT  1268   /* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */

9、 链接文件的修改

修改cpu/arm920t/u-boot.lds:

    在

cpu/arm920t/start.o (.text)

下添加

board/samsung/fs2410/lowlevel_init.o (.text)

board/samsung/fs2410/nand_read.o (.text)

10、 go命令的优化

修改该common/cmd_boot.c

int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

{

ulong        addr, rc;

int     rcode = 0;

/****add by farsight 2010-8-18**************************************/

char *commandline = getenv("bootargs");

struct param_struct *lht_params=(struct param_struct *)0x30000100;

printf("setup linux parameters at 0x30000100\n");

memset(lht_params,0,sizeof(struct param_struct));

lht_params->u1.s.page_size=4096;

lht_params->u1.s.nr_pages=0x4000000>>12;

memcpy(lht_params->commandline,commandline,strlen(commandline)+1);

printf("linux command line is: \"%s\"\n",commandline);

/***************************************************************/        

if (argc < 2) {

cmd_usage(cmdtp);

return 1;

addr = simple_strtoul(argv[1], NULL, 16); 

printf ("## Starting application at 0x%08lX ...\n", addr);

/*

 * pass address parameter as argv[0] (aka command name),

 * and all remaining args

 */

/*********************add by farsight 2010-8-18*********************/

__asm__(

"mov r1, #193\n"

"mov        ip, #0\n"

"mcr        p15, 0, ip, c13, c0, 0\n"        /* zero PID */

"mcr        p15, 0, ip, c7, c7, 0\n"        /* invalidate I,D caches */

"mcr        p15, 0, ip, c7, c10, 4\n"        /* drain write buffer */

"mcr        p15, 0, ip, c8, c7, 0\n"        /* invalidate I,D TLBs */

"mrc        p15, 0, ip, c1, c0, 0\n"        /* get control register */

"bic        ip, ip, #0x0001\n"                /* disable MMU */

"mov pc, %0\n"

"nop\n"

:

:"r"(addr)

);

/***************************************************************/

rc = do_go_exec ((void *)addr, argc - 1, argv + 1);

if (rc != 0) rcode = 1; 

printf ("## Application terminated, rc = 0x%lX\n", rc);

return rcode;

}

3、 重新编译

$ make distclean

$ make fs2410_config

$ make

这个时候我们就可以获得一个我们能够使用的u-boot了,不过此时只可以通过命令setenv bootcmd tftp 30800000 zImage \; go 30800000 通过前面go命令的优化传入环境变量引导内核挂载根文件系统。而bootm还没支持。待更新……

补充:上面所编译出来的uboot只支持加载zImage而不能加载uImage,因为给内核传递参数的时候被某些宏给屏蔽了,所以还须打开某些宏。

9>uboot给uImage内核传递参数修改:(include/configs/fs2410.h)

#define USE_920T_MMU
#undef CONFIG_USE_IRQ
在这两行下面添加:
#define CONFIG_CMDLINE_TAG 1
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
#define CONFIG_ETH_TAG 1