Chinaunix首页 | 论坛 | 博客
  • 博客访问: 682673
  • 博文数量: 183
  • 博客积分: 9166
  • 博客等级: 中将
  • 技术积分: 1920
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-31 16:17
文章分类

全部博文(183)

文章存档

2010年(159)

2009年(24)

分类: LINUX

2010-06-24 09:13:21

U-Boot移植



U-Boot移植过程记录

一些提示:
1.交叉编译环境要事先搭建好
2.解释一下一段代码
smdk2400_config : unconfig
   @$(MKCONFIG) $(@:_config=) arm arm920t smdk2400 NULL s3c24x0
       arm,就表示现在用的是 CPU 的架构是 arm 体系结构。
   arm920t,指明这是 cpu 的内核类型,它对应于 cpu/arm920t 目录。
   Smdk2410,这是开发板的型号,它的目录在 board/smdk2410 目录下。
   NULL,表示开发者或者经销商是谁(vender)
   S3c24x0,表示开发板上的 cpu 是啥。



正文:
1.删除用不到的目录
根目录下的lib_文件夹,保留lib_arm ,lib_generic即可
cpu/目录下的文件夹,保留你要移植的目标平台即可(我这里是arm920t)
board/目录下的文件夹,保留一个相似的板作模板(我这里是smdk2410)

2.修改最顶级的Makefile,添加自己的板子支持
a.按照2410的格式,自己新建一个:(这里命名为myboard,记住第二行之前一定是tab)
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

myboard_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t myboard NULL s3c24x0
b.创建自己的开发板主目录


1.进入board目录,用smdk2410做模板,复制一份命名为myboard
cd board
cp -fr smdk2410  myboard
2.更改Makefile文件
大约在28行
COBJS := smdk2410.o flash.o  更改为COBJS := myboard.o flash.o
[否则make的时候会出现.depend找不到libmyboard.a的错误]
3.更改文件名
mv board/myboard/smdk2410.c  board/myboard/myboard.c
mv include/configs/smdk2410.h include/configs/myboard.h
3.编译测试
1.make myboard_config
2.make
经过这两步,正常的话会在根目录下生成u-boot.bin文件,证明基础过程完成!

4.修改配置文件,使其符合自己的开发板。







一.U-BOOT板本为U-BOOT-1.1.6
二.新建开发板的目录
1.在board目录下将smdk2410复制为myboard目录
2.将board/myboard/smdk2410.c改名为myboard.c
3.将include/configs/smdk2410.h复制为myboard.h
4.修改顶层Makefile,添加:
myboard_config : unconfig
       @$(MKCONFIG) $(@:_config=) arm arm920t myboard NULL  s3c24x0
5.修改board/myboard/Makefile:
COBJS := smdk2410.o flash.o
改为:
COBJS := myboard.o flash.o
 
二.修改SDRAM的配置
 1.根据HCLK设置SDRAM的刷新参数,主要是REFCNT寄存器,修改board/myboard/lowlevel_init.S
#define REFCNT 1113 
改为
#define REFCNT 0x4f4    /*period=7.8125us , HCLK=100MHZ, (2048+1-7.8125*100)*/
 
三.修改board_init函数
1.修改board/myboard/myboard.c中的board_init函数,修改为:
#define S3C2440_MPLL_400MHZ   ((0x5c<<12) | (0x01<<4) | (0x01))
       #define S3C2440_UPLL_48MHZ    ((0x38<<12) | (0x02<<4) | (0x02))
       #define S3C2440_CLKDIV        0x05
 
       #define S3C2410_MPLL_220MHZ   ((0x5c<<12) | (0x04<<4) | (0x00))
       #define S3C2410_UPLL_48MHZ    ((0x28<<12) | (0x01<<4) | (0x02))
       #define S3C2410_CLKDIV        0x03
 
int board_init (void)
{
       S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
 
       /* set up the I/O ports */
       gpio->GPACON = 0x007FFFFF;
       gpio->GPBCON = 0x00044555;
       gpio->GPBUP = 0x000007FF;
       gpio->GPCCON = 0xAAAAAAAA;
       gpio->GPCUP = 0x0000FFFF;
       gpio->GPDCON = 0xAAAAAAAA;
       gpio->GPDUP = 0x0000FFFF;
       gpio->GPECON = 0xAAAAAAAA;
       gpio->GPEUP = 0x0000FFFF;
       gpio->GPFCON = 0x000055AA;
       gpio->GPFUP = 0x000000FF;
       gpio->GPGCON = 0xFF95FFBA;
       gpio->GPGUP = 0x0000FFFF;
       gpio->GPHCON = 0x002AFAAA;
       gpio->GPHUP = 0x000007FF;
 
       if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002) ) {
      
       } else {
              /* FCLK:HCLK:PCLK = 1:4:8 */
              clk_power->CLKDIVN = S3C2440_CLKDIV;
 
            __asm__(     "mrc p15,0,r1,c1,c0,0\n"
                          "orr r1,r1,#0xc0000000\n"
                          "mcr p15,0,r1,c1,c0,0\n"
                          :::"r1"
                       );
 
              /* to reduce PLL lock time, adjust the LOCKTIME register */
              clk_power->LOCKTIME = 0xFFFFFF;
 
              /* configure MPLL */
              clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
 
               /* some delay between MPLL and UPLL */
               delay (4000);
 
               /* configure UPLL */
               clk_power->UPLLCON = S3C2440_UPLL_48MHZ;
 
               /* some delay between MPLL and UPLL */
               delay (8000);
 
               /* arch number of SMDK2410-Board */
               gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;
       }
 
       /* adress of boot parameters */
       gd->bd->bi_boot_params = 0x30000100;
 
       icache_enable();
       dcache_enable();
 
       return 0;
}
 
四.在/include/s3c24x0.h中加入2440 的CAMDIVN定义:
typedef struct {

         S3C24X0_REG32   LOCKTIME;
         S3C24X0_REG32   MPLLCON;
         S3C24X0_REG32   UPLLCON;
         S3C24X0_REG32   CLKCON;
         S3C24X0_REG32   CLKSLOW;
         S3C24X0_REG32   CLKDIVN;
         S3C24X0_REG32   CAMDIVN;

} S3C24X0_CLOCK_POWER;
 
五.修改cpu/arm920t/s3c24x0/speed.c,首先要在程序的开头增加如下一行,才可以使用gd变量:
  DECLARE_GLOBAL_DATA_PTR;
 
#define S3C2440_CLKDIVN_PDIVN                  (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK             (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1                (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2                (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8              (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6              (3<<1)
#define S3C2440_CLKDIVN_UCLK                   (1<<3)
 
#define S3C2440_CAMDIVN_CAMCLK_MASK            (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL             (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF             (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF             (1<<9)
#define S3C2440_CAMDIVN_DVSEN                  (1<<12)
 
1.       修改get_PLLCLK()
DECLARE_GLOBAL_DATA_PTR;
static ulong get_PLLCLK(int pllreg)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    ulong r, m, p, s;
 
    if (pllreg == MPLL)
       r = clk_power->MPLLCON;
    else if (pllreg == UPLL)
       r = clk_power->UPLLCON;
    else
       hang();
 
    m = ((r & 0xFF000) >> 12) + 8;
    p = ((r & 0x003F0) >> 4) + 2;
    s = r & 0x3;
 
    if(gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {
        return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
    } else {
        return ((CONFIG_SYS_CLK_FREQ*m*2) / (p<
    }
}
 
2.       修改get_HCLK()
/* return HCLK frequency */
ulong get_HCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    unsigned long clkdiv;
    unsigned long camdiv;
    int hdiv = 1;
 
    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
        return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
    else {
        clkdiv = clk_power->CLKDIVN;
        camdiv = clk_power->CAMDIVN;
 
        switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
            case S3C2440_CLKDIVN_HDIVN_1:
                 hdiv = 1;
                 break;
            case S3C2440_CLKDIVN_HDIVN_2:
                 hdiv = 2;
                 break;
            case S3C2440_CLKDIVN_HDIVN_4_8:
                 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
                 break;
            case S3C2440_CLKDIVN_HDIVN_3_6:
                 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
                 break;
        }
 
        return get_FCLK() / hdiv;
    }
}
 
 
3.       修改get_PCLK()
/* return PCLK frequency */
ulong get_PCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    unsigned long clkdiv;
    unsigned long camdiv;
    int hdiv = 1;
 
    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
        return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
    else {
        clkdiv = clk_power->CLKDIVN;
        camdiv = clk_power->CAMDIVN;
 
        switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
            case S3C2440_CLKDIVN_HDIVN_1:
                 hdiv = 1;
                 break;
            case S3C2440_CLKDIVN_HDIVN_2:
                 hdiv = 2;
                 break;
            case S3C2440_CLKDIVN_HDIVN_4_8:
                 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
                 break;
            case S3C2440_CLKDIVN_HDIVN_3_6:
                 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
                 break;
        }
 
        return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
    }
}
 
六.选择 NOR FLASH 型号
1.修改include/configs/myboard.h 把型号改成开发板中的NOR flash型号 AM29LV800
#if 0
#define CONFIG_AMD_LV400    1     /* uncomment this if you have a LV400 flash */
#endif
#define CONFIG_AMD_LV800    1     /* uncomment this if you have a LV800 flash */
重新编译
 
七.配置include/configs/myboard.h中定义CS8900的各个默认地址,如IP,MAC等
#define CONFIG_ETHADDR        08:00:3e:26:0a:5b
#define CONFIG_NETMASK     255.255.255.0
#define CONFIG_IPADDR            192.168.1.8
#define CONFIG_SERVERIP         192.168.1.15
 
八.添加include/configs/myboard.h
#define CONFIG_SETUP_MEMORY_TAGS  1
#define CONFIG_CMD_LINE_TAG       1
#define CONFIG_BOOTDELAY       3
#define CONFIG_BOOTARGS      "noinitrd console=ttSAC0 root=/dev/mtdblock1 rootfstype=jffs2"
#define CONFIG_BOOTCOMMAND      "nboot 0x32000000 0 0; bootm 0x32000000"
 
九.添加PING命令
修改include/configs/myboard.h:
#define CONFIG_COMMANDS \
                  (CONFIG_CMD_DFL   | \
                  CFG_CMD_CACHE      | \
          CFG_CMD_PING     | \
                  CFG_CMD_REGINFO  | \
                  CFG_CMD_DATE  | \
                  CFG_CMD_ELF)
 
十.修改提示符
修改include/configs/myboard.h:
#define       CFG_PROMPT             "myboard> "    /* Monitor Command Prompt       */
 
十一.支持NAND FLASH
1.       修改配置文件include/configs/myboard.h的宏定义
 
#define CONFIG_COMMANDS \
                  (CONFIG_CMD_DFL   | \
                  CFG_CMD_CACHE      | \
          CFG_CMD_PING     | \
                  CFG_CMD_NAND       | \
                  /*CFG_CMD_EEPROM |*/ \
                  /*CFG_CMD_I2C  |*/ \
                  /*CFG_CMD_USB |*/ \
                  CFG_CMD_REGINFO  | \
                  CFG_CMD_DATE  | \
                  CFG_CMD_ELF)
 
2.       在include/configs/myboard.h中添加三个跟NAND 有关的宏定义
#define CFG_NAND_BASE           0
#define CFG_MAX_NAND_DEVICE     1
#define NAND_MAX_CHIPS          1
 
3.       在include/s3c24x0.h中添加S3C2440_NAND数据结构
/* NAND FLASH (see S3C2440 manual chapter 6) */
typedef struct {
    S3C24X0_REG32  NFCONF;
S3C24X0_REG32  NFCONT;
    S3C24X0_REG32  NFCMD;
    S3C24X0_REG32  NFADDR;
    S3C24X0_REG32  NFDATA;
    S3C24X0_REG32  NFMECCD0;
    S3C24X0_REG32  NFMECCD1;
    S3C24X0_REG32  NFSECCD;    
    S3C24X0_REG32  NFSTAT;
    S3C24X0_REG32  NFESTAT0;
    S3C24X0_REG32  NFESTAT1;
    S3C24X0_REG32  NFMECC0;
    S3C24X0_REG32  NFMECC1;
    S3C24X0_REG32  NFSECC;
    S3C24X0_REG32  NFSBLK;
    S3C24X0_REG32  NFEBLK;
} /*__attribute__((__packed__))*/ S3C2440_NAND;
 
4.       在include/s3c2410.h文件中仿照S3C2410_GetBase_NAND函数定义S3C2440_GetBase_NAND函数
static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)
{
    return (S3C2440_NAND * const)S3C2410_NAND_BASE;
}
 
5.新建cpu/arm920t/s3c24x0/nand_flash.c
#include
 
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include
#include
 
DECLARE_GLOBAL_DATA_PTR;
 
#define S3C2440_NFSTAT_READY    (1<<0)
#define S3C2440_NFCONT_nFCE     (1<<1)
 
static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)
{
    S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
 
    if(chip == -1) {
        s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE;
    } else {
        s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE;
    }
}
 
static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
    S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
    struct nand_chip *chip = mtd->priv;
 
    switch (cmd) {
        case NAND_CTL_SETNCE:
        case NAND_CTL_CLRNCE:
             printf("%s: called for NCE\n", __FUNCTION__);
             break;
        case NAND_CTL_SETCLE:
             chip->IO_ADDR_W = (void *) &s3c2440nand->NFCMD;
             break;
        case NAND_CTL_SETALE:
             chip->IO_ADDR_W = (void *) &s3c2440nand->NFADDR;
             break;
        default:
             chip->IO_ADDR_W = (void *) &s3c2440nand->NFDATA;
             break;
    }
}
 
static int s3c2440_nand_devready(struct mtd_info *mtd)
{
    S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
 
    return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);
}
 
static void s3c24x0_nand_inithw(void)
{
    S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
 
    #define TACLS   0
    #define TWRPH0  4
    #define TWRPH1  2
 
    s3c2440nand->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
    s3c2440nand->NFCONT = (1<<4) | (0<<1) | (1<<0);
}
 
void board_nand_init(struct nand_chip *chip)
{
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
 
    s3c24x0_nand_inithw();
 
    chip->IO_ADDR_R = (void *)&s3c2440nand->NFDATA;
    chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
    chip->hwcontrol = s3c2440_nand_hwcontrol;
    chip->dev_ready = s3c2440_nand_devready;
    chip->select_chip = s3c2440_nand_select_chip;
    chip->options = 0;
  
    chip->eccmode = NAND_ECC_SOFT;
}
 
#endif
 
6.修改cpu/arm920t/s3c24x0/Makefile:
COBJS       = i2c.o interrupts.o serial.o speed.o \
      usb_ohci.o nand_flash.o
 
十二.修改完,已经可以编译U-BOOT
   Make myboard_config
   Make all
   生成u-boot.bin,用HJTAG下载到板上运行
 
八.测试网络
1.把开发板连上网络
2.配置开发板的IP地址:
SMDK2410 # setenv ipaddr 192.168.6.239
SMDK2410 # setenv ethaddr 08:00:3e:26:0a:5b
SMDK2410 # setenv serverip 192.168.6.15
SMDK2410 # saveenv
3.打开电脑的tftp-server
tftp 0x30000000 u-boot.bin
4.       烧写U-BOOT
SMDK2410 #  protect off all
SMDK2410 #  erase all
SMDK2410 #  tftp 0x30000000 u-boot.bin
SMDK2410 #  cp.b 0x30000000 0x0 0x1ffff
SMDK2410 #  protect on all




阅读(2207) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~