(一)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了