二、【s3c2440移植u-boot-2016-11】 支持Nand Flash启动u-boot

(一)Nand Flash上启动u-boot

在第一个博客NOR Flash上启动u-boot的u-boot.bin是不支持用Nand Flash启动,至于为什么呢?
我这里就不啰嗦了,直接进入我们的正题,想知道有兴趣的朋友可以百度一下。

1、增加board/samsung/smdk2440/init.c文件

diff -urN u-boot-2016.11/board/samsung/smdk2440/init.c u-boot-2016.11_s3c2440/board/samsung/smdk2440/init.c  
--- u-boot-2016.11/board/samsung/smdk2440/init.c    1970-01-01 08:00:00.000000000 +0800  
+++ u-boot-2016.11_s3c2440/board/samsung/smdk2440/init.c    2018-06-15 15:29:34.456161999 +0800  
@@ -0,0 +1,142 @@  
+  
+/* NAND FLASH控制器 */  
+#define NFCONF (*((volatile unsigned long *)0x4E000000))  
+#define NFCONT (*((volatile unsigned long *)0x4E000004))  
+#define NFCMMD (*((volatile unsigned char *)0x4E000008))  
+#define NFADDR (*((volatile unsigned char *)0x4E00000C))  
+#define NFDATA (*((volatile unsigned char *)0x4E000010))  
+#define NFSTAT (*((volatile unsigned char *)0x4E000020))  
+/* GPIO */  
+#define GPHCON              (*(volatile unsigned long *)0x56000070)  
+#define GPHUP               (*(volatile unsigned long *)0x56000078)  
+/* UART registers*/  
+#define ULCON0              (*(volatile unsigned long *)0x50000000)  
+#define UCON0               (*(volatile unsigned long *)0x50000004)  
+#define UFCON0              (*(volatile unsigned long *)0x50000008)  
+#define UMCON0              (*(volatile unsigned long *)0x5000000c)  
+#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)  
+#define UTXH0               (*(volatile unsigned char *)0x50000020)  
+#define URXH0               (*(volatile unsigned char *)0x50000024)  
+#define UBRDIV0             (*(volatile unsigned long *)0x50000028)  
+#define TXD0READY   (1<<2)  
+void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);  
+static int isBootFromNorFlash(void)  
+{  
+    volatile int *p = (volatile int *)0;  
+    int val;  
+    val = *p;  
+    *p = 0x12345678;  
+    if (*p == 0x12345678)  
+    {  
+        /* 写成功, 是nand启动 */  
+        *p = val;  
+        return 0;  
+    }  
+    else  
+    {  
+        /* NOR不能像内存一样写 */  
+        return 1;  
+    }  
+}  
+void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)  
+{     
+    int i = 0;  
+    /* 如果是NOR启动 */  
+    if (isBootFromNorFlash())  
+    {  
+        while (i < len)  
+        {  
+            dest[i] = src[i];  
+            i++;  
+        }  
+    }  
+    else  
+    {  
+        //nand_init();  
+        nand_read_ll((unsigned int)src, dest, len);  
+    }  
+}  
+void clear_bss(void)  
+{  
+    extern int __bss_start, __bss_end;  
+    int *p = &__bss_start;  
+    for (; p < &__bss_end; p++)  
+        *p = 0;  
+}  
+void nand_init_ll(void)  
+{  
+#define TACLS   0  
+#define TWRPH0  1  
+#define TWRPH1  0  
+    /* 设置时序 */  
+    NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);  
+    /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */  
+    NFCONT = (1<<4)|(1<<1)|(1<<0);    
+}  
+static void nand_select(void)  
+{  
+    NFCONT &= ~(1<<1);   
+}  
+static void nand_deselect(void)  
+{  
+    NFCONT |= (1<<1);     
+}  
+static void nand_cmd(unsigned char cmd)  
+{  
+    volatile int i;  
+    NFCMMD = cmd;  
+    for (i = 0; i < 10; i++);  
+}  
+static void nand_addr(unsigned int addr)  
+{  
+    unsigned int col  = addr % 2048;  
+    unsigned int page = addr / 2048;  
+    volatile int i;  
+    NFADDR = col & 0xff;  
+    for (i = 0; i < 10; i++);  
+    NFADDR = (col >> 8) & 0xff;  
+    for (i = 0; i < 10; i++);  
+    NFADDR  = page & 0xff;  
+    for (i = 0; i < 10; i++);  
+    NFADDR  = (page >> 8) & 0xff;  
+    for (i = 0; i < 10; i++);  
+    NFADDR  = (page >> 16) & 0xff;  
+    for (i = 0; i < 10; i++);     
+}  
+static void nand_wait_ready(void)  
+{  
+    while (!(NFSTAT & 1));  
+}  
+static unsigned char nand_data(void)  
+{  
+    return NFDATA;  
+}  
+void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)  
+{  
+    int col = addr % 2048;  
+    int i = 0;  
+    /* 1. 选中 */  
+    nand_select();  
+    while (i < len)  
+    {  
+        /* 2. 发出读命令00h */  
+        nand_cmd(0x00);  
+        /* 3. 发出地址(分5步发出) */  
+        nand_addr(addr);  
+        /* 4. 发出读命令30h */  
+        nand_cmd(0x30);  
+        /* 5. 判断状态 */  
+        nand_wait_ready();  
+        /* 6. 读数据 */  
+        for (; (col < 2048) && (i < len); col++)  
+        {  
+            buf[i] = nand_data();  
+            i++;  
+            addr++;  
+        }  
+        col = 0;  
+    }  
+    /* 7. 取消选中 */         
+    nand_deselect();  
+}  
+  

2、修改arch/arm/lib/crt0.S

diff -urN u-boot-2016.11/arch/arm/lib/crt0.S u-boot-2016.11_s3c2440/arch/arm/lib/crt0.S
--- u-boot-2016.11/arch/arm/lib/crt0.S  2016-11-15 00:27:11.000000000 +0800
+++ u-boot-2016.11_s3c2440/arch/arm/lib/crt0.S  2018-06-15 15:30:16.773310005 +0800
@@ -82,15 +82,27 @@
 #else
    bic sp, sp, #7  /* 8-byte alignment for ABI compliance */
 #endif
-   mov r0, sp
-   bl  board_init_f_alloc_reserve
-   mov sp, r0
+   bl nand_init_ll
+   mov r0, #0
+   ldr r1, =_start
+   ldr r2, =__bss_start
+   sub r2, r2, r1
+   ldr r1, =CONFIG_SYS_TEXT_BASE
+   bl copy_code_to_sdram
+   bl clear_bss
+   ldr pc, =START_ON_RAM          //start run on RAM
+
+START_ON_RAM:
+   mov r0, sp
+   bl  board_init_f_alloc_reserve
+   mov sp, r0
    /* set up gd here, outside any C code */
-   mov r9, r0
-   bl  board_init_f_init_reserve
+   mov r9, r0
+   bl  board_init_f_init_reserve

-   mov r0, #0
-   bl  board_init_f
+   mov r0, #0
+   bl  board_init_f
+   str r1, [r0]

 #if ! defined(CONFIG_SPL_BUILD)

@@ -118,17 +130,19 @@
    orr lr, #1              /* As required by Thumb-only */
 #endif
    ldr r0, [r9, #GD_RELOCADDR]     /* r0 = gd->relocaddr */
-   b   relocate_code
+   //b relocate_code
+   ldr r2, =__rel_dyn_start
+   ldr r3, =__rel_dyn_end
 here:
 /*
  * now relocate vectors
  */

-   bl  relocate_vectors
+   //bl    relocate_vectors

 /* Set up final (full) environment */

-   bl  c_runtime_cpu_setup /* we still call old routine here */
+   //bl    c_runtime_cpu_setup /* we still call old routine here */
 #endif
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
 # ifdef CONFIG_SPL_BUILD
@@ -138,6 +152,8 @@
    movne   sp, r0
    movne   r9, r0
 # endif
+
+#if 0
    ldr r0, =__bss_start    /* this is auto-relocated! */

 #ifdef CONFIG_USE_ARCH_MEMSET
@@ -158,6 +174,7 @@
    addlo   r0, r0, #4      /* move to next */
    blo clbss_l
 #endif
+#endif

 #if ! defined(CONFIG_SPL_BUILD)
    bl coloured_LED_init

3、修改include/configs/smdk2440.h

diff -urN u-boot-2016.11/include/configs/smdk2440.h u-boot-2016.11_s3c2440/include/configs/smdk2440.h
--- u-boot-2016.11/include/configs/smdk2440.h   2018-06-15 00:00:40.163660155 +0800
+++ u-boot-2016.11_s3c2440/include/configs/smdk2440.h   2018-06-15 15:34:23.276500000 +0800
@@ -21,7 +21,7 @@
 #define CONFIG_S3C2440     /* specifically a SAMSUNG S3C2440 SoC */
 #define CONFIG_SMDK2440        /* on a SAMSUNG SMDK2440 Board */

-#define CONFIG_SYS_TEXT_BASE   0x0
+#define CONFIG_SYS_TEXT_BASE   0x33f00000

 #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH

4、修改board/samsung/smdk2440/Makefile将我们之前增加的init.c编译进来

diff -urN u-boot-2016.11/board/samsung/smdk2440/Makefile u-boot-2016.11_s3c2440/board/samsung/smdk2440/Makefile
--- u-boot-2016.11/board/samsung/smdk2440/Makefile  2018-06-14 22:37:01.047660155 +0800
+++ u-boot-2016.11_s3c2440/board/samsung/smdk2440/Makefile  2018-06-15 15:31:48.571186000 +0800
@@ -7,3 +7,4 @@

 obj-y  := smdk2440.o
 obj-y  += lowlevel_init.o
+obj-y  += init.o

5、arch/arm/lib/Makefile,将crt0.c和vectors.c单独编译,不要链接到built-in.o

diff -urN u-boot-2016.11/arch/arm/lib/Makefile u-boot-2016.11_s3c2440/arch/arm/lib/Makefile
--- u-boot-2016.11/arch/arm/lib/Makefile    2016-11-15 00:27:11.000000000 +0800
+++ u-boot-2016.11_s3c2440/arch/arm/lib/Makefile    2018-06-15 15:33:21.169461998 +0800
@@ -14,7 +14,8 @@
 else ifdef CONFIG_ARM64
 obj-y  += crt0_64.o
 else
-obj-y  += vectors.o crt0.o
+#obj-y += vectors.o crt0.o
+extra-y    += vectors.o crt0.o
 endif

 ifndef CONFIG_SPL_BUILD

6、修改arch/arm/cpu/u-boot.lds,保证代码拷贝函数在4K之前

diff -urN u-boot-2016.11/arch/arm/cpu/u-boot.lds u-boot-2016.11_s3c2440/arch/arm/cpu/u-boot.lds
--- u-boot-2016.11/arch/arm/cpu/u-boot.lds  2016-11-15 00:27:11.000000000 +0800
+++ u-boot-2016.11_s3c2440/arch/arm/cpu/u-boot.lds  2018-06-15 15:36:11.246458000 +0800
@@ -44,6 +44,9 @@
        *(.__image_copy_start)
        *(.vectors)
        CPUDIR/start.o (.text*)
+       arch/arm/lib/crt0.o (.text*)
+       arch/arm/lib/vectors.o (.text*)
+       board/samsung/smdk2440/built-in.o (.text*)
        *(.text*)
    }

7、分析反汇编文件看nand的初始化和代码的拷贝函数是否小于4kB

book@ubuntu:~/u-boot-2016.11$ ./auto_run.sh  
book@ubuntu:~/u-boot-2016.11$ arm-linux-objdump -D u-boot > u-boot.dis  
book@ubuntu:~/u-boot-2016.11$ gedit u-boot.dis
查找nand_init_ll可以看到text段的地址为33f00650~33f00664  
...  
33f00650 <nand_init_ll>:  
33f00650:<span style="white-space:pre;">    </span>e3a0344e <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>r3, #1308622848<span style="white-space:pre;">   </span>; 0x4e000000  
33f00654:<span style="white-space:pre;">    </span>e3a02c01 <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>r2, #256<span style="white-space:pre;">  </span>; 0x100  
33f00658:<span style="white-space:pre;">    </span>e5832000 <span style="white-space:pre;"> </span>str<span style="white-space:pre;">   </span>r2, [r3]  
33f0065c:<span style="white-space:pre;">    </span>e3a02013 <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>r2, #19<span style="white-space:pre;">   </span>; 0x13  
33f00660:<span style="white-space:pre;">    </span>e5832004 <span style="white-space:pre;"> </span>str<span style="white-space:pre;">   </span>r2, [r3, #4]  
33f00664:<span style="white-space:pre;">    </span>e12fff1e <span style="white-space:pre;"> </span>bx<span style="white-space:pre;">    </span>lr  
...  

继续查找copy_code_to_sdram可以看到text段大的地址为33f00840~33f00894  
...  
33f00840 <copy_code_to_sdram>:  
33f00840:<span style="white-space:pre;">    </span>e59fc04c <span style="white-space:pre;"> </span>ldr<span style="white-space:pre;">   </span>ip, [pc, #76]<span style="white-space:pre;"> </span>; 33f00894 <copy_code_to_sdram+0x54>  
33f00844:<span style="white-space:pre;">    </span>e92d40f0 <span style="white-space:pre;"> </span>push<span style="white-space:pre;">  </span>{r4, r5, r6, r7, lr}  
33f00848:<span style="white-space:pre;">    </span>e3a04000 <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>r4, #0<span style="white-space:pre;">    </span>; 0x0  
33f0084c:<span style="white-space:pre;">    </span>e5945000 <span style="white-space:pre;"> </span>ldr<span style="white-space:pre;">   </span>r5, [r4]  
33f00850:<span style="white-space:pre;">    </span>e584c000 <span style="white-space:pre;"> </span>str<span style="white-space:pre;">   </span>ip, [r4]  
33f00854:<span style="white-space:pre;">    </span>e5943000 <span style="white-space:pre;"> </span>ldr<span style="white-space:pre;">   </span>r3, [r4]  
33f00858:<span style="white-space:pre;">    </span>e153000c <span style="white-space:pre;"> </span>cmp<span style="white-space:pre;">   </span>r3, ip  
33f0085c:<span style="white-space:pre;">    </span>e1a07000 <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>r7, r0  
33f00860:<span style="white-space:pre;">    </span>e1a0c002 <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>ip, r2  
33f00864:<span style="white-space:pre;">    </span>e1a06001 <span style="white-space:pre;"> </span>mov<span style="white-space:pre;">   </span>r6, r1  
33f00868:<span style="white-space:pre;">    </span>11a02004 <span style="white-space:pre;"> </span>movne<span style="white-space:pre;"> </span>r2, r4  
33f0086c:<span style="white-space:pre;">    </span>1a000005 <span style="white-space:pre;"> </span>bne<span style="white-space:pre;">   </span>33f00888 <copy_code_to_sdram+0x48>  
33f00870:<span style="white-space:pre;">    </span>e5845000 <span style="white-space:pre;"> </span>str<span style="white-space:pre;">   </span>r5, [r4]  
33f00874:<span style="white-space:pre;">    </span>e8bd40f0 <span style="white-space:pre;"> </span>pop<span style="white-space:pre;">   </span>{r4, r5, r6, r7, lr}  
33f00878:<span style="white-space:pre;">    </span>eaffff87 <span style="white-space:pre;"> </span>b<span style="white-space:pre;"> </span>33f0069c <nand_read_ll>  
33f0087c:<span style="white-space:pre;">    </span>e7d73002 <span style="white-space:pre;"> </span>ldrb<span style="white-space:pre;">  </span>r3, [r7, r2]  
33f00880:<span style="white-space:pre;">    </span>e7c63002 <span style="white-space:pre;"> </span>strb<span style="white-space:pre;">  </span>r3, [r6, r2]  
33f00884:<span style="white-space:pre;">    </span>e2822001 <span style="white-space:pre;"> </span>add<span style="white-space:pre;">   </span>r2, r2, #1<span style="white-space:pre;">    </span>; 0x1  
33f00888:<span style="white-space:pre;">    </span>e152000c <span style="white-space:pre;"> </span>cmp<span style="white-space:pre;">   </span>r2, ip  
33f0088c:<span style="white-space:pre;">    </span>3afffffa <span style="white-space:pre;"> </span>bcc<span style="white-space:pre;">   </span>33f0087c <copy_code_to_sdram+0x3c>  
33f00890:<span style="white-space:pre;">    </span>e8bd80f0 <span style="white-space:pre;"> </span>pop<span style="white-space:pre;">   </span>{r4, r5, r6, r7, pc}  
33f00894:<span style="white-space:pre;">    </span>12345678 <span style="white-space:pre;"> </span>.word<span style="white-space:pre;"> </span>0x12345678  
...  
我们拷贝代码的基地址为33f00000,所以33f00894-33f00000=894(16)=2196(10)<4096=4KB

8、烧写u-boot.bin到Nand Flash上并启动

book@ubuntu:~/u-boot-2016.11$ ./auto_run.sh  

这里写图片描述
到这里初步可以用Nand Flash启动u-boot了

猜你喜欢

转载自blog.csdn.net/david_linux/article/details/80709986