U-boot-2014.10移植到TQ2416开发板之NandFlash启动探究

****************************************************************************************************

硬件平台:TQ2416

软件平台:U-boot-2014.10

记录日期:2015-07-09

调试工具:H-Jtag、J-link结合

文档记录:该文档属于移植U-boot-2014.10到TQ2416板对s3c2416的探究记录

其他备注:

1.TQ2416的开发板上用到的nandflash的H-JTAG文件,我会在文章最后放出

2.H-Jtag(只用来烧bin到nandflash)

3.J-link(调试我们的bin格式的程序,怎么调试最后说)

****************************************************************************************************

主题:探究s3c2416处理器的nandflash 启动模式 (非IROM方式)


1.首先了解下三星官方给出的s3c2416的启动模式描述



上面的黄颜色标注的地方,是我根据TQ2416的开发板硬件连接所确定的nandflash启动(非IROM模式) ,IROM启动OM[4:0]比较简单,只要设置OM[4:0]=0100x,但还需要GPC5/6/7这三个引脚的不同配置来配合选择启动设备,这里不讨论


Nand Boot 方式根据三星官方对s3c2416的启动描述中,(其实,nand boot这种方式,三星已经不推荐使用)其启动过程大致描述是这样,稍微总结一下:

1)首先,s3c2416的内部有一块SRAM(又被称之为Stepingstone,也就三星有这玩意,也就是它支撑着nand boot),Nand Boot启动的时候,前8KB的nandflash(s3c2410和s3c2440貌似只有4KB)存储将会被加载到Stepingstone,有且只会有8KB。

2)由于arm的处理器,在上电的时候总是从0x00000000地址开始运行,上面的这一块SRAM(Stepingstone)便被映射到了0x00000000地址上(这是自动映射的,不需要程序开发人员在程序中映射什么的,只要你对OM[4:0]的设置是以nand boot方式,系统上电便会自动的映射SRAM到0x00000000地址上),然后系统便从SRAM中开始执行你的这8K程序。

3)既然我们已经知道了,只要设置启动方式为nand boot模式,那么0x00000000地址就被映射了8kb的sram,就应该可以直接运行我们的一些demo,是不是这样,我们验证一下


*********************上面理论讲完了 下面来点代码验证下刚才的猜想**************************************

代码我放在了我的github上托管了,下面给出链接

https://github.com/lu-mingliang/TQ2416-led/

led.S

@@ -0,0 +1,176 @@
/*
 *	@Hardware: TQ2416	
 *	@software: ubuntu-12.04
 *	@author	 : <mingllu@163.com>
 *	@date    : 2015-07-09
 *	@filename: led.S
 */

#include "led.h"

	.text 
	.align 2 
	.global _start 

_start:
	/* set cpu s3v32 mode */
	mrs r0, cpsr
	bic r0, r0, #0x1f
	orr r0, r0, #0xd3
	msr cpsr, r0 

	/* disable WATCHDOG*/
	ldr r0, =ELFIN_WATCHDOG_BASE
	mov r1, #0
	str r1,[r0]

	/* disable IRQ & FIQ*/
	ldr r0, =ELFIN_INTERRUPT_BASE
	mov r1, #0xffffffff
	str r1, [r0, #INTMSK_OFFSET]
	str r1, [r0, #INTMSK2_OFFSET]
	str r1, [r0, #INTSUBMSK_OFFSET]

	mov r0, #0
	mcr p15, 0, r0, c7, c7, 0 /* invalidate TLB*/
	mcr p15, 0, r0, c8, c7, 0 /* flush V4 TLB */

	/* disable MMU & Cache */
	mrc	p15, 0, r0, c1, c0, 0 
	bic r0, r0, #0x00002300
	bic r0, r0, #0x00000087
	orr r0, r0, #0x00000002
	orr r0, r0, #0x00001000
	mcr	p15, 0, r0, c1, c0, 0 

	/* init system_clock */
	bl system_clock_init

	/* gpio init */
	bl gpio_asm_init

	b led


/*
 *	@system_clock_init 
 *	@description: |init MPLL EPLL 
 *				  |--ARMCLK 400M 
 *				  |--HCLK 	133M
 *				  |--PCLK 	96M	
 */
system_clock_init:
	ldr r0, =ELFIN_CLOCK_POWER_BASE

	@set CLKDIV0 
	ldr r1, =( (1 << 0) | (1 << 2) | (1 << 3) | (2 << 4) | (1 << 9) )
	str r1, [r0, #CLKDIV0CON_OFFSET]

	@set CLKDIV1
	ldr r1, =( (0 << 4) | (3 << 6) | (0 << 8) | (0 << 12) | (0 << 16)  | ( 0 << 24) )
	str r1, [r0, #CLKDIV1CON_OFFSET]

	@set MPLL Locktime 
	ldr r1, =3600
	str r1, [r0, #LOCKCON0_OFFSET]

	@set MPLL_VAL
	ldr r1, =( (1 << 0) | (3 << 5) | (400 << 14) | (0 << 24) | (0 << 25) )
	str r1, [r0, #MPLLCON_OFFSET]

	@set EPLL Locktime
	ldr r1, =3600
	str r1, [r0, #LOCKCON1_OFFSET]

	@set EPLL_VAL 
	ldr r1, =( (2 << 0) | (1 << 8) | (32 << 16) | (0 << 24) | (0 << 25) )
	str r1, [r0, #EPLLCON_OFFSET]

	@select clock source 
	ldr r1, [r0, #CLKSRCCON_OFFSET] 
	orr r1, r1, #((1 << 4) | ( 1 << 6))
	str r1, [r0, #CLKSRCCON_OFFSET]

	/* wait at least 200us to stablize all clock */ 

	ldr r1, =10000
1:	subs r1, r1, #1
	bne 1b 
	
	mov pc, lr 

sdram_asm_init:

	mov r10, lr	

	mov pc, r10 	

gpio_asm_init:
	ldr r0, =ELFIN_GPIO_BASE 

	@GPB5~GPB6:led1~led2
	ldr r2, [r0, #GPBCON_OFFSET] 
	bic r2, #(0xf < 10)
	orr r2, r2, #(5 << 10)
	str r2, [r0, #GPBCON_OFFSET]

	@GPA23~GPA24:led3~led4
	ldr r2, [r0, #GPACON_OFFSET] 
	bic r2, #(0x3 < 23)
	str r2, [r0, #GPACON_OFFSET]

	mov pc, lr

led:
	ldr r0, =ELFIN_GPIO_BASE  

	ldr r1, [r0, #GPBDAT_OFFSET] 
	ldr r2, [r0, #GPADAT_OFFSET]
	bic r1, r1, #(1 << 5)
	orr r1, r1, #(1 << 6)
	orr r2, r2, #(3 << 23)
	str r1, [r0, #GPBDAT_OFFSET]
	str r2, [r0, #GPADAT_OFFSET]

	ldr r3, =50000000 
1:	subs r3, r3, #1
	bne 1b 

	ldr r1, [r0, #GPBDAT_OFFSET] 
	ldr r2, [r0, #GPADAT_OFFSET]
	bic r1, r1, #(1 << 6)
	orr r1, r1, #(1 << 5)
	orr r2, r2, #(3 << 23)
	str r1, [r0, #GPBDAT_OFFSET]
	str r2, [r0, #GPADAT_OFFSET] 

	ldr r3, =50000000 
1:	subs r3, r3, #1
	bne 1b  

	ldr r1, [r0, #GPBDAT_OFFSET] 
	ldr r2, [r0, #GPADAT_OFFSET]
	bic r1, r1, #(1 << 23)
	orr r1, r1, #(1 << 24)
	orr r2, r2, #(3 << 5)
	str r1, [r0, #GPADAT_OFFSET]
	str r2, [r0, #GPBDAT_OFFSET] 

	ldr r3, =50000000 
1:	subs r3, r3, #1
	bne 1b 

	ldr r1, [r0, #GPBDAT_OFFSET] 
	ldr r2, [r0, #GPADAT_OFFSET]
	bic r1, r1, #(1 << 24)
	orr r1, r1, #(1 << 23)
	orr r2, r2, #(3 << 5)
	str r1, [r0, #GPADAT_OFFSET]
	str r2, [r0, #GPBDAT_OFFSET]

	ldr r3, =50000000 
1:	subs r3, r3, #1
	bne 1b  

	b led

led.h

/*
 *	header file for s3c2416 
 *
 */

/*
 * Watchdog timer
 */
#define ELFIN_WATCHDOG_BASE	0x53000000

/*
 * Interrupt
 */
#define ELFIN_INTERRUPT_BASE	0x4a000000

#define INTMSK_OFFSET		0x08 
#define INTMSK2_OFFSET		0x48
#define INTSUBMSK_OFFSET	0x1c
#define INTMOD_OFFSET		0x04 

/*
 * Clock and power management
 */
#define ELFIN_CLOCK_POWER_BASE	0x4c000000 
/* Clock & Power Controller */
#define LOCKCON0_OFFSET		0x00
#define LOCKCON1_OFFSET		0x04
#define OSCSET_OFFSET		0x08
#define MPLLCON_OFFSET		0x10
#define EPLLCON_OFFSET		0x18
#define CLKSRCCON_OFFSET	0x20
#define CLKDIV0CON_OFFSET	0x24
#define CLKDIV1CON_OFFSET	0x28
#define CLKDIV2CON_OFFSET	0x2c


/*
 * GPIO
 */

#define ELFIN_GPIO_BASE		0x56000000

#define GPACON_OFFSET		0x00
#define GPADAT_OFFSET		0x04 

#define GPBCON_OFFSET		0x10
#define GPBDAT_OFFSET		0x14
#define GPBPU_OFFSET		0x18


Makefile

@@ -0,0 +1,44 @@
# *************************************************************
# *	@Hardware: TQ2416	
# *	@software: ubuntu-12.04
# *	@author	 : <mingllu@163.com>
# *	@date    : 2015-07-09
# *	@filename: led.S
# **************************************************************

BINANME = led
TEXTBASE = 0x0
INSTPATH = $(PWD)/bin 

CROSS_COMPILE = /usr/local/arm-2014.05/bin/arm-none-linux-gnueabi-
CC 		= $(CROSS_COMPILE)gcc
LD 		= $(CROSS_COMPILE)ld
AR 		= $(CROSS_COMPILE)ar
OBJCOPY = $(CROSS_COMPILE)objcopy 
OBJDUMP = $(CROSS_COMPILE)objdump 
STRIP	= $(CROSS_COMPILE)strip 
READELF = $(CROSS_COMPILE)readelf 

CFLAGS = -g -O2 -Wall -nostdinc -nostdlib -fno-builtin 
AFLAGS = $(CFLAGS) -D__ASSEMBLY__

LDFLAGS = -Ttext $(TEXTBASE)

SRC_S = $(wildcard *.S)
OBJ_S = $(patsubst %.S,%.o,$(SRC_S)) 

OBJ_ALL = $(OBJ_S)

.PHONY:all 
all:${OBJ_ALL}
	${LD} $(LDFLAGS) -o led.elf ${OBJ_ALL}
	${OBJCOPY} -O binary -S led.elf led.bin 
	rm -rf *.elf *.o 
	cp -a led.bin /mnt/hgfs/share/

%.o: %.S
	$(CC) $(AFLAGS) -c -o $@ $< 

clean:
	rm -rf *.elf *.o bootstrap.bin 
上面是用来把TQ2416上的几个led灯点亮,每各灯依次闪烁0.5s左右。


总结:

1.根据今天做的这组测试,证明了s3c2416这款处理器的关于启动方式(1.iROM模式 2.Nand boot模式 3.OneNand模式)中的Nand boot模式,在上电之后,片内的SRAM确实是被自动映射到了0x00000000地址区域上,调试的led.bin只有412字节,在led.S中尚未初始化任何的sdram,程序能够运行证明了sram确实是自动映射。

2.上面的测试为接下来的探究紧接着也带来下面的探究,若在汇编程序中加入sdram的初始化,nandflash的读,以及u-boot的重新定向。是不是就可以完成了一个类似nand-spl的功能,这有待进一步验证。

H-JTAG烧录

关于利用H-Jtag烧录bin文件到s3c2416+S34ML02G100TF组合的TQ2416开发板上,我写了下面两个文件,可以直接放入到C:\Program File\H-JTAG中去,这两个分别是

1.C:\Program Files\H-JTAG\HFC Examples\s3c2416+s34ml02g100TF.hfc

FLASH SECTION:
NAND-FLASH
S3C2416+S34ML02G100TF100
MEMORY SECTION:
08-BIT X 1-CHIP
0x0
0
XTAL SECTION:
NULL
TCK SECTION:
-1
-1
SCRIPT SECTION:
PGMOPTION SECTION:
ADDON SECTION:
NULL
2.C:\Program Files\H-JTAG\FDevice\NAND-FLASH\S3C2416+S34ML02G100TF100

FLASH_TYPE=3
FLASH_SIZE=256M
FLASH_ID=0x00DA0001
FLASH_ID2=0x0F0F0F0F
FLASH_ADDRESS=0x0
FLASH_NAND_DEVICE=(2048+64)x64PAGESx2048BLOCKS
FLASH_WIDTH=8/0/0
FLASH_DRIVER=1204/0/0
上面这两个文件存放的路径我都给出来了,H-JTAG的使用方式,想必大家都会,就不说了。

J-link的烧录

我们上面的H-JTAG的方式只是用来烧录我们调试好的程序,为了方便我们调试,我们常用的还是使用j-link,比较方面测试。

1.首先设置TQ2416开发板到Nand boot的模式

2.打开JLink.exe(如果你不知道在哪找到它,就去它的安装目录下找,比如说我安装在了C盘下的C:\Program Files\SEGGER\JLinkARM_V440)

3.打开JLink.exe后,依次输入下面的命令,其中步骤三是可以更改的,你的文件放在哪个盘,你就从哪个盘loadbin就行,我的是放在了d:\share\下的,所以才有这个路径。

1.h
2.speed 12000
3.loadbin d:\share\led.bin 0x0
4.setpc 0x0
5.g

好了,今天的探究先到此结束,接下研究初始化sdram,并重nandflash中加载u-boot到sdram中去运行,最后将实现移植u-boot-2014.10到TQ2416的开发板上。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值