您的位置:首页 > 其它

OK6410裸板更新程序_update

2013-04-26 15:30 549 查看
我用的飞淩ok6410开发板,DNW下载程序太容易出问题了,于是买了个openjtag,买回来才发现暂不支持MLC NAND。我下决心写个有下载程序功能的裸板程序update.

再也不用忍受DNW了,并且还介绍一种SD卡下载方法。先用飞淩提供的一键烧写工具,写mmc.bin到sd卡,再把自己要下载的程序以u-boot.bin命名,也拷到sd卡,

mmc.bin会自动帮你把程序烧写到NAND,再从NAND启动就运行你的程序了。以后这片sd卡就相当于你的下载器,需要跑什么程序拷到sd卡就OK了。

具体操作过程见后面,现在开始写update程序。

系统:ubuntu 10.04.4

单板:ok6410

编译器:arm-linux-gcc-4.3.2

搭建开发环境详见ubuntu 10.04.4开发环境配置。

目标:串口输出菜单,有以下·功能供选择

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

update program with serial port

The board:witech(ok6410)

The NAND:K9GAG08U0D 2048MB

The DDR:K4X1G163PCX2 256MB

The NET:DM9000AEP

date: 2013.4.26

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

the menu of the update programe:

[w] write the nand flash

[r] read the nand flash

[e] erase the nand flash

[g] get file, and write to nand flash 0 block

[x] get file to ddr(0x57e00000), run it

[s] reset the programe

Please enter the chose:


即实现读写nand,通过V2.2.exe/gtkterm发送文件到内存,再写到NADN flash 0地址,以及重启update程序。

改程序主要功能是实现更新程序,以及把程序放到内存运行·。

一、编写源代码

根据s5pc100手册编写代码,包括源文件start.S clock.S sdram.c init.c main.c boot.lds Makefile

文件start.S:

.text
.global _start
_start:
/*0. 硬件相关的设置 */
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)

/*1.关看门狗*/
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]

ldr sp, =8*1024

/*2.设置时钟*/
bl  clock_init

/*3.初始化SDRAM DDR*/
bl  ddr_init

/*4.重定位:把代码从flash复制到他的链接地址*/
ldr sp, =0x58000000
bl  nand_init

mov r0, #0
ldr r1, =_start
ldr r2, =__bss_start
sub r2, r2, r1

bl copy_code_to_sdram
bl clear_bss
/*5.执行main*/
ldr lr, =halt
ldr pc, =main

halt:
b   halt
文件clock.S:

.globl clock_init

clock_init:

/* 1.设置LOCK_TIME */
ldr r0, =0x7E00F000  /* APLL_LOCK */
ldr r1, =0x0000FFFF
str r1, [r0]

str r1, [r0, #4]	 /* MPLL_LOCK */
str r1, [r0, #8]	 /* EPLL_LOCK */

#define OTHERS		0x7e00f900
@ set async mode  /* 当CPU时钟 != HCLK时,要设为异步模式 */
ldr r0, =OTHERS
ldr r1, [r0]
bic r1, r1, #0xc0	/* 1100,0000 */
str r1, [r0]

loop1:				/* 等待,直到CPU进入异步模式 */
ldr r0, =OTHERS
ldr r1, [r0]
and r1, r1, #0xf00
cmp r1, #0
bne loop1

/* SYNC667 */
/* MISC_CON[19] = 0 */

#define ARM_RATIO    0   /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1)    */
#define HCLKX2_RATIO 1   /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) */
#define HCLK_RATIO   1   /* HCLK = HCLKX2 / (HCLK_RATIO + 1)       */
#define PCLK_RATIO   3   /* PCLK   = HCLKX2 / (PCLK_RATIO + 1)     */
#define MPLL_RATIO   0   /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)     */
ldr r0, =0x7E00F020  /* CLK_DIV0 */
ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)
str r1, [r0]

/* 2.配置时钟 */
/* 2.1 配置APLL */
/* 2.1.1 设置APLL
* 2.1.2 MUXAPLL
* 2.1.3 SYNC667
* 2.1.4 DIVAPLL
*/
#define APLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F00C
ldr r1, =APLL_CON_VAL
str r1, [r0]		/* APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  */

/* 2.2 配置MPLL */
/* 2.2.1 设置MPLL
* 2.2.2 MUXMPLL
* 2.2.3 SYNCMUX
* 2.2.4 SYNC667
* 2.2.5 HCLKX2_RATIO
* 2.2.6 PCLK_RATIO
*/
#define MPLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F010
ldr r1, =MPLL_CON_VAL
str r1, [r0]		/* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  */

/* 3.选择PLL的输出作为时钟源 */
ldr r0, =0x7E00F01C
ldr r1, =0x03
str r1, [r0]

mov pc, lr
文件sdram.c:

//#include <common.h>

#define MEMCCMD	0x7e001004
#define P1REFRESH	0x7e001010
#define P1CASLAT	0x7e001014
#define MEM_SYS_CFG	0x7e00f120
#define P1MEMCFG	0x7e00100c
#define P1T_DQSS	0x7e001018
#define P1T_MRD		0x7e00101c
#define P1T_RAS		0x7e001020
#define P1T_RC		0x7e001024
#define P1T_RCD		0x7e001028
#define P1T_RFC		0x7e00102c
#define P1T_RP		0x7e001030
#define P1T_RRD		0x7e001034
#define P1T_WR		0x7e001038
#define P1T_WTR		0x7e00103c
#define P1T_XP		0x7e001040
#define P1T_XSR		0x7e001044
#define P1T_ESR		0x7e001048
#define P1MEMCFG2	0X7e00104c
#define P1_chip_0_cfg	0x7e001200

#define P1MEMSTAT	0x7e001000
#define P1MEMCCMD	0x7e001004
#define P1DIRECTCMD	0x7e001008

#define HCLK	133000000

#define nstoclk(ns)	(ns/( 1000000000/HCLK)+1)

#define vi *( volatile unsigned int * )

#define set_zero( addr, bit ) ( (vi addr) &= ( ~ ( 1 << (bit) ) ) )
#define set_one( addr, bit ) ( (vi addr) |= ( 1 << ( bit ) ) )

#define set_bit( addr, bit, val ) ( (vi addr) = (( vi addr)&=(~(1<<(bit))) ) | ( (val)<<(bit) ) )

#define set_2bit( addr, bit, val ) ( (vi addr) = (( vi addr)&(~(3<<(bit))) ) | ( (val)<<(bit) ) )
#define set_nbit( addr, bit, len,  val ) \
( (vi addr) = ((( vi addr)&(~(( ((1<<(len))-1) )<<(bit))))  | ( (val)<<(bit) ) ))

#define get_bit( addr, bit ) ( (( vi addr ) & ( 1 << (bit) )) > 0  )

#define get_val( addr, val ) ( (val) = vi addr )
#define read_val( addr ) ( vi ( addr ) )
#define set_val( addr, val ) ( (vi addr) = (val) )
#define or_val( addr, val ) ( (vi addr) |= (val) )

void ddr_init( void )
{
// tell dramc to configure
set_val( MEMCCMD, 0x4 );

// set refresh period
set_val( P1REFRESH, nstoclk(7800) );

// set timing para
set_val( P1CASLAT, ( 3 << 1 ) );
set_val( P1T_DQSS, 0x1 );	// 0.75 - 1.25
set_val( P1T_MRD, 0x2 );
set_val( P1T_RAS, nstoclk(45) );
set_val( P1T_RC, nstoclk(68) );

unsigned int trcd = nstoclk( 23 );
set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
unsigned int trfc = nstoclk( 80 );
set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
unsigned int trp = nstoclk( 23 );
set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
set_val( P1T_RRD, nstoclk(15) );
set_val( P1T_WR, nstoclk(15) );
set_val( P1T_WTR, 0x7 );
set_val( P1T_XP, 0x2 );
set_val( P1T_XSR, nstoclk(120) );
set_val( P1T_ESR, nstoclk(120) );

// set mem cfg
set_nbit( P1MEMCFG, 0, 3, 0x2 );  /* 10 column address */

/* set_nbit: 把从第bit位开始的一共len位消零,然后把这几位设为val */

set_nbit( P1MEMCFG, 3, 3, 0x2 );  /* 13 row address */
set_zero( P1MEMCFG, 6 );		  /* A10/AP */
set_nbit( P1MEMCFG, 15, 3, 0x2 ); /* Burst 4 */

set_nbit( P1MEMCFG2, 0, 4, 0x5 );
set_2bit( P1MEMCFG2, 6, 0x1 );		/* 32 bit */
set_nbit( P1MEMCFG2, 8, 3, 0x3 );	/* Mobile DDR SDRAM */
set_2bit( P1MEMCFG2, 11, 0x1 );

set_one( P1_chip_0_cfg, 16 );		/* Bank-Row-Column organization */

// memory init
set_val( P1DIRECTCMD, 0xc0000 ); // NOP
set_val( P1DIRECTCMD, 0x000 );	// precharge
set_val( P1DIRECTCMD, 0x40000 );// auto refresh
set_val( P1DIRECTCMD, 0x40000 );// auto refresh
set_val( P1DIRECTCMD, 0xa0000 ); // EMRS
set_val( P1DIRECTCMD, 0x80032 ); // MRS

set_val( MEM_SYS_CFG, 0x0 );

// set dramc to "go" status
set_val( P1MEMCCMD, 0x000 );

// wait ready
while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));
}
文件init.c:

#define MEM_SYS_CFG     (*((volatile unsigned long *)0x7E00F120))
#define NFCONF          (*((volatile unsigned long *)0x70200000))
#define NFCONT          (*((volatile unsigned long *)0x70200004))
#define NFCMMD          (*((volatile unsigned long *)0x70200008))
#define NFADDR          (*((volatile unsigned long *)0x7020000C))
#define NFDATA          (*((volatile unsigned char *)0x70200010))
#define NFSTAT          (*((volatile unsigned long *)0x70200028))

void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);

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 int src, unsigned int dest, unsigned int len)
{
int i = 0;
/*如果是Nor启动*/
unsigned char *src_start = (unsigned char *)src;
unsigned char *dest_start = (unsigned char *)dest;
if(isBootFromNorFlash())
{
while (i < len)
{
dest_start[i] = src_start[i];
i++;
}
}
else
{
//nand_init();
//nand_resd(src, dest, len)
nand_read(src, dest, len);
}
}

void nand_select(void)
{
NFCONT &= ~(1<<1);
}

void nand_deselect(void)
{
NFCONT |= (1<<1);
}

void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd;
}

void nand_addr(unsigned char addr)
{
NFADDR = addr;
}

unsigned char nand_get_data(void)
{
return NFDATA;
}

void nand_send_data(unsigned char data)
{
NFDATA = data;
}

void wait_ready(void)
{
while ((NFSTAT & 0x1) == 0);
}

void nand_reset(void)
{
/* 选中 */
nand_select();

/* 发出0xff命令 */
nand_cmd(0xff);

/* 等待就绪 */
wait_ready();

/* 取消选中 */
nand_deselect();
}

void clear_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;

for (; p < &__bss_end; p++)
*p = 0;
}

void nand_init(void)
{
/* 让xm0csn2用作nand flash cs0 片选引脚 */
MEM_SYS_CFG &= ~(1<<1);

/* 设置时间参数 */
#define TACLS     0
#define TWRPH0    2
#define TWRPH1    1
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));

/* 使能nand flash controller */
NFCONT |= 1;
NFCONT &= ~(1<<16); /* 森止soft lock */

nand_reset();
}

void nand_send_addr(unsigned int addr)
{
#if 1
unsigned int page   = addr / 4096;
unsigned int colunm = addr & (4096 - 1);

/* 这两个地址表示从页内哪里开始 */
nand_addr(colunm & 0xff);
nand_addr((colunm >> 8) & 0xff);

/* 下面三个地址表示哪一页 */
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
#else
nand_addr(addr & 0xff);         /* a0~a7 */
nand_addr((addr >> 8) & 0x1f);   /* 程序的角度: a8~a12 */

nand_addr((addr >> 13) & 0xff); /* 程序的角度: a13~a20 */
nand_addr((addr >> 21) & 0xff); /* 程序的角度: a21~a28 */
nand_addr((addr >> 29) & 0x7); /* 程序的角度: a29   ~ */

#endif
}

void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i = nand_start % 4096;
int left = i;
int count = 0;
unsigned char *dest = (unsigned char *)ddr_start;
unsigned char data = 0;

/* 选中芯片 */
nand_select();

while (count < len)
{
/* 发出命令0x00 */
nand_cmd(0x00);

/* 发出地址 */
nand_send_addr(addr);

/* 发出命令0x30 */
nand_cmd(0x30);

/* 等待就绪 */
wait_ready();

/* 读数据 */
for (; i < (4096-left) && count < len; i++)//从某页的i处开始读
{
data = nand_get_data();
if(addr<16384)//前4页每次只能写2K
{
if(i<(2048-left))
{
dest[count++] = data;
}
}
else
{
dest[count++] = data;
}
//dest[count++] = nand_get_data();
addr++;
}

i = 0;
left = i;
}

/* 取消片选 */
nand_deselect();
// return 0;
}

void nand_erase_block(unsigned long addr)
{
int page = addr / 4096;

nand_select();
nand_cmd(0x60);

nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);

nand_cmd(0xd0);
wait_ready();

nand_deselect();
}

void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len)
{
unsigned long count = 0;
unsigned long addr  = nand_start;
int i = nand_start % 4096;
int left = i;

nand_select();
while (count < len)
{
nand_cmd(0x80);
nand_send_addr(addr);
for (; i < (4096-left) && count < len; i++)
{
if(addr<16384)//写前2K
{
if(i<(2048-left))//前2页每页只能写2K
{
nand_send_data(buf[count++]);
}
}
else
{
nand_send_data(buf[count++]);
}
//nand_send_data(buf[count++]);
addr++;
}

nand_cmd(0x10);
wait_ready();
i = 0;
left = i;
}

nand_deselect();

}

#define ULCON0     (*((volatile unsigned long *)0x7F005000))
#define UCON0      (*((volatile unsigned long *)0x7F005004))
#define UFCON0     (*((volatile unsigned long *)0x7F005008))
#define UMCON0     (*((volatile unsigned long *)0x7F00500C))
#define UTRSTAT0   (*((volatile unsigned long *)0x7F005010))
#define UFSTAT0    (*((volatile unsigned long *)0x7F005018))
#define UTXH0      (*((volatile unsigned char *)0x7F005020))
#define URXH0      (*((volatile unsigned char *)0x7F005024))
#define UBRDIV0    (*((volatile unsigned short *)0x7F005028))
#define UDIVSLOT0  (*((volatile unsigned short *)0x7F00502C))

#define GPACON     (*((volatile unsigned long *)0x7F008000))

#define ENABLE_FIFO

static void delay(void)
{
volatile int i = 10;
while (i--);
}
void init_uart(void)
{
GPACON &= ~0xff;
GPACON |= 0x22;

/* ULCON0 */
ULCON0 = 0x3;  /* 数据位:8, 无较验, 停止位: 1, 8n1 */
UCON0  = 0x5;  /* 使能UART发送、接收 */
#ifdef ENABLE_FIFO
UFCON0 = 0x07; /* FIFO enable */
#else
UFCON0 = 0x00; /* FIFO disable */
#endif
UMCON0 = 0;

/* 波特率 */
/* DIV_VAL = (PCLK / (bps x 16 ) ) - 1
* bps = 115200
* DIV_VAL = (66500000 / (115200 x 16 ) ) - 1
*         = 35.08
*/
UBRDIV0   = 35;

/* x/16 = 0.08
* x = 1
*/
UDIVSLOT0 = 0x1;

}

unsigned char getc(void)
{
#ifdef ENABLE_FIFO
while ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)delay();
#else
while ((UTRSTAT0 & (1<<0)) == 0);
#endif

return URXH0;
}

int getc_nowait(unsigned char *pChar)
{
#ifdef ENABLE_FIFO
if ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)
#else
if ((UTRSTAT0 & (1<<0)) == 0)
#endif
{
return -1;
}
else
{
*pChar = URXH0;
return 0;
}
}

void putc(char c)
{
#ifdef ENABLE_FIFO
while (UFSTAT0 & (1<<14))delay();
#else
while ((UTRSTAT0 & (1<<2)) == 0);
#endif
UTXH0 = c;
}

void puts(char *str)
{
int i = 0;
while (str[i])
{
putc(str[i]);
i++;
}
}

void puthex(unsigned int val)
{
/* 0x1234abcd */
int i;
int j;

puts("0x");

for (i = 0; i < 8; i++)
{
j = (val >> ((7-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc('0' + j);
else
putc('A' + j - 0xa);

}

}
void putbyte(unsigned char val)
{
/* 0x1234abcd */
int i;
int j;

puts("0x");

for (i = 0; i < 2; i++)
{
j = (val >> ((1-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc('0' + j);
else
putc('A' + j - 0xa);

}

}
文件main.c:

extern void init_uart(void);
extern void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);
extern void putc(char c);
extern void puts(char *str);
extern void puthex(unsigned int val);
extern unsigned char getc(void);
extern int getc_nowait(unsigned char *pChar);
extern void putbyte(unsigned char val);
extern void nand_erase_block(unsigned long addr);
extern void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len);

int strlen(char *str)
{
int i = 0;
while (str[i])
{
i++;
}
return i;
}
void nand_read_test(void)

{
int i;
char buf[100];
unsigned long addr;
unsigned long size;

puts("enter the start address: 0x80000");

//scanf("%s", buf);

//addr = strtoul(buf, NULL, 0);
addr = 0x80000;
//puts("read addr = 0x%x\n\r", addr);

puts("enter the size: 0x60");

//scanf("%s", buf);
//size = strtoul(buf, NULL, 0);
size = 0x60;

if (size > 100)
{
puts("the max size is 100\n\r");
size = 100;
}
nand_read(addr, buf, size);

puts("datas: \n\r");
for (i = 0; i < size; i++)
{
// printf("%02x ", buf[i]);
putbyte(buf[i]);
puts("\t");
if ((i+1) % 8 == 0)
{
puts("\n\r");
}
}
puts("\n\r");
}

void nand_erase_test(void)
{
//char buf[100];
unsigned long addr;

puts("enter the start address: ");
//scanf("%s", buf);
//addr = strtoul(buf, NULL, 0);
addr = 0x80000;
puts("erase addr = ");
puthex(addr);
puts("\n\r");
nand_erase_block(addr);

}

void nand_write_test(void)
{
char buf[20] = {"abcd1234ABCD"};
unsigned long addr;
unsigned long size;

puts("enter the start address:0x80000 ");
//scanf("%s", buf);
//addr = strtoul(buf, NULL, 0);
addr = 0x80000;
puts("enter the string:abcd1234ABCD ");
//scanf("%s", buf);
size = strlen(buf) + 1;
puts(" size= ");
puthex(size);
puts("\n\r");
nand_write(addr, buf, size);

}

void update_program(void)
{
unsigned char *buf = (unsigned char *)0x52000000;
unsigned long len = 0;
int have_begin = 0;
int nodata_time = 0;
unsigned long erase_addr;
char c;
int i;

/* 璇讳覆鍙h幏寰楁暟鎹?*/
puts("\n\ruse V2.2.exe/gtkterm to send file\n\r");
while (1)
{
if (getc_nowait(&buf[len]) == 0)
{
have_begin = 1;
nodata_time = 0;
len++;
}
else
{
if (have_begin)
{
nodata_time++;
}
}

if (nodata_time == 1000)
{
break;
}
}
puts("\n\rhave get data:");
puthex(len);
puts(" bytes\n\r");
puts("the first 16 bytes data: \n\r");
for (i = 0; i < 16; i++)
{
// put("%02x ", buf[i]);
putbyte(buf[i]);
puts("\t");
}
puts("\n\r");

puts("Press Y to program the flash: \n\r");

c = getc();
putc(c);
puts("\n\r");
if (c == 'y' || c == 'Y')
{
/* 鐑у啓鍒皀and flash block 0 */
for (erase_addr = 0; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)
{
nand_erase_block(erase_addr);
}
nand_write(0, buf, len);

puts("update program successful\n\r");
}
else
{
puts("Cancel program!\n\r");
}
}

void run_program(void)
{
unsigned char *buf = (unsigned char *)0x57e00000;
unsigned long len = 0;
int have_begin = 0;
int nodata_time = 0;
void (*theProgram)(void);
int i;

puts("\n\r use gtkterm to send file\n\r");
while (1)
{
if (getc_nowait(&buf[len]) == 0)
{
have_begin = 1;
nodata_time = 0;
len++;
}
else
{
if (have_begin)
{
nodata_time++;
}
}

if (nodata_time == 1000)
{
break;
}
}
//printf("have get %d bytes data\n\r", len);
puts("\n\r have get data:");
puthex(len);
puts(" bytes\n\r");
puts("the first 16 bytes data: \n\r");
for (i = 0; i < 16; i++)
{
// put("%02x ", buf[i]);
putbyte(buf[i]);
puts("\t");
//putc('\0');
}
puts("\n\r");
puts("jump to 0x57e00000 to run it\n\r");

theProgram = (void (*)(void))0x57e00000;

theProgram();
}

int main(void)
{
char c;

init_uart();

puts("\n\r*********************************\n\r");
puts("update program with serial port\n\r");
puts("The board:witech(ok6410)\n\r");
puts("The NAND:K9GAG08U0D 2048MB\n\r");
puts("The DDR:K4X1G163PCX2 256MB\n\r");
puts("The NET:DM9000AEP\n\r");
puts("                 date: 2013.4.26\n\r");
puts("***********************************\n\r");

while (1)
{
puts("the menu of the update programe:\n\r");
puts("[w] write the nand flash\n\r");
puts("[r] read the nand flash\n\r");
puts("[e] erase the nand flash\n\r");
puts("[g] get file, and write to nand flash 0 block\n\r");
puts("[x] get file to ddr(0x57e00000), run it\n\r");
puts("[s] reset the programe\n\r");
puts("Please enter the chose:\n\r");

do {
c = getc();
if (c == '\n' || c == '\r')
{
puts("\n\r");
}
else
{
putc(c);
}
} while (c == '\n' || c == '\r');

switch (c)
{
case 'w':
case 'W':
{
nand_write_test();
break;
}

case 'r':
case 'R':
{
nand_read_test();
break;
}

case 'e':
case 'E':
{
nand_erase_test();
break;
}

case 'g':
case 'G':
{
update_program();
break;
}

case 'x':
case 'X':
{
run_program();
break;
}

case 's':
case 'S':
{
void (*theProgram)(void);
theProgram = (void (*)(void))0x57e00000;
theProgram();
break;
}

}
}

return 0;
}

文件boot.lds:

SECTIONS {
. = 0x57e00000;
.text : { *(.text) }

. = ALIGN(4);
.rodata : {*(.rodata*)}

. = ALIGN(4);
.data : { *(.data) }

. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss)  *(COMMON) }
__bss_end = .;
}

文件Makefile:

CC      = arm-linux-gcc
LD      = arm-linux-ld
AR      = arm-linux-ar
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump

CFLAGS 		:= -Wall -O2
CPPFLAGS   	:= -nostdinc -nostdlib -fno-builtin

objs := start.o clock.o sdram.o init.o main.o

update.bin: $(objs)
${LD} -Tboot.lds -o boot.elf $^
${OBJCOPY} -O binary -S boot.elf $@
${OBJDUMP} -D -m arm boot.elf > boot.dis

%.o:%.c
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

%.o:%.S
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

clean:
rm -f *.o *.bin *.elf *.dis
二、编译源程序

change@change:~/Si/OK6410/update$ cd /home/change/

change@change:~$ cd Si/OK6410/update/

change@change:~/Si/OK6410/update$ make clean

rm -f *.o *.bin *.elf *.dis

change@change:~/Si/OK6410/update$ make

arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o start.o start.S

arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o clock.o clock.S

arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o sdram.o sdram.c

arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o init.o init.c

arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o main.o main.c

main.c: In function 'nand_read_test':

main.c:50: warning: passing argument 2 of 'nand_read' makes integer from pointer without a cast

main.c: In function 'nand_write_test':

main.c:98: warning: pointer targets in passing argument 2 of 'nand_write' differ in signedness

arm-linux-ld -Tboot.lds -o boot.elf start.o clock.o sdram.o init.o main.o

arm-linux-objcopy -O binary -S boot.elf update.bin

arm-linux-objdump -D -m arm boot.elf > boot.dis

change@change:~/Si/OK6410/update$

这都是经过修改后的最终编译结果,所以没有错误。

三、烧写、测试

用新想到的方法烧写程序,不用前面说的u-boot下载程序。先用飞淩提供的一键烧写工具,写mmc.bin到sd卡,再把上面编译生成的update.bin以u-boot.bin命名,并拷到sd卡,接着把单板拨到sd卡启动。我的OK6410在NAND启动的情况下直接把6、7拨到on就变成SD启动了。单板SD卡启动上电,串口(115200 8 n 1)输出如下:

K

U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410

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

** u-boot 1.1.6 **

** Updated for TE6410 Board **

** Version 1.0 (10-01-15) **

** OEM: Forlinx Embedded **

** Web: http://www.witech.com.cn **

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

CPU: S3C6410 @532MHz

Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)

Board: SMDK6410

DRAM: 128 MB

Flash: 0 kB

NAND: tmp = 29

select s3c_nand_oob_mlc_128

2048 MB

SD/MMC: 1877 MB

*** Warning - bad CRC or moviNAND, using default environment

In: serial

Out: serial

Err: serial

Hit any key to stop autoboot: 0

NAND erase: device 0 whole chip

Skipping bad block at 0x00800000

Skipping bad block at 0x0e400000

Skipping bad block at 0x0e780000

Skipping bad block at 0x13b80000

Skipping bad block at 0x27a80000

Skipping bad block at 0x7e280000

Erasing at 0x7ff80000 -- 100% complete.

OK

reading u-boot.bin

5228 bytes read

NAND write: device 0 offset 0x0, size 0x100000

1032192 bytes written: OK

reading zImage

** Unable to read "zImage" from mmc 0:1 **

说明u-boot烧写完毕。烧写mmc.bin的SD卡,会自动帮你把程序烧写到NAND。接着断电取下SD卡,单板拨到NAND启动,串口输出如下:

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

update program with serial port

The board:witech(ok6410)

The NAND:K9GAG08U0D 2048MB

The DDR:K4X1G163PCX2 256MB

The NET:DM9000AEP

date: 2013.4.26

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

the menu of the update programe:

[w] write the nand flash

[r] read the nand flash

[e] erase the nand flash

[g] get file, and write to nand flash 0 block

[x] get file to ddr(0x57e00000), run it

[s] reset the programe

Please enter the chose:

用串口工具v2.2.exe,演示update程序功能如下:

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

update program with serial port

The board:witech(ok6410)

The NAND:K9GAG08U0D 2048MB

The DDR:K4X1G163PCX2 256MB

The NET:DM9000AEP

date: 2013.4.26

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

the menu of the update programe:

[w] write the nand flash

[r] read the nand flash

[e] erase the nand flash

[g] get file, and write to nand flash 0 block

[x] get file to ddr(0x57e00000), run it

[s] reset the programe

Please enter the chose:

g

use V2.2.exe/gtkterm to send file

接着选择要发送的文件eg:u-boot.bin,并发送文件,发送完毕输出如下:

have get data:0x0003A6BC bytes

the first 16 bytes data:

0x15 0x00
0x00 0xEA
0x14 0xF0
0x9F 0xE5
0x14 0xF0
0x9F 0xE5
0x14 0xF0
0x9F 0xE5

Press Y to program the flash:

接着手动发送y,这里要谨慎操作,因为一旦输入y,程序就会擦除以前的程序。串口输出如下:

update program successful

the menu of the update programe:

[w] write the nand flash

[r] read the nand flash

[e] erase the nand flash

[g] get file, and write to nand flash 0 block

[x] get file to ddr(0x57e00000), run it

[s] reset the programe

Please enter the chose:

看到update program successful上面程序更新完毕。下面来验证,断电重启,串口输出如下:

U-Boot 2012.04.01 (Nov 25 2012 - 21:01:21) for SMDK6410

CPU: S3C6400@532MHz

Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)

Board: SMDK6410

DRAM: 128 MiB

WARNING: Caches not enabled

Flash: 0 KB

NAND: select s3c_nand_oob_mlc_64

id_data[0] = 0xec id_data[1] = 0xd5 id_data[2] = 0x94 id_data[3] = 0x29 id_data[4] = 0x34 id_data[5] = 0x41 id_data[6] = 0xec id_data[7] = 0xd5 NAND_ECC_NONE selected by board driver. This is not recommended !!

2048 MiB

realpage value:255

page value:255

ret value:0

*** Warning - bad CRC, using default environment

In: serial

Out: serial

Err: serial

Net: dm9000

Hit any key to stop autoboot: 0

##### 100ask Bootloader for OpenJTAG #####

Download u-boot to Nand Flash

[k] Download Linux kernel uImage

[j] Download root_jffs2 image

[y] Download root_yaffs image

[d] Download to SDRAM & Run

[z] Download zImage into RAM

[g] get file, and write to nand flash 0 block

[f] Format the Nand Flash

[s] Set the boot parameters

[b] Boot the system

[r] Reboot u-boot

[q] Quit from menu

Enter your selection: q

SMDK6410 #

说明u-boot已经下载完毕,当然以前的程序也就擦掉了。经过测试基本OK,可能还存在bug,反正人多力量大,可以提出一起解决。

刚刚新发现一问题,用飞淩提供的一键烧写工具,写mmc.bin到sd卡,再把上面编译生成的update.bin以u-boot.bin命名,并拷到sd卡,接着把单板拨到sd卡启动。出现问题

U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410

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

** u-boot 1.1.6 **

** Updated for TE6410 Board **

** Version 1.0 (10-01-15) **

** OEM: Forlinx Embedded **

** Web: http://www.witech.com.cn **

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

CPU: S3C6410 @532MHz

Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)

Board: SMDK6410

DRAM: 128 MB

Flash: 0 kB

NAND: tmp = 29

select s3c_nand_oob_mlc_128

2048 MB

SD/MMC: 943 MB

*** Warning - bad CRC or moviNAND, using default environment

In: serial

Out: serial

Err: serial

Hit any key to stop autoboot: 0

NAND erase: device 0 whole chip

Skipping bad block at 0x00800000

Skipping bad block at 0x0e400000

Skipping bad block at 0x0e780000

Skipping bad block at 0x13b80000

Skipping bad block at 0x27a80000

Skipping bad block at 0x7e280000

Erasing at 0x7ff80000 -- 100% complete.

OK

reading u-boot.bin

error found: 0010

解决error found: 0010方法:

在这里http://www.pc6.com/softview/SoftView_66768.html下载Aomei Partition Assistant Professional Edition 4.0,用该分区根据将以前分区删除,然后新建分区就行了,记住只选择你的SD卡盘,不要把自己系统盘给删了,那就亏大了。重新分区后的SD卡启动如下

U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410

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

** u-boot 1.1.6 **

** Updated for TE6410 Board **

** Version 1.0 (10-01-15) **

** OEM: Forlinx Embedded **

** Web: http://www.witech.com.cn **

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

CPU: S3C6410 @532MHz

Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)

Board: SMDK6410

DRAM: 128 MB

Flash: 0 kB

NAND: tmp = 29

select s3c_nand_oob_mlc_128

2048 MB

SD/MMC: 1904 MB

*** Warning - bad CRC or moviNAND, using default environment

In: serial

Out: serial

Err: serial

Hit any key to stop autoboot: 0

NAND erase: device 0 whole chip

Skipping bad block at 0x00800000

Skipping bad block at 0x0e400000

Skipping bad block at 0x0e780000

Skipping bad block at 0x13b80000

Skipping bad block at 0x27a80000

Skipping bad block at 0x7e280000

Erasing at 0x7ff80000 -- 100% complete.

OK

reading u-boot.bin

239292 bytes read

NAND write: device 0 offset 0x0, size 0x100000

1032192 bytes written: OK

reading zImage

** Unable to read "zImage" from mmc 0:1 **

这样就OK了。发现啥问题尽量提,一起解决它。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: