移值2016的u-boot-第2篇-支持Nand flash启动

Posted 宁次

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了移值2016的u-boot-第2篇-支持Nand flash启动相关的知识,希望对你有一定的参考价值。

 

1, 要求:在4K 的代码以内,完成 NOR NAND 类型判断,初始化 NAND 复制自身到 SDRAM ,重定向。

2, 在 /arch/arm/cpu/arm920t/ 文件夹里 添加一个 inic.c 的文件,要在这个文件里面做上面说的事情。
修改 /arch/arm/cpu/arm920t/Makefile 加入 inic.c 的 编译。
extra-y = start.o
obj-y += init.o
obj-y += cpu.o

init.c 最后有补丁文件

3, 在 start.S 中初始化 SP 后调用 init.c 中的 初始化 NAND FLASH 和 复制 u-boot 到 SDRAM 清BSS 等

ldr sp, =4096 #在 NOR 启动时定在这里是不能写的,sp 中通常是保存 入栈 出栈 , 局部变量等,因为函数中并没有用到,设不设这里都可以。
bl init_sdram
ldr sp, =0x34000000
bl nand_init_ll
/**
* 从 0 地址开始复制 到 SDRAM 中
* 在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE
* u-boot 的加载地址
*/
mov r0,#0
ldr r1,=CONFIG_SYS_TEXT_BASE
ldr r2,=__bss_start
sub r2, r2, r1
bl copy_code_to_sdram
bl clear_bss #清不清都可以,因为重定向那里还要在清一次,为了以后去掉重定向这里也清。
#从片内 4K 跳到 SDRAM 中 bl 不行,要用 ldr pc
ldr pc,=_main

4, 启用流程
/arch/arm/cpu/arm920t/start.S
/arch/arm/lib/crt0.S
u-boot 第一阶段
/common/Board_f.c 中的 board_init_f() 函数
最后调用
jump_to_copy()
if (gd->flags & GD_FLG_SKIP_RELOC)
return 0;
调用/arch/arm/librelocate.S relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr);
执行完毕后返回
crt0.S
bl board_init_f
下面直接执行第2阶段,也是因为执行了重定位,bl 跳不了
ldr pc, =board_init_r

5, 如何兼容 NOR FLASH NAND FLASH 启用?
不改动 原来的 重定位代码比较简单。
兼容 NOR FLASH NAND FLASH 的方法是,如果不想修改重定位的代码,就是先把 u-boot 复制到
SDRAM 的一个低地址,然后,它会从 这里在复制到 SDRAM 的高地址去。
NAND FLASH 启用要做的就是,在 4K 自动复制的代码里面,实现把u-boot 复制到 SDRAM 的低地址

6, 确定一个可用的链接地址
crt0.S
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
这里先把 sp 定在了最低端,因此不能使用 0x30000000
又因为u-boot 最终会被放到高地址也不能用 0x34000000
因为内存很大,放在10M 的位置吧。
在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE 0x30a00000

 

补丁文件:

  1 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/init.c u-boot-2016.03-ok/arch/arm/cpu/arm920t/init.c
  2 --- u-boot-2016.03/arch/arm/cpu/arm920t/init.c    1970-01-01 07:00:00.000000000 +0700
  3 +++ u-boot-2016.03-ok/arch/arm/cpu/arm920t/init.c    2016-05-17 06:48:31.635438931 +0800
  4 @@ -0,0 +1,196 @@
  5 +/* NAND FLASH控制器 */
  6 +#define NFCONF (*((volatile unsigned long *)0x4E000000))
  7 +#define NFCONT (*((volatile unsigned long *)0x4E000004))
  8 +#define NFCMMD (*((volatile unsigned char *)0x4E000008))
  9 +#define NFADDR (*((volatile unsigned char *)0x4E00000C))
 10 +#define NFDATA (*((volatile unsigned char *)0x4E000010))
 11 +#define NFSTAT (*((volatile unsigned char *)0x4E000020))
 12 +
 13 +/* CLK */
 14 +#define CLKDIVN  (*(volatile unsigned long *)0x4C000014)
 15 +#define MPLLCON  (*(volatile unsigned long *)0x4C000004) 
 16 +
 17 +/* SDRAM */
 18 +#define BWSCON    (*(volatile unsigned long *)0x48000000) 
 19 +#define BANKCON6  (*(volatile unsigned long *)0x4800001c) 
 20 +#define REFRESH   (*(volatile unsigned long *)0x48000024) 
 21 +#define BANKSIZE  (*(volatile unsigned long *)0x48000028) 
 22 +#define MRSRB6    (*(volatile unsigned long *)0x4800002c)
 23 +
 24 +void init_clock(void)
 25 +{
 26 +    //Mpll = 400M
 27 +    MPLLCON = (0x5c<<12) | (1<<4) | 1;
 28 +    //FCLK 400M HCLK 100M PCLK 50M
 29 +    CLKDIVN = 2<<1 | 1<<0;
 30 +    __asm__(
 31 +        "mrc  p15,0,r0,c1,c0,0\\n" 
 32 +        "orr  r0,r0,#0xc0000000\\n"
 33 +        "mcr  p15,0,r0,c1,c0,0\\n" 
 34 +    );
 35 +}
 36 +
 37 +void init_sdram(void)
 38 +{
 39 +    BWSCON   = 1<<25;
 40 +    BANKCON6 = 1<<16 | 1<<15 | 1;
 41 +    REFRESH  = (1<<23) + 1268;
 42 +    BANKSIZE = 1<<7 | 1<<4 | 1;
 43 +    MRSRB6   = 0x30;
 44 +}
 45 +
 46 +void clear_bss(void)
 47 +{
 48 +    extern int __bss_start, __bss_end;
 49 +    int *p = &__bss_start;
 50 +    
 51 +    for (; p < &__bss_end; p++)
 52 +    {    
 53 +        *p = 0;
 54 +    }
 55 +}
 56 +
 57 +static void nand_latency(void)
 58 +{
 59 +    int i=100;
 60 +    while(i--);
 61 +}
 62 +
 63 +static void nand_is_ready(void)
 64 +{
 65 +    //bit 0 : 1 不忙了
 66 +    while(! (NFSTAT & 1));
 67 +}
 68 +
 69 +static void nand_write_addr(unsigned int addr)
 70 +{
 71 +    int col, page;
 72 +    col = addr % 2048;
 73 +    page = addr / 2048;
 74 +    
 75 +    NFADDR = col & 0xff;            /* Column Address A0~A7 */
 76 +    nand_latency();        
 77 +    NFADDR = (col >> 8) & 0x0f;     /* Column Address A8~A11 */
 78 +    nand_latency();
 79 +    NFADDR = page & 0xff;            /* Row Address A12~A19 */
 80 +    nand_latency();
 81 +    NFADDR = (page >> 8) & 0xff;    /* Row Address A20~A27 */
 82 +    nand_latency();
 83 +    NFADDR = (page >> 16) & 0x03;    /* Row Address A28~A29 */
 84 +    nand_latency();
 85 +}
 86 +
 87 +static unsigned char nand_read_char(void)
 88 +{
 89 +    //只保留8个bit
 90 +    return NFDATA & 0xff;
 91 +}
 92 +
 93 +static void nand_cmd(unsigned char cmd)
 94 +{
 95 +    NFCMMD = cmd;
 96 +    nand_latency();
 97 +}
 98 +
 99 +static void nand_select_chip(void)
100 +{
101 +    //1bit : 0 选中
102 +    NFCONT &= ~(1<<1);
103 +}
104 +
105 +static void nand_deselect_chip(void)
106 +{
107 +    //1bit : 1 选中
108 +    NFCONT |= (1<<1);
109 +}
110 +
111 +static void nand_reset(void)
112 +{
113 +    nand_select_chip();
114 +    nand_cmd(0xff);
115 +    nand_deselect_chip();
116 +}
117 +
118 +void nand_init_ll(void)
119 +{    
120 +    //TACLS 3.3v 时 12ns
121 +    #define TACLS   0
122 +    //12ns
123 +    #define TWRPH0  1
124 +    //5ns
125 +    #define TWRPH1  0
126 +    NFCONF = TACLS<<12 | TWRPH0<<8 |  TWRPH1<<4;
127 +    /* 4 ECC
128 +     * 1 CE 先不选中,用的时候在选中
129 +     * 0 启动 flash controller
130 +     */
131 +    NFCONT = 1<<4 | 1<<1 | 1;
132 +    nand_reset();
133 +}
134 +
135 +static void nand_read(unsigned int addr, unsigned char *buf, int len)
136 +{
137 +    //选中
138 +    nand_select_chip();
139 +    //j 地址可能不是从0对齐开始读的
140 +    unsigned int i = addr,j = addr % 2048;
141 +    for(; i<(addr + len);)
142 +    {
143 +        //读命令
144 +        nand_cmd(0x00);
145 +        nand_is_ready();
146 +        
147 +        //发送地址
148 +        nand_write_addr(i);
149 +        nand_is_ready();
150 +    
151 +        //在次发出读命令
152 +        nand_cmd(0x30);
153 +        nand_is_ready();
154 +        //读2K
155 +        for(; j<2048; j++)
156 +        {
157 +            *buf = nand_read_char();
158 +            buf++;
159 +            i++;
160 +        }
161 +        j=0;
162 +        nand_latency();
163 +    }
164 +    //取消选中
165 +    nand_deselect_chip();
166 +}
167 +
168 +static int boot_is_nor()
169 +{
170 +    //利用 NOR 不能写的特点判断
171 +    volatile unsigned int *p = (volatile unsigned int *)0;
172 +    unsigned int val;
173 +    val = *p;
174 +    *p = 0x12345678;
175 +    if(0x12345678 == *p)
176 +    {
177 +        *p = val;
178 +        return 0;
179 +    }
180 +    return 1;
181 +}
182 +
183 +//片内4K 的程序要复制到链接SDRAM中去
184 +void copy_code_to_sdram(unsigned char *src,unsigned char *dst,int len)
185 +{
186 +    int i = 0;
187 +    if(boot_is_nor())
188 +    {
189 +        while(i < len)
190 +        {
191 +            dst[i] = src[i];
192 +            i++;
193 +        }
194 +    }
195 +    else
196 +    {
197 +        nand_read((int)src, dst, len);
198 +    }
199 +}
200 +
201 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/Makefile u-boot-2016.03-ok/arch/arm/cpu/arm920t/Makefile
202 --- u-boot-2016.03/arch/arm/cpu/arm920t/Makefile    2016-03-14 22:20:21.000000000 +0800
203 +++ u-boot-2016.03-ok/arch/arm/cpu/arm920t/Makefile    2016-05-17 06:48:31.767626866 +0800
204 @@ -8,6 +8,7 @@
205  extra-y    = start.o
206  
207  obj-y    += cpu.o
208 +obj-y    += init.o
209  obj-$(CONFIG_USE_IRQ)    += interrupts.o
210  
211  obj-$(CONFIG_EP93XX) += ep93xx/
212 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/start.S u-boot-2016.03-ok/arch/arm/cpu/arm920t/start.S
213 --- u-boot-2016.03/arch/arm/cpu/arm920t/start.S    2016-03-14 22:20:21.000000000 +0800
214 +++ u-boot-2016.03-ok/arch/arm/cpu/arm920t/start.S    2016-05-17 06:48:31.782641369 +0800
215 @@ -82,11 +82,50 @@
216  
217      /* FCLK:HCLK:PCLK = 1:2:4 */
218      /* default FCLK is 120 MHz ! */
219 -    ldr    r0, =CLKDIVN
220 -    mov    r1, #3
221 -    str    r1, [r0]
222 +    //ldr    r0, =CLKDIVN
223 +    //mov    r1, #3
224 +     //str    r1, [r0]
225 +
226 +    /* 设置分频参数 */
227 +    ldr r0, =CLKDIVN
228 +    mov r1, #0x05;    /* FCLK:HCLK:PCLK=1:4:8 */
229 +    str r1, [r0]
230 +
231 +    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
232 +    mrc    p15, 0, r1, c1, c0, 0        /* 读出控制寄存器 */ 
233 +    orr    r1, r1, #0xc0000000            /* 设置为“asynchronous bus mode” */
234 +    mcr    p15, 0, r1, c1, c0, 0        /* 写入控制寄存器 */
235 +
236 +    /* 配置时钟 */
237 +    #define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))
238 +    ldr r0, =0x4c000004
239 +    ldr r1, =S3C2440_MPLL_400MHZ
240 +    str r1, [r0]
241 +
242  #endif    /* CONFIG_S3C24X0 */
243  
244 +    /**
245 +         * 调用 init.c 中的初始化
246 +         * 因为已经初始化好内存 所以 sp 在 顶部 
247 +         * 在 NOR 时不能用片内 4K
248 +         */
249 +        ldr sp, =4096
250 +        bl init_sdram
251 +        ldr sp, =0x34000000
252 +        bl nand_init_ll
253 +        /**
254 +         * 从 0 地址开始复制 到 SDRAM 中
255 +         * 在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE
256 +         * u-boot 的加载地址
257 +         */
258 +        mov r0,#0
259 +        ldr r1, =CONFIG_SYS_TEXT_BASE
260 +        ldr r2, =__bss_start
261 +        sub r2, r2, r1
262 +        bl copy_code_to_sdram
263 +        bl clear_bss
264 +        ldr pc, =_main
265 +
266      /*
267       * we do sys-critical inits only at reboot,
268       * not when booting from ram!
269 @@ -95,8 +134,6 @@
270      bl    cpu_init_crit
271  #endif
272  
273 -    bl    _main
274 -
275  /*------------------------------------------------------------------------------*/
276  
277      .globl    c_runtime_cpu_setup
278 diff -urN u-boot-2016.03/arch/arm/cpu/u-boot.lds u-boot-2016.03-ok/arch/arm/cpu/u-boot.lds
279 --- u-boot-2016.03/arch/arm/cpu/u-boot.lds    2016-03-14 22:20:21.000000000 +0800
280 +++ u-boot-2016.03-ok/arch/arm/cpu/u-boot.lds    2016-05-12 09:28:12.338040880 +0800
281 @@ -32,7 +32,7 @@
282       */
283      /DISCARD/ : { *(.rel._secure*) }
284  #endif
285 -    . = 0x00000000;
286 +    . = 0;
287  
288      . = ALIGN(4);
289      .text :
290 diff -urN u-boot-2016.03/arch/arm/Kconfig u-boot-2016.03-ok/arch/arm/Kconfig
291 --- u-boot-2016.03/arch/arm/Kconfig    2016-03-14 22:20:21.000000000 +0800
292 +++ u-boot-2016.03-ok/arch/arm/Kconfig    2016-05-09 08:48:52.118143749 +0800
293 @@ -91,6 +91,10 @@
294  config TARGET_SMDK2410
295      bool "Support smdk2410"
296      select CPU_ARM920T
297 +    
298 +config TARGET_SMDK2440
299 +    bool "Support smdk2440"
300 +    select CPU_ARM920T
301  
302  config TARGET_ASPENITE
303      bool "Support aspenite"
304 @@ -829,6 +833,7 @@
305  source "board/phytec/pcm052/Kconfig"
306  source "board/ppcag/bg0900/Kconfig"
307  source "board/samsung/smdk2410/Kconfig"
308 +source "board/samsung/smdk2440/Kconfig"
309  source "board/sandisk/sansa_fuze_plus/Kconfig"
310  source "board/schulercontrol/sc_sps_1/Kconfig"
311  source "board/siemens/draco/Kconfig"
312 diff -urN u-boot-2016.03/arch/arm/lib/crt0.S u-boot-2016.03-ok/arch/arm/lib/crt0.S
313 --- u-boot-2016.03/arch/arm/lib/crt0.S    2016-03-14 22:20:21.000000000 +0800
314 +++ u-boot-2016.03-ok/arch/arm/lib/crt0.S    2016-05-16 17:11:44.287690421 +0800
315 @@ -99,7 +99,6 @@
316   * relocate_code(addr_moni). Trick here is that we\'ll return
317   * \'here\' but relocated.
318   */
319 -
320      ldr    sp, [r9, #GD_START_ADDR_SP]    /* sp = gd->start_addr_sp */
321  #if defined(CONFIG_CPU_V7M)    /* v7M forbids using SP as BIC destination */
322      mov    r3, sp
323 @@ -130,14 +129,17 @@
324  
325      bl    c_runtime_cpu_setup    /* we still call old routine here */
326  #endif
327 +
328 +
329  #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
330 -# ifdef CONFIG_SPL_BUILD
331 +#ifdef CONFIG_SPL_BUILD
332      /* Use a DRAM stack for the rest of SPL, if requested */
333      bl    spl_relocate_stack_gd
334      cmp    r0, #0
335      movne    sp, r0
336      movne    r9, r0
337 -# endif
338 +#endif
339 +
340      ldr    r0, =__bss_start    /* this is auto-relocated! */
341  
342  #ifdef CONFIG_USE_ARCH_MEMSET
343 @@ -177,3 +179,4 @@
344  #endif
345  
346  ENDPROC(_main)
347 +
348 diff -urN u-boot-2016.03/arch/arm/lib/relocate.S u-boot-2016.03-ok/arch/arm/lib/relocate.S
349 --- u-boot-2016.03/arch/arm/lib/relocate.S    2016-03-14 22:20:21.000000000 +0800
350 +++ u-boot-2016.03-ok/arch/arm/lib/relocate.S    2016-05-16 17:11:48.481661370 +0800
351 @@ -26,6 +26,7 @@
352  
353  ENTRY(relocate_vectors)
354  
355 +
356  #ifdef CONFIG_CPU_V7M
357      /*
358       * On ARMv7-M we only have to write the new vector address
359 diff -urN u-boot-2016.03/board/samsung/smdk2440/Kconfig u-boot-2016.03-ok/board/samsung/smdk2440/Kconfig
360 --- u-boot-2016.03/board/samsung/smdk2440/Kconfig    

以上是关于移值2016的u-boot-第2篇-支持Nand flash启动的主要内容,如果未能解决你的问题,请参考以下文章

s3c2440 移值u-boot-2016.03 第6篇 支持mtd yaffs 烧写

s3c2440 移值2016的u-boot-第3篇-支持Nor flash 识别

s3c2440 移值u-boot-2016.03 第5篇 支持dm9000 识别

u-boot2016.05 有关 4096page size , oob == 224 nand 的移植支持

u-boot-2016.03 支持yaffs2文件系统烧写之添加nand write.yaffs2命令

u-boot-2014.10移植支持nand