Chinaunix首页 | 论坛 | 博客
  • 博客访问: 567195
  • 博文数量: 169
  • 博客积分: 2656
  • 博客等级: 少校
  • 技术积分: 1685
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-30 13:03
文章分类

全部博文(169)

文章存档

2011年(1)

2010年(135)

2009年(33)

我的朋友

分类: 嵌入式

2010-06-05 01:07:38

6410开发板上有nor芯片,但是u-boot没有做nor驱动,将u-boot保存在nor中比较安全,因为nand很有可能会被全部清空。

查看开发板硬件原理图,发现使用的nor flash芯片是am29lv160DB,2MByte,但是由于a20被ddr占用,只连接了a0-a18这19根数据线,也就是只能使用1Mbyte空间。

既然只有1Mbyte空间,应该和am29lv800这颗芯片的使用方法兼容,查看smdk6410.h,发现启动有AMD_LV800相关的定义,smdk6410文件夹中的flash.c文件也是针对AMD_LV800的,看来使用nor芯片的难度不大。

1 为u-boot添加nor驱动支持
1)修改smdk6410.h文件
确认打开宏定义#define CONFIG_AMD_LV800

修改#define CFG_FLASH_BASE   0x10000000
根据原理图,nor芯片使用CSn[0]片选,基址0x10000000

修改#define CFG_MAX_FLASH_BANKS 1
至少有一颗nor芯片

修改#define CFG_MAX_FLASH_SECT 19
nor flash大小

2)重新编译下载后,启动能够识别出nor flash芯片
Flash:   1 MB
但是任何操作均没有响应

3)查看flash.c源码,发现只要定义CONFIG_AMD_LV800,在flash_init中就会对nor参数进行赋值,并没有从芯片读取数据。
也就说目前并没有真正从nor flash芯片中读到数据。

4)开始怀疑bank宽度设置不正确,因为前面做dm9000ae时就需要将bank宽度设置为16。
查看s3c6410数据手册,发现CSn[0]的bank宽度又H/W控制,如果配置nor启动,能够正确设置,但我目前还是nand启动。。。
调用printf,在启动时打印出SROM_BW_REG的值,是0xd0,果然,只初始化了CSn[1],CSn[0]还是停留在8bit宽带

5)参考dm9000的初始化,修改smdk6410.c文件
SROM_BW_REG &= ~(0xf);     //nor
SROM_BW_REG |= (1<<3) | (1<<2) | (1);
添加初始化带宽代码,当然也可以修改SROM_BC0_REG,优化时序,也可以使用默认值。

6)重新编译后,nor flash可以使用!
nor 开头会被默认设置为RO,每次要unprotect比较烦,可以注释掉flash.c中flash_init相关代码
/*
flash_protect (FLAG_PROTECT_SET,
         CFG_FLASH_BASE,
         CFG_FLASH_BASE + monitor_flash_len - 1,
         &flash_info[0]);

flash_protect (FLAG_PROTECT_SET,
         CFG_ENV_ADDR,
         CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
*/


2 为u-boot添加nor启动
其实nor启动比nand启动简单多了,因为程序可以直接在nor中运行,通过简单的搬运代码将自身搬运到ram中即可。

1)修改smdk6410.h文件
#define CONFIG_BOOT_NOR  
//#define CONFIG_BOOT_NAND
将nand_boot改为nor_boot

注释掉下面内容
//# error Define one of CONFIG_BOOT_{NAND|MOVINAND|ONENAND|ONENAND_IROM}

还有个宏不知道是否有用,也打开
#define CONFIG_USE_NOR_BOOT

2)重新编译,将内容烧到nor flash的开头(用cp.b比较方便)
将启动方式改为nor(1010)
上电后发现只能显示“OK”就没有内容了,郁闷
用si搜索了ok,没发现相关代码,估计这个ok使用asicii代码输出的(后面印证确实如此)

3)无奈跟u-boot启动代码
首先是执行s3c64xx的start.s文件
下面是代码执行顺序
_start:
reset:
cpu_init_crit:
bl lowlevel_init
这句bl 跳转到lowlevel_init.S初始化处理器代码,如果将其屏蔽掉,就没有OK了

4)跳转到lowlevel_init.s文件
lowlevel_init:
bl mem_ctrl_asm_init (这段在cpu_init.s中)
wakeup_reset:
system_clock_init: 初始化时钟,就是上次改666频率那段汇编
uart_asm_init:    初始话串口
找到输出'O'的代码
ldr r1, =0x4f4f4f4f
str r1, [r0, #UTXH_OFFSET]   @'O'
nand_asm_init:   初始话nand基本代码
最后找到输出'K'的代码
ldr r0, =ELFIN_UART_BASE
ldr r1, =0x4b4b4b4b
str r1, [r0, #UTXH_OFFSET]
这段代码可用来跟踪初始化流程!

5)回到start.s,下面的代码实现搬运
/*
* Go setup Memory and board specific bits prior to relocation.
*/
bl lowlevel_init /* go setup pll,mux,memory */

/* when we already run in ram, we don't need to relocate U-Boot.
* and actually, memory controller must be configured before U-Boot
* is running in ram.
*/
ldr r0, =0xff000fff
bic r1, pc, r0   /* r0 <- current base addr of code */
ldr r2, _TEXT_BASE   /* r1 <- original base addr in ram */
bic r2, r2, r0   /* r0 <- current base addr of code */
cmp     r1, r2                  /* compare r0, r1                  */
beq     after_copy   /* r0 == r1 then skip flash copy   */

#ifdef CONFIG_BOOT_NOR    /* relocate U-Boot to RAM */
adr r0, _start   /* r0 <- current position of code   */
ldr r1, _TEXT_PHY_BASE /* r1 <- destination                */
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2   /* r2 <- size of armboot            */
add r2, r0, r2   /* r2 <- source end address         */

nor_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 nor_copy_loop

ldr r0, =ELFIN_UART_BASE //在这儿输出'1',是可以的,说明搬运完成,代码应该已经到ram中
ldr r1, =0x31313131
str r1, [r0, #UTXH_OFFSET]

b after_copy

after_copy:
enable_mmu: //打开mmu
ldr r0, =ELFIN_UART_BASE //在这儿输出'2',也可以,说明mmu打开正常
ldr r1, =0x32323232
str r1, [r0, #UTXH_OFFSET]
stack_setup: //初始化堆栈
clear_bss:
ldr r0, =ELFIN_UART_BASE
ldr r1, =0x33333333
str r1, [r0, #UTXH_OFFSET] //在这儿输出'3',也可以,下面就要跳转到c代码了!

ldr pc, _start_armboot
_start_armboot:
.word start_armboot

6)start_armboot位于lib_arm/board.c
void start_armboot (void)
在line289添加puts("a");后,竟然也可以输出,orz,然后,整个u-boot就莫名其妙的好了。。

OK123a

U-Boot 1.1.6 (Aug 19 2009 - 22:36:49) for SMDK6410

****************************************
**    UT-S3C6410 Nor boot v2          **
****************************************

CPU:    
         Fclk = 666MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (ASYNC Mode)
Board:   SMDK6410
DRAM:    128 MB
Flash:   1 MB
NAND:    256 MB
In:      serial
Out:     serial
Err:     serial
kyon6410 #

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