移植uboot-1.1.6到勤研2440(和精智2440接近,仿照100ask24x0_config配置,重现韦东山的uboot-1.1.6_patch过程)

来源:互联网 发布:ps制作淘宝店铺首页 编辑:程序博客网 时间:2024/05/16 17:46
1)开发环境

1.开发板:勤研2440,

nor flash:没移植改变nor flash前,显示Amd29LV400BB 512K,但实际是:

Bank # 1: MXIC MX29LV160B FLASH (16 x 16)  Size: 2 MB in 35 Sectors
  AMD Standard command set, Manufacturer ID: 0xC2, Device ID: 0x2249
  Erase timeout: 30000 ms, write timeout: 100 ms

第0扇区大小为8K,第1、2为4K,第3为16K,后面31扇区为32K。前面4个扇区加起来刚好是主要扇区的大小 = 32K

Sector Start Addresses:
    00000000 (RO) 00002000 (RO) 00003000 (RO) 00004000 (RO) 00008000 (RO)
    00010000 (RO) 00018000      00020000      00028000      00030000
    00038000      00040000      00048000      00050000      00058000
    00060000      00068000      00070000      00078000      00080000 (RO,放参数)
    00088000 (RO) 00090000      00098000      000A0000      000A8000
    000B0000      000B8000      000C0000      000C8000      000D0000
    000D8000      000E0000      000E8000      000F0000      000F8000


2.软件环境:ubantu9.0(韦东山一期光盘)

3. linux版本:linux-2.6.22.6 (/work/system/linux-2.6.22.6)补丁:linux-2.6.22.6_jz2440.patch

4.u-boot:uboot-1.1.6  补丁:u-boot-1.1.6_jz2440.patch

 

5.自己的u-boot目录/work/system/u-boot-jimmy/u-boot-1.1.6

 

参考:http://blog.csdn.net/johnmcu/article/details/6561311

 2)具体步骤

A)解压U-BOOT-1.1.6,进入U-BOOT目录,修改Makefile

smdk2410_config :       unconfig
        @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

加上

myjz2440_config: unconfig
        @$(MKCONFIG) $(@:_config=) arm arm920t myjz2440  NULL s3c24x0

 

修改完Makefile后,在board目录下,新建自己的开发板目录myjz2440,把smdk2410目录下的所有文件拷到myjz2440,把smdk2410.c改为myjz2440.c。修改该目录下的Makefile,把smdk2410.o改为myjz2440.o

COBJS :=myjz2440.o flash.o

 

include/configs目录下创建板子的配置头文件,拷贝smdk2410.hmyjz2440.h

 

  测试能否编译成功:

  执行makemyjz2440_config

 

B).修改SDRAM配置,在board/myjz2440/lowlevel_init.S(内存控制器初始化)中,检查

#define B6_BWSCON  (DW32)位宽为32

B1_BWSCON改为(DW16 B5_BWSCON改为(DW8),如下:

#define B1_BWSCON               (DW16)
#define B2_BWSCON               (DW16)
//#define B3_BWSCON             (DW16 + WAIT + UBLB)
#define B3_BWSCON               (DW16 + UBLB)
#define B4_BWSCON               (DW16 + WAIT + UBLB)
#define B5_BWSCON               (DW8)
#define B6_BWSCON               (DW32)
#define B7_BWSCON               (DW32)

 

根据HCLK设置SDRAM 的刷新参数,主要是REFCNT寄存器,开发板HCLK100M

将  

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

增加对S3C2440的支持2440的时钟计算公式、NAND操作和2410不太一样。

对于2440开发板,将FCLK设为400MHz,分频比为FCLKHCLKPCLK=148

 

修改board/myjz2440/myjz2440.c中的board_init函数(为了方便,可以再 vi include/s3c24x0.h,加入:

#define isS3C2410               ((rGSTATUS1 & 0xffff0000) == 0x32410000)
):

 

DECLARE_GLOBAL_DATA_PTR;

 

#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) 

/*参考链接是#define S3C2440_MPLL_400MHZ ((0x7f<<12)|(0x02<<4)|(0x01)) ,不过没什么影响*/
#define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))
#define S3C2440_MPLL_100MHZ     ((0x5c<<12)|(0x01<<4)|(0x03))
#define S3C2440_UPLL_96MHZ      ((0x38<<12)|(0x02<<4)|(0x01))
#define S3C2440_UPLL_48MHZ      ((0x38<<12)|(0x02<<4)|(0x02)) //usb有关
#define S3C2440_CLKDIV          (0x05) // | (1<<3))    /* FCLK:HCLK:PCLK = 1:4:8, UCLK = UPLL/2 */
#define S3C2440_CLKDIV188       0x04                  /* FCLK:HCLK:PCLK = 1:8:8 */
#define S3C2440_CAMDIVN188      ((0<<8)|(1<<9)) /* FCLK:HCLK:PCLK = 1:8:8 */

/* Fin = 16.9344MHz */
#define S3C2440_MPLL_399MHz_Fin16MHz    ((0x6e<<12)|(0x03<<4)|(0x01))
#define S3C2440_UPLL_48MHZ_Fin16MHz     ((60<<12)|(4<<4)|(2))


 

int board_init (void)
{

        S3C24X0_CLOCK_POWER *clk_power = S3C24X0_GetBase_CLOCK_POWER();

        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
        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;

        /* FCLK:HCLK:PCLK = 1:4:8 */
        clk_power->CLKDIVN = S3C2440_CLKDIV;

        /* change to asynchronous bus mod */
        __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */
                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */
                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */
                    :::"r1"
                    );
        /* to reduce PLL lock time, adjust the LOCKTIME register */
        clk_power->LOCKTIME = 0xFFFFFFFF;
        clk_power->UPLLCON = S3C2440_UPLL_48MHZ;
        delay (4000);
         /* configure MPLL */
        clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
        /* some delay between MPLL and UPLL */
        /* configure UPLL */
        /* some delay between MPLL and UPLL */
        delay (8000);

      gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
        gd->bd->bi_boot_params = 0x30000100;
        icache_enable();
        dcache_enable();
        return 0;
}

 

cpu/arm920t/s3c24X0/speed.c中修改:

在程序开头增加一行DECLARE_GLOBAL_DATA_PTR;,这样才可以使用gd变量:

 

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;
 /* support both of S3C2410 and S3C2440 */

    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 << s));   /* S3C2440 */
}

/* return FCLK frequency */
ulong get_FCLK(void)
{
    return(get_PLLCLK(MPLL));
}
// jimm add for jz2440
#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)

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

        /* work out clock scalings */

        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;
    }
}

ulong get_PCLK(void)
{
 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

    unsigned long clkdiv;

    unsigned long camdiv;

    int hdiv = 1;

 

    /* support both of S3C2410 and S3C2440 */

    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;
        /* work out clock scalings */
        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);
    }
}

/* return UCLK frequency */
ulong get_UCLK(void)
{
    return(get_PLLCLK(UPLL));
}

重新执行make myjz2440_config   ;make all生成u-boot.bin,由于还没有增加NAND Flash的支持,所以可烧入NOR Flash中运行

make all时会出现错误:没有CAMDIVN

这个要在include/s3c24x0.h中定义, 在129S3C24X0_CLOCK_POWER结构体中增加:

S3C24X0_REG32   CAMDIVN;   /* for s3c2440*/

 

成功后,控制台显示:

U-Boot 1.1.6 (Jul 20 2013 - 09:53:57)

DRAM:  64 MB
Flash: 512 kB(nor flash ,实际有2M)
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
myjz2440 #  printenv
bootdelay=3
baudrate=115200
ipaddr=10.140.1.253
serverip=10.140.1.250
netmask=255.255.255.0
stdin=serial
stdout=serial
stderr=serial


myjz2440 # ping 10.140.1.250
CS8900 Ethernet chip not found?!


C).下面配置支持网卡芯片DM9000(板卡上是DM9000)

driver下,有网卡驱动DM9000x.c DM9000x.h

DM9000接在BANK4,位宽16

 

include/configs/myjz2440.h中设置网卡基地址:

56行处,将CS8900的定义改成:

#define CONFIG_DRIVER_DM9000      1

#define CONFIG_DM9000_BASE     0x20000300

#define DM9000_IO          CONFIG_DM9000_BASE

#define DM9000_DATA        (CONFIG_DM9000_BASE + 4)

#define CONFIG_DM9000_USE_16BIT

修改Makefile: COBJS= dm9000x.o

(修改顶层目录的Makefile:209行的内容

LIBS += drivers/sk98lin/libsk98lin.a  删除

可以将顶层目录下没用的lib_x文件夹删除,只留lib_arm lib_generic

编译可生成支持网卡的uboot

 如果显示:

yjz2440 haha# ping 10.140.1.250
MAC: 08:08:08:08:008:08
could not establish link

 

修改drivers/dm9000x.c

eth_init(){

//从环境获取

  if (is_zero_ether_addr(bd->bi_enetaddr) ||
            is_multicast_ether_addr(bd->bi_enetaddr)) {
                /* try reading from environment */
                u8 i;
                char *s, *e;
                s = getenv ("ethaddr");
                for (i = 0; i < 6; ++i) {
                        bd->bi_enetaddr[i] = s ?
                                simple_strtoul (s, &e, 16) : 0;
                        if (s)
                                s = (*e) ? e + 1 : e;
                }
        }

....

#if 0

 while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
                udelay(1000);
                i++;
                if (i == 10000) {
                        printf("could not establish link\n");
                        return 0;
                }
        }
#endif

 


#define DM9000_outb(d,r) ( *(volatile u8 *)r = d )
#define DM9000_outw(d,r) ( *(volatile u16 *)r = d )
#define DM9000_outl(d,r) ( *(volatile u32 *)r = d )
#define DM9000_inb(r) (*(volatile u8 *)r)
#define DM9000_inw(r) (*(volatile u16 *)r)
#define DM9000_inl(r) (*(volatile u32 *)r)

static inline int is_zero_ether_addr(const u8 *addr)
{
        return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
}

static inline int is_multicast_ether_addr(const u8 *addr)
{
        return (0x01 & addr[0]);
}

 

烧录后显示:

myjz2440 haha# ping 10.140.1.250
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
operating at unknown: 0 mode
checksum bad
checksum bad
checksum bad
checksum bad
host 10.140.1.250 is alive

 

设置Linux启动参数

77行处,加两个宏定义:

/* for tag(s) to transfer message to kernel*/

#define CONFIG_SETUP_MEMORY_TAGS   1

#define CONFIG_CMDLINE_TAG         1


D).下面修改 的nor flash大小显示(MX29LV160B FLASH (16 x 16)  Size: 2 MB)

添加Norflash的information

>vi include/flash.h

第181行添加

#define EON_ID_LV160AB   0x22492249


在include/configs/myjz2440.h添加

//jimym add for myjz2440 MX29LV160B
#define CONFIG_MX29LV160B  1
#ifdef CONFIG_MX29LV160B
#define CONFIG_MX29LV160B     1        //TQ2440 Nor Flash
#define PHYS_FLASH_SIZE            0x200000 //2M
#define CFG_MAX_FLASH_SECT  (35)     //扇区数
#define CFG_ENV_ADDR               (CFG_FLASH_BASE + 0x80000) //
0x80000为参数开始存放位置
#endif

//注释掉下面两个类型的Nor Flash设置(CONFIG_AMD_LV400,CONFIG_AMD_LV800),因为不是我们所使用的型号

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


在board/myjz2440/flash.c添加:

//jimmy add
#define MAIN_SECT_SIZE     0x8000  // 定义为32k,主要扇区的大小


#define MEM_FLASH_ADDR1  (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2  (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))

由于我们是把norflash连接到了s3c2440的bank0上,因此norflash中的地址相对于s3c2440来说基址为0x00000000,即CFG_FLASH_BASE  = 0。
而之所以又把norflash中的地址向左移一位(即乘以2),是因为我们是把s3c2440的ADDR1连接到了norflash的A0上的缘故。

由数据手册可知EN29LV160AB第0扇区大小为8K,第1、2为4K,第3为16K,后面31扇区为32K。前面4个扇区加起来刚好是主要扇区的大小 = 32K, 所以修改87行下如下

for (j = 0; j < flash_info[i].sector_count; j++)
{
    if (j <= 3)
   {
        /* 1st one is 8 KB */
       if (j == 0)
      {
             flash_info[i].start[j] = flashbase + 0;
      }

      /* 2nd and 3rd are both 4 KB */
      if ((j == 1) || (j == 2))
     {
           flash_info[i].start[j] = flashbase + 0x2000 + (j - 1) * 0x1000;
     }

     /* 4th 16 KB */
     if (j == 3)
    {
           flash_info[i].start[j] = flashbase + 0x4000;
     }
 }
 else
 {
       flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE;
 }
}
size += flash_info[i].size;

修改flash_print_info,添加MX29LV160B相关信息如下:


  switch (info->flash_id & FLASH_VENDMASK) {
        case (AMD_MANUFACT & FLASH_VENDMASK):
                printf ("AMD: ");
                break;
case (MX_MANUFACT & FLASH_VENDMASK):
  printf ("MXIC: ");
  break;
        default:
                printf ("Unknown Vendor ");
                break;
        }

switch (info->flash_id & FLASH_TYPEMASK) {
        case (AMD_ID_LV400B & FLASH_TYPEMASK):
                printf ("1x Amd29LV400BB (4Mbit)\n");
                break;
        case (AMD_ID_LV800B & FLASH_TYPEMASK):
                printf ("1x Amd29LV800BB (8Mbit)\n");
                break;
case (MX29LV160B & FLASH_TYPEMASK):
  printf ("1x MX29LV160B (16Mbit)\n");
  break;
        default:
                printf ("Unknown Chip Type\n");
                goto Done;
                break;
        }

修改int flash_erase (flash_info_t * info, int s_first, int s_last)
 if ((info->flash_id & FLASH_VENDMASK) !=
            //(AMD_MANUFACT & FLASH_VENDMASK)) {
            (MX_MANUFACT & FLASH_VENDMASK)) {
                return ERR_UNKNOWN_FLASH_VENDOR;
        }
至此,uboot关于Norflash已经移植好

make distclean

make smdk2440_config

make即可生成u-boot.bin

下载到板子的Norflash,在命令台输入saveenv即可

myjz2440 haha# setenv bootdelay 4
myjz2440 haha# saveenv
Saving Environment to Flash...
Un-Protected 2 sectors
Erasing Flash...Erasing sector 19 ... ok.
Erasing sector 20 ... ok.
Erased 2 sectors
Writing to Flash... done
Protected 2 sectors
myjz2440 haha# flinfo

Bank # 1: MXIC: 1x MX29LV160B (16Mbit)
  Size: 2 MB in 35 Sectors
  Sector Start Addresses:
    00000000 (RO) 00002000 (RO) 00003000 (RO) 00004000 (RO) 00008000 (RO)
    00010000 (RO) 00018000      00020000      00028000      00030000
    00038000      00040000      00048000      00050000      00058000
    00060000      00068000      00070000      00078000      00080000 (RO)
    00088000 (RO) 00090000      00098000      000A0000      000A8000
    000B0000      000B8000      000C0000      000C8000      000D0000
    000D8000      000E0000      000E8000      000F0000      000F8000





 

 

原创粉丝点击