Chinaunix首页 | 论坛 | 博客
  • 博客访问: 444478
  • 博文数量: 72
  • 博客积分: 3186
  • 博客等级: 中校
  • 技术积分: 1039
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-07 16:53
文章分类

全部博文(72)

文章存档

2012年(1)

2011年(5)

2010年(10)

2009年(56)

我的朋友

分类: 嵌入式

2009-12-21 00:29:32

这段时间一直在学习uboot,从阅读源代码到开始动手移植。这块an2410跟smdk2410几乎
一样,所以移植起来参照include/configs/下的smdk2410.h,不会太复杂。移植成功后
再回头看看原来的调试过程,才发现犯的错误都挺离谱的。今天重新解压了一份
开净的u-boot源代码移植到板子上,并将整个过程记录下来,以供备忘,也给正在
an2410上移植uboot的朋友做个参考。



下面仅记录移植步骤及改动的地方,关于代码细节可参考

目标板: an2410-ssb (阿南的板子)
移植重点: 从nand flash启动 k9f1208
          这块板子上没有nor flash
others: 网卡芯片 cs8900a
        sdram 64M 2块ks562632

uboot版本 : u-boot-1.3.4

移植步骤:

1. 在board下建立an2410文件夹,这里直接将board/smdk2410 复制为 board/an2410

2. 在顶层的Makefile里添加如下两行(可先搜索smdk2410,然后再其上添加)
        an2410_config:    unconfig
                @$(MKCONFIG) $(@:_config=) arm arm920t an2410 NULL s3c24x0
   同时搜索CROSS_COMPILE,并修改其下面arm对应相的交叉编译路径

3. 将include/configs/smkd2410.h 复制为 include/configs/an2410.h

4. 修改cpu/arm920t/start.S,这个文件是uboot代码的汇编部分,其中修改的有以下几
个部分

(1)

====上面是设置时钟分频比====
    /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
这里加上下面三句,主要目的是调试的时候用,在调试的时候,是把uboot直接加载到
sdram上去,所以就不需要设置sdram,这里的3句会检测是否是调试状态,若是则跳过
        adr     r0, _start /* 加载此时的启始地址到r0 */
        ldr     r1, _TEXT_BASE /* 加载默认的连接地址到r1 */
        cmp     r0, r1 /* 若r0与r1相等,则说明此时是在ram上,否则,是从
                        * nand上启动,需要重新设定sdram
                        */
    blne    cpu_init_crit
#endif

(2) 紧接着上面,这里要先设置芯片的时钟。在uboot里,原来设置cpu时钟是在
start_armboot里,即board_init里。这里提前设置时钟,cpu也会跑快些
由于设置时钟用的C函数,所以把堆栈的设置提前了
        /*
         * Setup the stack,下面调用C函数之前,先设置栈指针
         */
stack_setup:
    ldr    r0, _TEXT_BASE    /* upper 128 KiB: relocated uboot */
    sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area */
    sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
    sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub    sp, r0, #12    /* leave 3 words for abort-stack */

#ifndef CFG_SKIP_LOWLEVEL_INIT
        bl      clock_init /* 现在就设置时钟频率 */
#endif

(3) 设置nand ,由于下面马上就要从nand上copy代码了,所以这里先设置nand,代码参考
vivi中的head.S,这里加了一个预定义CFG_BOOT_FROM_NAND,所以在an2410.h中需要定义


#if CFG_BOOT_FROM_NAND
#define NAND_CTL_BASE 0x4e000000
#define oNFCONF 0x00
#define oNFCMD  0x04
#define oNFSTAT 0x10
        mov     r1, #NAND_CTL_BASE
        ldr     r2, =0xf830    @ configure nand flash
        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]
        tst     r2, #0x1      @ wait ready
        beq     2b
        ldr     r2, [r1, #oNFCONF]
        orr     r2, r2, #0x800  @ disable chip
        str     r2, [r1, #oNFCONF]
#endif

(3) 复制代码,nand_read_ll同样也是取自于vivi
其中需要有修改的地方,见patch
#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 */  /* 之前已经设置了栈指针 */
        beq     clear_bss

    ldr    r2, _armboot_start
    ldr    r3, _bss_start
    sub    r2, r3, r2    /* r2 <- size of armboot */
#if CFG_BOOT_FROM_NAND
        bl      nand_read_ll    /* 将u-boot从nand复制到ram */
#else
    add    r2, r0, r2    /* r2 <- source end address */


5. 修改 board/an2410/lowlevel_init.S

#define B3_BWSCON        (DW16 + UBLB) /* CS8900A*/

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

6. 添加board/an2410/nand_boot.c , 其中有两个函数 nand_read_ll, 这个是取自
vivi,用来复制代码;另一个是clock_init, 用来初始化cpu时钟
代码见patch

7. 修改 board/an2410/Makefile ,去掉flash.o ,添加nand_boot.o

#COBJS    := smdk2410.o flash.o
COBJS    := smdk2410.o nand_boot.o

8. 由于clock_init已经设置了时钟,所以在board/an2410/smdk2410.c中的
board_init函数里去掉时钟初始化相关部分

9. 修改an2410.h,其中有多处要修改的

增加下面几行
#define CONFIG_JFFS2_CMDLINE 1
#define CONFIG_JFFS2_NAND 1
#define MTDIDS_DEFAULT "nand0=nandflash0"
#define MTDPARTS_DEFAULT ""

/* 下面增加几个命令 */
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NAND
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_PING

#define CONFIG_BOOTDELAY    3
#define CONFIG_BOOTARGS    "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
#define CONFIG_ETHADDR    08:00:3e:26:0a:5b
#define CONFIG_NETMASK          255.255.255.0
#define CONFIG_IPADDR        192.68.0.10
#define CONFIG_SERVERIP        192.168.0.100

参数taglist
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_CMDLINE_TAG 1
#define CONFIG_BOOTCOMMAND    "nand read.jffs2 0x30007fc0 kernel; bootm 0x30007fc0"

去掉flash
#define CFG_NO_FLASH 1
//#define CONFIG_AMD_LV400    1    /* uncomment this if you have a LV400 flash */
#if 0
#define CONFIG_AMD_LV800    1    /* uncomment this if you have a LV800 flash */
#endif

环境变量都保存在nand里
//#define    CFG_ENV_IS_IN_FLASH    1
#define    CFG_ENV_IS_IN_NAND      1
#define CFG_ENV_SIZE    0x10000    /* Total Size of Environment Sector */
#define CFG_ENV_OFFSET  0x40000

#define CFG_NAND_BASE   0
#define CFG_MAX_NAND_DEVICE 1
#define CFG_MAX_NAND_CHIP 1
#define CFG_BOOT_FROM_NAND 1




主要的修改就是上面的了,uboot的可移植非常好,所以只要几步就可以移植到特定的开
方板上。启动信息如下(没有开debug, 没有内核)

U-Boot 1.3.4 (Dec 21 2009 - 00:08:13)

DRAM:  64 MB
NAND:  64 MiB
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0

NAND read: device 0 offset 0x60000, size 0x200000

Reading data from 0x25fe00 -- 100% complete.
 2097152 bytes read: OK
Wrong Image Format for bootm command
ERROR: can't get kernel image!
an2410 >

文件:patch.tar
大小:50KB
下载:下载& lt;/a>



文件:uboot.tar
大小:160KB
下载:下载


阅读(3056) | 评论(0) | 转发(0) |
0

上一篇:7. bootm命令

下一篇:vivi分析-顶层Makefile

给主人留下些什么吧!~~