移植u-boot.2012.04.01_2

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

*u-boot版本:u-boot2012.04.01

*gcc版本:arm-linux-gcc-4.3.2

*服务器:ubuntu12.04

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

一、建立单板
在board/复制smdk2410文件夹为smdk2440文件夹
在include/configs/将smdk2410.h - >smdk2440.h

二、修改时钟
1.进入smdk2440文件夹,修改函数board_early_init_f
  注释掉:
  //writel(0xFFFFFF, &clk_power->locktime);

  /* configure MPLL */
  //writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
  // &clk_power->mpllcon);


2.在start.S里面:
  /* FCLK:HCLK:PCLK = 1:2:4 */
  /* default FCLK is 400 MHz ! */
  /*2. 设置时钟 */
  ldr r0, =0x4c000014
  // mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
  mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
  str r1, [r0]

  /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
  mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */
  orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
  mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */

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

  /* MPLLCON = S3C2440_MPLL_200MHZ */
  ldr r0, =0x4c000004
  ldr r1, =S3C2440_MPLL_400MHZ
  str r1, [r0]

  /* 启动ICACHE */
  mrc p15, 0, r0, c1, c0, 0 @ read control reg
  orr r0, r0, #(1<<12)
  mcr p15, 0, r0, c1, c0, 0 @ write it back
  #endif /* CONFIG_S3C24X0 */

3. ③把lowlevel_init.S里面的lowlevel_init函数里面
SMRDATA:
  .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+  (B7_BWSCON<<28))
  .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
  .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
  .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
  .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
  .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
  .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
  .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
  .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
  .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
  .word 0x32
  .word 0x30
  .word 0x30
  替换为:
SMRDATA:
  .long 0x22011110 //BWSCON
  .long 0x00000700 //BANKCON0
  .long 0x00000700 //BANKCON1
  .long 0x00000700 //BANKCON2
  .long 0x00000700 //BANKCON3
  .long 0x00000700 //BANKCON4
  .long 0x00000700 //BANKCON5
  .long 0x00018005 //BANKCON6
  .long 0x00018005 //BANKCON7
  .long 0x008C04F4 // REFRESH
  .long 0x000000B1 //BANKSIZE
  .long 0x00000030 //MRSRB6
  .long 0x00000030 //MRSRB7

4.$ vi boards.cfg
  在boards.cfg文件下复制65行,修改boards.cfg:
  仿照
  smdk2410 arm arm920t - samsung s3c24x0
  添加:
  smdk2440 arm arm920t - samsung s3c24x0
5.完成以上三步,编译通过
6.乱码,查看串口波特率的设置,发现在get_HCLK里没有定义CONFIG_S3C2440
7.处理措施:include/configs/smdk2440.h:
  去掉CONFIG_S3C2410
  添加#define CONFIG_S3C2440
  编译,出现错误:
  s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
8. 处理措施:舍弃nand,使用我们自己的代码init.c
  $ vi drivers/mtd/nand/Makefile //从makefile看出依赖于哪个宏,而不是在makefile里面注释掉
  COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
  得知依赖的宏是CONFIG_NAND_S3C2410
  进入:include/configs/smdk2440.h -->
  有: /*
  * NAND configuration
  */
  #ifdef CONFIG_CMD_NAND
  #define CONFIG_NAND_S3C2410
  #define CONFIG_SYS_S3C2410_NAND_HWECC
  #define CONFIG_SYS_MAX_NAND_DEVICE 1
  #define CONFIG_SYS_NAND_BASE 0x4E000000
  #endif
  所以我们屏蔽掉CONFIG_CMD_NAND宏即可
9.烧写

  下面是uboot输出:
  U-Boot 2012.04.01 (Jul 29 2013 - 20:26:01)

  CPUID: 32440001
  FCLK: 400 MHz
  HCLK: 100 MHz
  PCLK: 50 MHz
  DRAM: 64 MiB
  WARNING: Caches not enabled
  Flash: *** failed ***
  ### ERROR ### Please RESET the board ### 串口输出正确

  此时支持nor启动,但是不支持nand启动

/*###################################华丽分界线##################################*/

  修改UBOOT支持NAND启动
1.1 去掉 "-pie"选项,减少代码大小
  grep "\-pie" * -nR
  arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉这行
  如下:
  ifndef CONFIG_NAND_SPL
  #LDFLAGS_u-boot += -pie
  endif
1.2 把init.c放入board/samsung/smdk2440目录,修改init.c文件主要是加上static , 修改Makefile
  修改CONFIG_SYS_TEXT_BASE为0x33f80000 //0x34000000-33f80000 =512k,对于uboot足够

1.3 修改start.S
  ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  bic sp, sp, #7 /* 8-byte alignment for ABI compliance */


  bl nand_init_ll
  mov r0, #0 //src_addr
  //ldr r1, =_start
  ldr r1,_TEXT_BASE //地址固定 dest_addr

  //ldr r2, =__bss_start //CONFIG_SYS_TEXT_BASE
  //sub r2, r2, r1
  //以上两条在这里是
  ldr r2,_bss_start_ofs //len


  bl copy_code_to_sdram
  bl clear_bss

  ldr pc,= call_board_init_f

  /* Set stackpointer in internal RAM to call board_init_f */
  call_board_init_f:
  ldr r0,=0x00000000
  bl board_init_f //会调用重定位

  =============================================================

  //第一个参数由board_init_f传回来,存在r0里面 < ------------------------ -------------
  ldr r1,=__bss_start //注意等号                                                                            |
  bl board_init_f //调用第二阶段                                                                              |
                                                                                                                            |
  修改init.c                                                                                                          |
                                                                                                                            |
  __bss_end__名字有点差别                                                                                  |
                                                                                                                            |
1.4 修改board_init_f, 把relocate_code去掉                                                                  |
  //relocate_code(addr_sp, id, addr);                                                                     |
  删掉start.S里面相关代码,然后下面就执行第二阶段代码,实质上调用board_init_r              |
  1.5 修改board_init_r ,函数原型是void board_init_r(gd_t *id, ulong dest_addr           |
  参数:r0 = 链接地址                                                                                             |
  r1 = id (可以使用board_init_f返回得到) ----------------------------------------------
  相应的在board_init_f,把void变为snsigned int
  并在最后加上:
  return (unsigned int*)id;

1.6 修改链接脚本: 把start.S, init.c, lowlevel.S等文件放在最前面
  find -name "u-boot.lds"
  ./arch/arm/cpu/u-boot.lds:
  board/samsung/smdk2440/libsmdk2440.o (.text)
1.7 编译报错
  board.c:259: error: conflicting types for 'board_init_f'
  previous declaration of 'board_init_f' was here
  /work/tmp/u-boot-2012.04.01/include/common.h:276: error:
1.8 修改:/include/Common.h
  /* arch/$(ARCH)/lib/board.c */
  unsigned int board_init_f (ulong);
  void board_init_r (gd_t *, ulong);
1.9 编译
  #make distclean
  #make smdk2440_config
  #make
1.10 结果 ok。
注意:期间可能会发生各种乱七八糟的错误,尽量多执行make distclean然后再重新编译

2.0 地址映射不对
  修改board_init_f函数:
  //addr -= gd->mon_len;
  //addr &= ~(4096 - 1);
  addr = CONFIG_SYS_TEXT_BASE; //or addr = _TEXT_BASE

  此时发现u-boot.bin有40多k,包括bss段有70多k,那么我们设定的CONFIG_SYS_TEXT_BASE为0x33f80000到34000000有512k
  所以这里还是不够的,那么我们在这里把CONFIG_SYS_TEXT_BASE设定为0x33f00000,预留1M,足够
  .globl _bss_end_ofs //start.S 是程序本身的大小,可以在反汇编里面查看到大小
  _bss_end_ofs:
  .word __bss_end__ - _start

  乱码:
  因为CONFIG_CMD_NAND没有屏蔽掉

  报错:/work/tmp/u-boot-2012.04.01/fs/yaffs2/yaffscfg.c:210: undefined reference to `nand_info'
  处理:去掉#define CONFIG_YAFFS2 -- 》 在smdk2440.h里面

  打印信息:说明支持NAND FLASH

  U-Boot 2012.04.01 (Jul 26 2015 - 16:02:34)

  CPUID: 32440001
  FCLK: 400 MHz
  HCLK: 100 MHz
  PCLK: 50 MHz
  DRAM: 64 MiB

  以上支持nand启动,但是并不是支持nand读写操作
/*########################华丽分界线######################*/

 


修改UBOOT支持NOR FLASH
此时,uboot会打印如下内容:
Flash: *** failed ***
### ERROR ### Please RESET the board ### 串口输出正确
搜索“Flash”看源码知:
board_init_r函数里面有:
  # ifdef CONFIG_SYS_FLASH_CHECKSUM
。。。
  else {
  puts(failed);
  hang();
}而
  hang()
  void hang(void)
  {
  puts("### ERROR ### Please RESET the board ###\n");
  for (;;);
  }
说明,由于没有定义CONFIG_SYS_FLASH_CHECKSUM,导致,在hang()里面死循环
修改为:
  else {
  puts("0 KB\n\r"); //屏蔽掉hang()函数
  //puts(failed);
  //hang();
  }

怎么样可以让nand里面识别出 nor flash ?
  flash_init()里面有:
  if (!flash_detect_legacy(cfi_flash_bank_addr(i), i)) //先使用flash_detect_legacy老版本来检测
  //#ifdef CONFIG_FLASH_CFI_LEGACY使用这个宏来决定使用哪一个
  flash_get_size(cfi_flash_bank_addr(i), i); //新方法

  flash_detect_legacy里面调用
  flash_read_jedec_ids(info);得到ID信息
  jedec_flash_match //匹配ID信息
遍历jedec_table数组,找到对应芯片

  我们使用的芯片是MX29LV160DB,但是uboot里面没有,而有相近的AM29LV040B,这是需要借助数据手册仿写一个
MX29LV160DB特性有:
大小:2M
位数:16位
扇区数目:4个

已经有的配置:
{
  .mfr_id = (u16)AMD_MANUFACT,
  .dev_id = AM29LV040B,
  .name = "AMD AM29LV040B",
  .uaddr = {
  [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
  },
  .DevSize = SIZE_512KiB,
  .CmdSet = P_ID_AMD_STD,
  .NumEraseRegions= 1,
  .regions = {
  ERASEINFO(0x10000,8),
  }
  }


以上各种参数说明:
  struct amd_flash_info {
  const __u16 mfr_id;
  const __u16 dev_id;
  const char *name;
  const int DevSize;
  const int NumEraseRegions;
  const int CmdSet;
  const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */
  const ulong regions[6];
  };

  在上面 flash_get_size()函数里面有一句:
  if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
  printf("ERROR: too many flash sectors\n");
  break;
  }
  。。。
  for (i = 0; i < num_erase_regions; i++) { //搜索num_erase_regions可知扇区最多有4种
  if (i > NUM_ERASE_REGIONS) {
  printf ("%d erase regions found, only %d used\n",
  num_erase_regions, NUM_ERASE_REGIONS);
  break;
  }

搜索CONFIG_SYS_MAX_FLASH_SECT可以知道:
  #define CONFIG_SYS_MAX_FLASH_SECT (19) 扇区数量最大19个


最终修改为:

  {
  .mfr_id = (u16)AMD_MANUFACT, //厂家ID
  .dev_id = 0x2249, //设备ID
  .name = "AMD AM29LV040B", //名字
  .uaddr = {
  [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ //unlock addr
  },
  .DevSize = SIZE_2MiB, //size
  .CmdSet = P_ID_AMD_STD, //命令类型
  .NumEraseRegions= 4, //可擦除扇区数目,这里是4个
  .regions = {
  ERASEINFO(16*1024,1), //下面是具体的扇区列表
  ERASEINFO(8*1024,2),
  ERASEINFO(32*1024,1),
  ERASEINFO(64*1024,31)
  }
}


























































你可能感兴趣的:(2012)