****************************************************************************************************
硬件平台: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的开发板上。