平台:jz2440
作者:庄泽彬(欢迎转载,请注明作者)
说明:韦东山二期视频学习笔记
交叉编译工具:arm-linux-gcc (GCC)4.3.2
PC环境:ubuntu18.04
一、uboot的编译和烧录
下载uboot-2012-04版本的uboot进行移植,下载链接:ftp://ftp.denx.de/pub/u-boot/
编译:
make smdk2410_config
make -j4
使用oflash进行烧录,注意要烧录到norflash进行启动,不能烧录到nandflash启动:
sudo oflash u-boot.bin
使用没有修改的uboo2012-04版本烧录启动肯定不能启动,要进行修改,支持jz2440
二、uboot的启动流程
在进行移植之前,我们要先了解uboot的启动流程,才能快速的移植。根据编译过程,看看是那些文件先编译,在uboot启动阶段最先执行.
根据下图编译的log,和链接器脚本可知,arch/arm/cpu/arm920t/start.c 是最先执行的,并且链接地址为0。
根据start.c分析uboot主要内容如下:
2.1 set the cpu to SVC32 mode 设置为管理模式
2.2 turn off the watchdog 关闭看门狗
2.3 mask all IRQs by setting all bits in the INTMR
2.4 设置时钟比例: FCLK:HCLK:PCLK = 1:2:4
2.5 设置内存控制器
2.6 设置栈,调用board_init_f进行初始化
2.6.1 设置栈指针地址sp = 0x30000f80
2.6.2 设置gd变量
DECLARE_GLOBAL_DATA_PTR
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
ffixed-r8
指定r8寄存器来存放gd变量的地址
2.7 重定位代码:
为什么要重定位代码呢?norflash的全局变量能像内存一样读,但是不能像内存一样写,从这一点出发也需要把代码进行重定位,重定位之后,还要修改代码,修改里面的变量,函数使用新的地址.
在链接的时候添加pie选项,会把地址信息存放在.rel和dynsym段中。arm-linux-ld -pie
查看链接脚本中也有这两个段:
最终的sdram内存分布如下图:
三、uboot重定位分析
3.1 从NOR Flash 把代码复制到sdram(源码:u-boot-2012.04.01\arch\arm\cpu\arm920t\start.S)
/* Set up the stack */
stack_setup:
mov sp, r4 adr r0, _start
cmp r0, r6
beq clear_bss /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy_loop */
ldr r3, _bss_start_ofs
add r2, r0, r3 /* r2 <- source end address */ copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop
3.2 程序的链接地址是0,访问全局变量、静态变量、调用函数时是基于0地址编译得到的地址,现在把程序复制到了sdram,需要修改代码,把基于0地址编译得到的地址改为新地址
分析"重定位之修改代码为新地址":
#ifndef CONFIG_SPL_BUILD
/*
* fix .rel.dyn relocations
*/
ldr r0, _TEXT_BASE /* r0 <- Text base */
// r0=0, 代码基地址 sub r9, r6, r0 /* r9 <- relocation offset */
// r9 = r6-r0 = 0x33f41000 - 0 = 0x33f41000 ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
// r10 = 00073608 add r10, r10, r0 /* r10 <- sym table in FLASH */
// r10 = 00073608 + 0 = 00073608 ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
// r2=0006b568 add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
// r2=r2+r0=0006b568 ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
// r3=00073608 add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
// r3=r3+r0=00073608 fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
. r0=[0006b568]= add r0, r0, r9 /* r0 <- location to fix up in RAM */
. r0=r0+r9= + 0x33f41000 = 0x33f41020 ldr r1, [r2, #]
. r1=[0006b568+]= and r7, r1, #0xff
. r7=r1&0xff= cmp r7, # /* relative fixup? */
. r7 == (0x17) beq fixrel
cmp r7, # /* absolute fixup? */ beq fixabs
/* ignore unknown type of fixup */
b fixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
mov r1, r1, LSR # /* r1 <- symbol index in .dynsym */ add r1, r10, r1 /* r1 <- address of symbol in table */ ldr r1, [r1, #] /* r1 <- symbol value */ add r1, r1, r9 /* r1 <- relocated sym addr */ b fixnext
fixrel:
/* relative fix: increase location by offset */
ldr r1, [r0]
. r1=[]=000001e0 add r1, r1, r9
. r1=r1+r9=000001e0 + 0x33f41000 = 33F411E0 fixnext:
str r1, [r0]
. [0x33f41020] = 33F411E0 add r2, r2, # /* each rel.dyn entry is 8 bytes */
. r2=r2+=0006b568+=6B570 cmp r2, r3
. blo fixloop
#endif
3.3 调用clear_bss
3.4 调用C函数board_init_r:第2阶段的代码
四、修改uboot代码--新建单板、修改系统时钟、串口
4.1 新建新的单板
4.2修改系统时钟、支持串口显示:
uboot代码里先以60Mhz时钟计算参数来设置内存控制器,但是还没有设置MPLL
cpu_init_crit
| |
| lowlevel_init 对内存的初始化,要求HCLK=60Mhz,但是时钟的设置在初始化内存之后,这部分代码有问题需要调整
|
board_init_f
|
init_sequence
|
board_early_init_f
/* to reduce PLL lock time, adjust the LOCKTIME register */
writel(0xFFFFFF, &clk_power->locktime);
/* configure MPLL */
writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,&clk_power->mpllcon);
使用openjtag调试,根据下面调试的内容可知,无法往sdram写入数据,这部分的初始化需要调整
代码修改如下:
zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$ git diff .
diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S
index 8c5612c..8655eca
--- a/arch/arm/cpu/arm920t/start.S
+++ b/arch/arm/cpu/arm920t/start.S
@@ -, +, @@ copyex: /* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
- ldr r0, =CLKDIVN
- mov r1, #
- str r1, [r0]
+ /* 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, , r1, c1, c0, /* 读出控制寄存器 */
+ orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
+ mcr p15, , r1, c1, c0, /* 写入控制寄存器 */
+
+ #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, , r0, c1, c0, @ read control reg
+ orr r0, r0, #(<<)
+ mcr p15, , r0, c1, c0, @ write it back
+
+
#endif /* CONFIG_S3C24X0 */ /*
diff --git a/board/samsung/smdk2440/lowlevel_init.S b/board/samsung/smdk2440/lowlevel_init.S
index a2bf570..c14cab3 100644
--- a/board/samsung/smdk2440/lowlevel_init.S
+++ b/board/samsung/smdk2440/lowlevel_init.S
@@ -152,16 +152,16 @@ lowlevel_init:
/* the literal pools origin */ SMRDATA:
- .word (+(B1_BWSCON<<)+(B2_BWSCON<<)+(B3_BWSCON<<)+(B4_BWSCON<<)+(B5_BWSCON<<)+(B6_BWSCON<<)+(B7_BWSCON<<))
- .word ((B0_Tacs<<)+(B0_Tcos<<)+(B0_Tacc<<)+(B0_Tcoh<<)+(B0_Tah<<)+(B0_Tacp<<)+(B0_PMC))
- .word ((B1_Tacs<<)+(B1_Tcos<<)+(B1_Tacc<<)+(B1_Tcoh<<)+(B1_Tah<<)+(B1_Tacp<<)+(B1_PMC))
- .word ((B2_Tacs<<)+(B2_Tcos<<)+(B2_Tacc<<)+(B2_Tcoh<<)+(B2_Tah<<)+(B2_Tacp<<)+(B2_PMC))
- .word ((B3_Tacs<<)+(B3_Tcos<<)+(B3_Tacc<<)+(B3_Tcoh<<)+(B3_Tah<<)+(B3_Tacp<<)+(B3_PMC))
- .word ((B4_Tacs<<)+(B4_Tcos<<)+(B4_Tacc<<)+(B4_Tcoh<<)+(B4_Tah<<)+(B4_Tacp<<)+(B4_PMC))
- .word ((B5_Tacs<<)+(B5_Tcos<<)+(B5_Tacc<<)+(B5_Tcoh<<)+(B5_Tah<<)+(B5_Tacp<<)+(B5_PMC))
- .word ((B6_MT<<)+(B6_Trcd<<)+(B6_SCAN))
- .word ((B7_MT<<)+(B7_Trcd<<)+(B7_SCAN))
- .word ((REFEN<<)+(TREFMD<<)+(Trp<<)+(Trc<<)+(Tchr<<)+REFCNT)
- .word 0x32
- .word 0x30
- .word 0x30
+.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
diff --git a/board/samsung/smdk2440/smdk2410.c b/board/samsung/smdk2440/smdk2410.c
index e9ba922..44f38d1
--- a/board/samsung/smdk2440/smdk2410.c
+++ b/board/samsung/smdk2440/smdk2410.c
@@ -, +, @@ int board_early_init_f(void)
struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); /* to reduce PLL lock time, adjust the LOCKTIME register */
- writel(0xFFFFFF, &clk_power->locktime);
+ //writel(0xFFFFFF, &clk_power->locktime); /* configure MPLL */
- writel((M_MDIV << ) + (M_PDIV << ) + M_SDIV,
- &clk_power->mpllcon);
+ //writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
+ // &clk_power->mpllcon); /* some delay between MPLL and UPLL */
pll_delay();
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index 7d16320..71336c7
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@
*/
#define CONFIG_ARM920T /* This is an ARM920T Core */
#define CONFIG_S3C24X0 /* in a SAMSUNG S3C24x0-type SoC */
-#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
+//#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
+#define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2410 SoC */
#define CONFIG_SMDK2410 /* on a SAMSUNG SMDK2410 Board */ #define CONFIG_SYS_TEXT_BASE 0x0
@@ -, +, @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
-#define CONFIG_CMD_NAND
+//#define CONFIG_CMD_NAND
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_USB
@@ -, +, @@
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
-#define CONFIG_YAFFS2
+//#define CONFIG_YAFFS2
#define CONFIG_RBTREE /* additions for new relocation code, must be added to all boards */
编译和烧录查看现在结果,现在串口起码可以输出了啊:
五、支持nandflash启动
原来的代码在链接时加了“-pie选项”,使得u-boot.bin里多了rel、dynsym段,这两个段主要是重定位之后修改成新的地址使用的,使用这种方式代码相对会比较大。
5.1 去掉-pie选项,修改如下:
代码修改支持nandflash主要如下:
zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$ git diff .
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 3c5f987..cca02b3
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -, +, @@ endif # needed for relocation
ifndef CONFIG_NAND_SPL
-LDFLAGS_u-boot += -pie
+#LDFLAGS_u-boot += -pie
endif
diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S
index 8655eca..34f7da8
--- a/arch/arm/cpu/arm920t/start.S
+++ b/arch/arm/cpu/arm920t/start.S
@@ -, +, @@ copyex:
bl cpu_init_crit
#endif -/* Set stackpointer in internal RAM to call board_init_f */
-call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, # /* 8-byte alignment for ABI compliance */
+
+ bl nand_init_ll
+ mov r0,#
+ ldr r1,_TEXT_BASE
+
+ ldr r2,_bss_start_ofs
+
+ 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 -/*------------------------------------------------------------------------------*/
-
-/*
- * void relocate_code (addr_sp, gd, addr_moni)
- *
- * This "function" does not return, instead it continues in RAM
- * after relocating the monitor code.
- *
- */
- .globl relocate_code
-relocate_code:
- mov r4, r0 /* save addr_sp */
- mov r5, r1 /* save addr of gd */
- mov r6, r2 /* save addr of destination */
-
- /* Set up the stack */
-stack_setup:
- mov sp, r4
-
- adr r0, _start
- cmp r0, r6
- beq clear_bss /* skip relocation */
- mov r1, r6 /* r1 <- scratch for copy_loop */
- ldr r3, _bss_start_ofs
- add r2, r0, r3 /* r2 <- source end address */
-
-copy_loop:
- ldmia r0!, {r9-r10} /* copy from source address [r0] */
- stmia r1!, {r9-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end address [r2] */
- blo copy_loop
-
-#ifndef CONFIG_SPL_BUILD
- /*
- * fix .rel.dyn relocations
- */
- ldr r0, _TEXT_BASE /* r0 <- Text base */
- sub r9, r6, r0 /* r9 <- relocation offset */
- ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
- add r10, r10, r0 /* r10 <- sym table in FLASH */
- ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
- add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
- ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
- add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
-fixloop:
- ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
- add r0, r0, r9 /* r0 <- location to fix up in RAM */
- ldr r1, [r2, #]
- and r7, r1, #0xff
- cmp r7, # /* relative fixup? */
- beq fixrel
- cmp r7, # /* absolute fixup? */
- beq fixabs
- /* ignore unknown type of fixup */
- b fixnext
-fixabs:
- /* absolute fix: set location to (offset) symbol value */
- mov r1, r1, LSR # /* r1 <- symbol index in .dynsym */
- add r1, r10, r1 /* r1 <- address of symbol in table */
- ldr r1, [r1, #] /* r1 <- symbol value */
- add r1, r1, r9 /* r1 <- relocated sym addr */
- b fixnext
-fixrel:
- /* relative fix: increase location by offset */
- ldr r1, [r0]
- add r1, r1, r9
-fixnext:
- str r1, [r0]
- add r2, r2, # /* each rel.dyn entry is 8 bytes */
- cmp r2, r3
- blo fixloop
-#endif
+ ldr r1,_TEXT_BASE -clear_bss:
-#ifndef CONFIG_SPL_BUILD
- ldr r0, _bss_start_ofs
- ldr r1, _bss_end_ofs
- mov r4, r6 /* reloc addr */
- add r0, r0, r4
- add r1, r1, r4
- mov r2, #0x00000000 /* clear */
-
-clbss_l:str r2, [r0] /* clear loop... */
- add r0, r0, #
- cmp r0, r1
- bne clbss_l
-
- bl coloured_LED_init
- bl red_led_on
-#endif
+ //second action
+ bl board_init_r /*
* We are done. Do not return, instead branch to second part of board
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index e49ca0c..ba20982 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -35,6 +35,7 @@ SECTIONS
{
__image_copy_start = .;
CPUDIR/start.o (.text)
+ board/samsung/smdk2440/libsmdk2440.o (.text)
*(.text)
} diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 5270c11..afafe7b 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -256,7 +256,7 @@ init_fnc_t *init_sequence[] = {
NULL,
}; -void board_init_f(ulong bootflag)
+unsigned int board_init_f(ulong bootflag)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
@@ -369,8 +369,9 @@ void board_init_f(ulong bootflag)
* reserve memory for U-Boot code, data & bss
* round down to next 4 kB limit
*/
- addr -= gd->mon_len;
- addr &= ~( - );
+ //addr -= gd->mon_len;
+ //addr &= ~(4096 - 1);
+ addr = CONFIG_SYS_TEXT_BASE; debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> , addr); @@ -, +, @@ void board_init_f(ulong bootflag)
debug("relocation Offset is: %08lx\n", gd->reloc_off);
memcpy(id, (void *)gd, sizeof(gd_t)); - relocate_code(addr_sp, id, addr);
+ //relocate_code(addr_sp, id, addr); + return (unsigned int )id;
+
/* NOTREACHED - relocate_code() does not return */
} diff --git a/board/samsung/smdk2440/Makefile b/board/samsung/smdk2440/Makefile
index b8657b4..04d36b3
--- a/board/samsung/smdk2440/Makefile
+++ b/board/samsung/smdk2440/Makefile
@@ -, +, @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).o -COBJS := smdk2410.o
+COBJS := smdk2410.o init.o
SOBJS := lowlevel_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/include/common.h b/include/common.h
index 4b5841e..390ab72
--- a/include/common.h
+++ b/include/common.h
@@ -, +, @@ int abortboot(int bootdelay);
extern char console_buffer[]; /* arch/$(ARCH)/lib/board.c */
-void board_init_f (ulong) __attribute__ ((noreturn));
+unsigned int board_init_f(ulong) ;
void board_init_r (gd_t *, ulong) __attribute__ ((noreturn));
int checkboard (void);
int checkflash (void);
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index 71336c7..b638eb4
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@
#define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2410 SoC */
#define CONFIG_SMDK2410 /* on a SAMSUNG SMDK2410 Board */ -#define CONFIG_SYS_TEXT_BASE 0x0
+#define CONFIG_SYS_TEXT_BASE 0x33f00000 #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$
添加了一个文件:board/samsung/smdk2440/init.c这里封装了nandflash初始化等操作,nand_init_ll、copy_code_to_sdram,由于我们在start.S文件中重定位了代码,因此不需要在arch/arm/lib/board.c中要去掉重定位的操作relocate_code。
这个值CONFIG_SYS_TEXT_BASE为什么要设置为0x33f00000,这个值是程序链接的大小,bin文件的大小只有300多k,但是没有包含bss等段,
反汇编查看文件的大小:0x00094b40的十进制是600多k,因此设置的CONFIG_SYS_TEXT_BASE我们设置为1M(设置大一点比较安全),我们的sdram的末端地址为0x34000000,0x3400000-0x33f00000=1M
arm-linux-objdump -D u-boot > u-boot.dis
编译烧录,开发板设置为nandflash启动,根据下图nandflash启动还是可以输出之前的log,设置成nandflash启动的代码修改暂时没有问题,其余的bug后续修复.
六、支持norflash:
首先我们来看看代码为什么会打印 Flash:*** failed ***,norflash会调用这个进行初始化flash_init,如果初始化失败,则会卡在hang中无法执行,我们打开了调试信息之后,其实是识别出来norflash的,但是为什么会初始化失败是由于jedec_table这个数组没有添加我们norflash的型号导致的。
Board.c (arch\arm\lib)
flash_init
flash_detect_legacy
jedec_flash_match
jedec_table //根据这个数组匹配有没有相应的norflash型号
|
|success
|------
|
|failed
|-----puts(failed);
|
|-----hang();norflash初始化失败则会卡在这里
代码修改如下:
zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$ git diff .
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index afafe7b..b8c17ae
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -, +, @@ void board_init_r(gd_t *id, ulong dest_addr)
print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else {
- puts(failed);
- hang();
+ puts("0 KB\r\n");
+ //puts(failed);
+ //hang();
}
#endif diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 35294bc..295003e
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -, +, @@
#include <mtd/cfi_flash.h>
#include <watchdog.h> +//#define DEBUG 1
+//#define _DEBUG 1
+
/*
* This file implements a Common Flash Interface (CFI) driver for
* U-Boot.
diff --git a/drivers/mtd/jedec_flash.c b/drivers/mtd/jedec_flash.c
index 2350f36..4037ec2 100644
--- a/drivers/mtd/jedec_flash.c
+++ b/drivers/mtd/jedec_flash.c
@@ -367,6 +367,24 @@ static const struct amd_flash_info jedec_table[] = {
}
},
#endif
+ {
+ .mfr_id = (u16)MX_MANUFACT,
+ .dev_id = 0x2249,
+ .name = "MXIC MT29LV160DB",
+ .uaddr = {
+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
+ },
+ .DevSize = SIZE_2MiB,
+ .CmdSet = P_ID_AMD_STD,
+ .NumEraseRegions= ,
+ .regions = {
+ ERASEINFO(*, ),
+ ERASEINFO(*, ),
+ ERASEINFO(*, ),
+ ERASEINFO(*, ),
+ }
+ },
+
}; static inline void fill_info(flash_info_t *info, const struct amd_flash_info *jedec_entry, ulong base)
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index b638eb4..
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@ #define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
-#define CONFIG_SYS_MAX_FLASH_SECT (19)
+#define CONFIG_SYS_MAX_FLASH_SECT (128) #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$
按照上述方式进行修改,编译烧录现象如下,起码norflash初始化不会报错:
在uboot中进行norflash的读写实验,从下图可以看出norflash进行读写的实验基本没有问题,但是在0x3000000会有点问题:
由于之前在第一阶段的时候讲sp设置到了0x30000000,因此在调用函数的时候30000000的数据会变化,我们在第一阶段的时候sp已经重新定义了位置,在第二阶段的时候没有修改sp的指向,因此这里需要重新设置sp的地址:
修改代码如下:
diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S
index 34f7da8..a1876a5
--- a/arch/arm/cpu/arm920t/start.S
+++ b/arch/arm/cpu/arm920t/start.S
@@ -, +, @@ FIQ_STACK_START:
IRQ_STACK_START_IN:
.word 0x0badc0de +.globl base_sp
+base_sp:
+ .long
+
+
/*
* the actual start code
*/
@@ -, +, @@ call_board_init_f:
bl board_init_f ldr r1,_TEXT_BASE
-
+
+ ldr sp,=base_sp
+
//second action
bl board_init_r diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index afafe7b..6cd7352
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -, +, @@ unsigned int board_init_f(ulong bootflag)
init_fnc_t **init_fnc_ptr;
gd_t *id;
ulong addr, addr_sp;
+ extern ulong base_sp;
#ifdef CONFIG_PRAM
ulong reg;
#endif
@@ -, +, @@ unsigned int board_init_f(ulong bootflag)
debug("relocation Offset is: %08lx\n", gd->reloc_off);
memcpy(id, (void *)gd, sizeof(gd_t)); + base_sp = addr_sp;
+
//relocate_code(addr_sp, id, addr);
重新进行norflash的读写实验,在0x3000000读写没有问题.
七、支持nandflash操作:
修改代码如下:
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1d1b628..
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -, +, @@ COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
COBJS-$(CONFIG_NAND_NDFC) += ndfc.o
COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o
COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
+COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
diff --git a/drivers/mtd/nand/s3c2440_nand.c b/drivers/mtd/nand/s3c2440_nand.c
index e1a459b..a0c8876
--- a/drivers/mtd/nand/s3c2440_nand.c
+++ b/drivers/mtd/nand/s3c2440_nand.c
@@ -, +, @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
}
#endif -static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+static void s3c2440_hwcontrol(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
- struct s3c2410_nand *nand = s3c2410_get_base_nand();
-
- debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
-
- if (ctrl & NAND_CTRL_CHANGE) {
- ulong IO_ADDR_W = (ulong)nand;
-
- if (!(ctrl & NAND_CLE))
- IO_ADDR_W |= S3C2410_ADDR_NCLE;
- if (!(ctrl & NAND_ALE))
- IO_ADDR_W |= S3C2410_ADDR_NALE;
+ struct s3c2440_nand *nand = s3c2440_get_base_nand(); - chip->IO_ADDR_W = (void *)IO_ADDR_W;
-
- if (ctrl & NAND_NCE)
- writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
- &nand->nfconf);
- else
- writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
- &nand->nfconf);
+ if (ctrl &NAND_CLE){
+ writeb(dat,&nand->nfcmd);
+ }else if (ctrl &NAND_ALE){
+ writeb(dat,&nand->nfaddr);
}
-
- if (cmd != NAND_CMD_NONE)
- writeb(cmd, chip->IO_ADDR_W);
} -static int s3c2410_dev_ready(struct mtd_info *mtd)
+static int s3c2440_dev_ready(struct mtd_info *mtd)
{
- struct s3c2410_nand *nand = s3c2410_get_base_nand();
+ struct s3c2440_nand *nand = s3c2440_get_base_nand();
debug("dev_ready\n");
return readl(&nand->nfstat) & 0x01;
} +static void s3c2440_nand_select(struct mtd_info *mtd, int chipnr)
+{
+ struct s3c2440_nand *nand = s3c2440_get_base_nand();
+
+ switch (chipnr) {
+ case -:
+ nand->nfcont |= (<<);
+ break;
+ case :
+ nand->nfcont &= ~(<<);
+ break;
+
+ default:
+ BUG();
+ }
+}
+
+
#ifdef CONFIG_S3C2410_NAND_HWECC
void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
- struct s3c2410_nand *nand = s3c2410_get_base_nand();
+ struct s3c2440_nand *nand = s3c2440_get_base_nand();
debug("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf);
}
@@ -, +, @@ int board_nand_init(struct nand_chip *nand)
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();
+ struct s3c2440_nand *nand_reg = s3c2440_get_base_nand(); debug("board_nand_init()\n"); @@ -, +, @@ int board_nand_init(struct nand_chip *nand)
twrph1 = ;
#endif - cfg = S3C2410_NFCONF_EN;
- cfg |= S3C2410_NFCONF_TACLS(tacls - );
- cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - );
- cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - );
+ //cfg = S3C2410_NFCONF_EN;
+ //cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
+ //cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
+ //cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
+ cfg = ((tacls-)<<)|((twrph0-)<<)|((twrph1-)<<);
writel(cfg, &nand_reg->nfconf); + writel((<<)|(<<)|(<<), &nand_reg->nfcont);
+
/* initialize nand_chip data structure */
nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
nand->IO_ADDR_W = (void *)&nand_reg->nfdata; - nand->select_chip = NULL;
+ nand->select_chip = s3c2440_nand_select; /* read_buf and write_buf are default */
/* read_byte and write_byte are default */
@@ -, +, @@ int board_nand_init(struct nand_chip *nand)
#endif /* hwcontrol always must be implemented */
- nand->cmd_ctrl = s3c2410_hwcontrol;
+ nand->cmd_ctrl = s3c2440_hwcontrol; - nand->dev_ready = s3c2410_dev_ready;
+ nand->dev_ready = s3c2440_dev_ready; #ifdef CONFIG_S3C2410_NAND_HWECC
nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index ..6f5710d
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
-//#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NAND
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_USB
@@ -, +, @@
* NAND configuration
*/
#ifdef CONFIG_CMD_NAND
+
+#ifdef CONFIG_S3C2410
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
+#else
+#define CONFIG_NAND_S3C2440
+#define CONFIG_SYS_S3C2440_NAND_HWECC
+#endif
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x4E000000
#endif
使用loady进行烧录,现在串口输入loady 30000000,之后按ctrl+A,之后按s,选择ymodel,选择文件即可使用loady进行烧录
烧录到Norflash
烧录到nandflash:
启动,识别到nandflash:
八、支持DM9000:
根据下图可知uboot支持的是cs8900网卡,我们使用的是DM9000网卡,因此需要把dm9000编译进uboot而不是cs8900,在配置文件添加这个宏CONFIG_DRIVER_DM9000
根据下面的原理图可知DM9000是使用nGCS4作为片选引脚,内存的基地址要设置为0x2000_0000 ,
代码修改如下,BANKCON4用于修改DM9000的时序:
zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$ git diff .
diff --git a/board/samsung/smdk2440/lowlevel_init.S b/board/samsung/smdk2440/lowlevel_init.S
index c14cab3..0adf662
--- a/board/samsung/smdk2440/lowlevel_init.S
+++ b/board/samsung/smdk2440/lowlevel_init.S
@@ -, +, @@ SMRDATA:
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
-.long 0x00000700 //BANKCON4
+.long 0x00000740 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index 6f5710d..780adb7
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@
/*
* Hardware drivers
*/
+ # if
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
+#else
+#define CONFIG_DRIVER_DM9000
+#define CONFIG_DM9000_BASE 0x20000000
+#define DM9000_IO CONFIG_DM9000_BASE
+#define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#endif
/*
* select serial console configuration
*/
编译烧录:现象如下,显示没有找到网卡:
在uboot里网卡初始化流程如下,由于没有修改成DM9000的初始化导致的:
puts("Net: ");
eth_initialize(gd->bd);
|
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
return rc;
}
#endif
代码修改如下:
diff --git a/board/samsung/smdk2440/smdk2410.c b/board/samsung/smdk2440/smdk2410.c
index 44f38d1..b56f8aa
--- a/board/samsung/smdk2440/smdk2410.c
+++ b/board/samsung/smdk2440/smdk2410.c
@@ -, +, @@ int board_eth_init(bd_t *bis)
#ifdef CONFIG_CS8900
rc = cs8900_initialize(, CONFIG_CS8900_BASE);
#endif
+
+#ifdef CONFIG_DRIVER_DM9000
+ rc = dm9000_initialize(bis);
+#endif
+
return rc;
}
#endif
编译烧录现象如下,识别到DM9000,并且ping成功:
使用tftp下载:
安装相关的软件
apt-get install tftp-hpa tftpd-hpa xinetd
修改配置文件:
sudo vim /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"
创建tftp的目录
sudo mkdir /tftpboot
sudo chmod /tftpboot
使用tftp下载内核实验如下,成功下载内核,因此uboot对应dm9000的修改暂时没有问题:
九、修改默认参数以及裁剪uboot
代码修改如下:
zhuang@zhuang:~/project/-jz2440/systems/u-boot-2012.04.$ git diff .
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 6cd7352..634f4c8
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -, +, @@ void board_init_r(gd_t *id, ulong dest_addr)
}
#endif + //mtdparts_init();
+ run_command("mtdparts default",); //在执行mtdpart之前需要运行mtdparts default 进行初始化设置
+
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index bb3f227..709071d
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@
/************************************************************
* USB support (currently only works with D-cache off)
************************************************************/
-#define CONFIG_USB_OHCI
-#define CONFIG_USB_KEYBOARD
-#define CONFIG_USB_STORAGE
-#define CONFIG_DOS_PARTITION
+//#define CONFIG_USB_OHCI //裁剪没有用到的模块
+//#define CONFIG_USB_KEYBOARD
+//#define CONFIG_USB_STORAGE
+//#define CONFIG_DOS_PARTITION /************************************************************
* RTC
************************************************************/
-#define CONFIG_RTC_S3C24X0
+//#define CONFIG_RTC_S3C24X0 #define CONFIG_BAUDRATE 115200
@@ -, +, @@
/*
* BOOTP options
*/
-#define CONFIG_BOOTP_BOOTFILESIZE
-#define CONFIG_BOOTP_BOOTPATH
-#define CONFIG_BOOTP_GATEWAY
-#define CONFIG_BOOTP_HOSTNAME
+//#define CONFIG_BOOTP_BOOTFILESIZE
+//#define CONFIG_BOOTP_BOOTPATH
+//#define CONFIG_BOOTP_GATEWAY
+//#define CONFIG_BOOTP_HOSTNAME /*
* Command line configuration.
@@ -103,13 +103,13 @@ #define CONFIG_CMD_BSP
#define CONFIG_CMD_CACHE
-#define CONFIG_CMD_DATE
-#define CONFIG_CMD_DHCP
+//#define CONFIG_CMD_DATE
+//#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
#define CONFIG_CMD_NAND
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_USB
+//#define CONFIG_CMD_USB #define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
@@ -162,7 +162,7 @@ #define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
-#define CONFIG_BOOTCOMMAND "nand read 30000000 0xabc 0x200000;bootm 30000000"
+#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel 0x200000;bootm 30000000"
#define CONFIG_ETHADDR "00:06:3b:01:41:55"
/*-----------------------------------------------------------------------
* Stack sizes
@@ -200,11 +200,28 @@
#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
#define CONFIG_SYS_MAX_FLASH_SECT (128) +#if 0
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE 0x10000
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
+#endif
+
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET 0x00040000 //设置params分区存放的大小和便宜
+#define CONFIG_ENV_SIZE 0x20000 /* nand blcok size */
+#define CONFIG_ENV_RANGE CONFIG_ENV_SIZE
+
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_MTD_DEVICE
+#define MTDIDS_DEFAULT "nand0=jz2440-0" // which device
+ //mtdparts 命令对nandflash的划分
+#define MTDPARTS_DEFAULT "mtdparts=jz2440-0:256k(u-boot)," \
+ "128k(params)," \
+ "2m(kernel)," \
+ "-(rootfs)"
+ /*
* Size of malloc() pool
@@ -234,6 +251,7 @@
/*
* File system
*/
+ #if 0
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
@@ -, +, @@
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
-//#define CONFIG_YAFFS2
+#define CONFIG_YAFFS2
#define CONFIG_RBTREE
-
+#endif
/* additions for new relocation code, must be added to all boards */
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - \
设置默认的环境变量修改文件include/configs/smdk2440.h
/*
* select serial console configuration
*/
@@ -, +, @@
#define CONFIG_ZERO_BOOTDELAY_CHECK #define CONFIG_NETMASK 255.255.255.0
-#define CONFIG_IPADDR 10.0.0.110
-#define CONFIG_SERVERIP 10.0.0.1
+#define CONFIG_IPADDR 192.168.1.17
+#define CONFIG_SERVERIP 192.168.1.100 #if defined(CONFIG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
@@ -, +, @@
#define CONFIG_LZO
#define CONFIG_LZMA +
+#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
+#define CONFIG_BOOTCOMMAND "nand read 30000000 0xabc 0x200000;bootm 30000000"
+#define CONFIG_ETHADDR "00:06:3b:01:41:55"
/*-----------------------------------------------------------------------
编译烧录,设置默认的环境变量生效:
tftp下载uboot到sdram,解除写保护,擦除分区,从内存拷贝到norflash。
下载内核到nandflash
从nandflash读到sdram并启动
支持mtdpart命令:
利用分区名进行烧录,擦除等操作
十、uboot支持jffs2文件系统烧录,默认支持jffs2文件系统烧录
支持yaffs2文件系统,代码修改如下:
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
old mode
new mode
index 60c778e..f9c4a88
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -, +, @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
return -EINVAL;
} - if (!need_skip && !(flags & WITH_DROP_FFS)) {
+ if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {
rval = nand_write (nand, offset, length, buffer);
if (rval == )
return ;
@@ -, +, @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, ops.len = pagesize;
ops.ooblen = nand->oobsize;
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OOB_RAW;
ops.ooboffs = ; pages = write_size / pagesize_oob;
@@ -, +, @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
ops.oobbuf = ops.datbuf + pagesize; rval = nand->write_oob(nand, offset, &ops);
- if (!rval)
+ if (rval)
break; offset += pagesize;
diff --git a/include/configs/smdk2440.h b/include/configs/smdk2440.h
index 709071d..dc25330
--- a/include/configs/smdk2440.h
+++ b/include/configs/smdk2440.h
@@ -, +, @@
#define CONFIG_LZO
#define CONFIG_LZMA -
+#define CONFIG_CMD_NAND_YAFFS
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel 0x200000;bootm 30000000"
#define CONFIG_ETHADDR "00:06:3b:01:41:55"
更新uboot
烧录yaffs文件系统
使用yaffs文件系统启动Ok