TQ2440裸板更新程序_update

以前的裸板程序都是通过u-boot下载到内存运行,今天实现更新程序update,程序运行时会输出一个菜单供选择。

系统:ubuntu 10.04.4
单板:tq2440
编译器:arm-linux-gcc-4.3.2
搭建开发环境详见ubuntu 10.04.4开发环境配置。

目标:实现自我更新程序,串口输出菜单,有以下·功能供选择

*********************************
update program with serial port
The board:TQ2440
The NAND:K9F1216U0A 256MB
The NOR:EN29LV160AB 2MB
The SRAM:HY57V561620 x2 64MB
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(0x32000000), run it
[s] reset the programe
Please enter the chose:

一、编写源代码

根据s3c2440手册编写代码,包括文件:start.S init.c main.c boot.lds Makefile

文件start.S:

#define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))
#define MEM_CTL_BASE    	0x48000000

.text
.global	_start
_start:	
	/*1.关看门狗*/
	ldr r0, =0x53000000
	mov r1, #0
	str r1, [r0]
	
	/*2.设置时钟*/
	ldr r0, =0x4c000014
	mov r1, #0x03
	str r1, [r0]

	/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
	mrc	p15, 0, r1, c1, c0, 0		/* 读出控制寄存器 */ 
	orr	r1, r1, #0xc0000000		/* 设置为“asynchronous bus mode” */
	mcr	p15, 0, r1, c1, c0, 0		/* 写入控制寄存器 */

	/* MPLLCON = S3C2440_MPLL_200MHZ */
	ldr r0, =0x4c000004
	ldr r1, =S3C2440_MPLL_200MHZ
	str r1, [r0]

	/*3.初始化SDRAM*/
	ldr r0, =MEM_CTL_BASE
	adr r1, sdram_config			/*当前地址*/
	add r3, r0, #(13*4)
1:	
	ldr r2, [r1], #4
	str r2, [r0], #4
	cmp r0 ,r3
	bne 1b

	/*4.重定位:把bootloader本身代码从flash复制到他的链接地址*/
	ldr sp, =0x34000000

	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*/
	//bl main
	ldr lr, =halt
	ldr pc, =main

halt:
	b halt
	
sdram_config:

	.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

文件init.c:

/* 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 UFSTAT0             (*(volatile unsigned long *)0x50000018)
#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(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;
  unsigned char *src_start = (unsigned char *)src;
  unsigned char *dest_start = (unsigned char *)dest;
  /*如果是Nor启动*/
  if(isBootFromNorFlash())
    {
      while (i < len)
	{
	  //dest[i] = src[i];
	  dest_start[i] = src_start[i];
	  i++;
	}  
    }
  else
    {
      //nand_init();
      //nand_resd(src, dest, len)
      nand_read(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_select(void)
{
  NFCONT &= ~(1<<1);	
}

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

void nand_cmd(unsigned char cmd)
{
  volatile int i;
  NFCMMD = cmd;
  for (i = 0; i < 10; i++);
}

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++);	
}

void wait_ready(void)
{
	while (!(NFSTAT & 1));
}

unsigned char nand_get_data(void)
{
	return NFDATA;
}

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

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

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

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

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

void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
	unsigned int addr = nand_start;
	int col = addr % 2048;
	int i = 0;
	unsigned char *dest = (unsigned char *)ddr_start;
	
	/* 1. 选中 */
	nand_select();
	while (i < len)
	{
		/* 2. 发出读命令00h */
		nand_cmd(0x00);

		/* 3. 发出地址(分5步发出) */
		nand_addr(addr);

		/* 4. 发出读命令30h */
		nand_cmd(0x30);

		/* 5. 判断状态 */
		wait_ready();

		/* 6. 读数据 */
		for (; (col < 2048) && (i < len); col++)
		{
			dest[i] = nand_get_data();
			i++;
			addr++;
		}
		
		col = 0;
	}

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

void nand_erase_block(unsigned long addr)
{
  int page = addr / 2048;
  
  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 % 2048;
  //int left = i;
  
  nand_select();
  while (count < len)
    {
      nand_cmd(0x80);
      nand_addr(addr);
      //for (; i < (2048-left) && count < len; i++)
      for (; i < 2048 && 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();
  
}
void nand_init(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);

  nand_reset();	
}

#define PCLK            50000000    // init.c中的clock_init函数设置PCLK为50MHz
#define UART_CLK        PCLK        //  UART0的时钟源设为PCLK
#define UART_BAUD_RATE  115200      // 波特率
#define UART_BRD        ((UART_CLK  / (UART_BAUD_RATE * 16)) - 1)

#define ENABLE_FIFO 

static void delay(void)
{
  volatile int i = 10;
  while (i--);
}
/*
 * 初始化UART0
 * 115200,8N1,无流控
 */
void uart0_init(void)
{
    GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0
    GPHUP   = 0x0c;     // GPH2,GPH3内部上拉

    ULCON0  = 0x03;     // 8N1(8个数据位,无较验,1个停止位)
    UCON0   = 0x05;     // 查询方式,UART时钟源为PCLK
    #ifdef ENABLE_FIFO
	UFCON0 = 0x07; /* FIFO enable */
    #else
	UFCON0 = 0x00; /* FIFO disable */
    #endif
    UMCON0  = 0x00;     // 不使用流控
    UBRDIV0 = UART_BRD; // 波特率为115200
}

/*
 * 发送一个字符
 */
void putc(unsigned char c)
{
    /* 等待,直到发送缓冲区中的数据已经全部发送出去 */
    //while (!(UTRSTAT0 & TXD0READY));
    #ifdef ENABLE_FIFO
    	while (UFSTAT0 & (1<<14))delay();
    #else
    	while ((UTRSTAT0 & (1<<2)) == 0);
#endif   
    /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
    UTXH0 = c;
}
/*
 * 接收字符
 */
unsigned char getc(void)
{
    /* 等待,直到接收缓冲区中的有数据 */
    //while (!(UTRSTAT0 & RXD0READY));
    #ifdef ENABLE_FIFO
    	while ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)delay();
    #else
    	while ((UTRSTAT0 & (1<<0)) == 0);
#endif   
    /* 直接读取URXH0寄存器,即可获得接收到的数据 */
    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 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 uart0_init(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_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 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 update_program(void)
{
  unsigned char *buf = (unsigned char *)0x32000000;
  //unsigned char *buf = (unsigned char *)0xD0036000;
  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 *)0x32000000;
  //unsigned char *buf = (unsigned char *)0xD0036000;
  unsigned long len = 0;
  int have_begin = 0;
  int nodata_time = 0;
  void (*theProgram)(void);
  int i;
  /* 璇讳覆鍙h幏寰楁暟鎹?*/
  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 == 10000)
	{
	  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 0x32000000 to run it\n\r");
  
  theProgram = (void (*)(void))0x32000000;

  theProgram();
}

int main(void)
{
  char c;

  uart0_init();

  puts("\n\r*********************************\n\r");
  puts("update program with serial port\n\r");
  puts("The board:TQ2440\n\r");
  puts("The NAND:K9F1216U0A 256MB\n\r");
  puts("The NOR:EN29LV160AB 2MB\n\r");
  puts("The SRAM:HY57V561620 x2 64MB\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(0x32000000), 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))0x33f80000;
	    theProgram();
	    break;
	  }
	
	}
    }

  return 0;
}

文件boot.lds:

SECTIONS {
    . = 0x33f80000;
    .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 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 > update.dis

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

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

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

二、编译源代码

change@change:~$ cd Si/TQ2440/update/
change@change:~/Si/TQ2440/update$ make clean
rm -f *.o *.bin *.elf *.dis
change@change:~/Si/TQ2440/update$ ls
boot.lds  init.c  main.c  Makefile  start.S
change@change:~/Si/TQ2440/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 init.o init.c
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o main.o main.c
main.c: In function 'nand_write_test':
main.c:38: warning: pointer targets in passing argument 2 of 'nand_write' differ in signedness
main.c: In function 'nand_read_test':
main.c:69: warning: passing argument 2 of 'nand_read' makes integer from pointer without a cast
arm-linux-ld -Tboot.lds -o boot.elf start.o init.o main.o
arm-linux-objcopy -O binary -S boot.elf update.bin
arm-linux-objdump -D -m arm boot.elf > update.dis
change@change:~/Si/TQ2440/update$ cp update.bin /home/change/work/tftpboot/
change@change:~/Si/TQ2440/update$

三、烧写、测试

单板从NOR flash启动,用u-boot下载上面编译的程序update.bin到NAND Flash

U-Boot 1.1.6 (Mar 24 2012 - 03:44:51)


DRAM:  64 MB
Flash:  2 MB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0 
TQ2440 # set ipaddr 172.16.1.133
TQ2440 # set gatewayip 172.16.1.1
TQ2440 # set serverip 172.16.1.131
TQ2440 # tftp 0x32000000 update.bin
dm9000 i/o: 0x20000000, id: 0x90000a46 
MAC: 00:80:00:80:00:80
could not establish link
TFTP from server 172.16.1.131; our IP address is 172.16.1.133
Filename 'update.bin'.
Load address: 0x32000000
Loading: ##
done
Bytes transferred = 5136 (1410 hex)
TQ2440 # nand erase 0 0x40000


NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
TQ2440 # nand write 0x32000000 0 0x40000


NAND write: device 0 offset 0x0, size 0x40000
 262144 bytes written: OK
TQ2440 # save
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
TQ2440 # 

程序烧写完毕,接着单板断电从NAND启动,设置串口115200 8 n 1输出如下:

*********************************
update program with serial port
The board:TQ2440
The NAND:K9F1216U0A 256MB
The NOR:EN29LV160AB 2MB
The SRAM:HY57V561620 x2 64MB
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(0x32000000), run it
[s] reset the programe
Please enter the chose:

下面开始用串口v2.2.exe测试更新程序:

*********************************
update program with serial port
The board:TQ2440
The NAND:K9F1216U0A 256MB
The NOR:EN29LV160AB 2MB
The SRAM:HY57V561620 x2 64MB
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(0x32000000), run it
[s] reset the programe
Please enter the chose:

手动发送g
g
use V2.2.exe/gtkterm to send file

选择要发送的程序文件eg:boot.bin,并发送文件
have get data:0x000008BC bytes
the first 16 bytes data: 
0x530x04 0xA00xE3 0x000x10 0xA00xE3 0x000x10 0x800xE5 0x980x00 0x9F0xE5

Press Y to program the flash: 
y

此时需谨慎,手动发送y,会擦除以前的程序,向NAND写新的程序
update program successful

这表明程序更新完毕,断电重启就会启动上面发送文件程序,这里串口输出如下:

Copy kernel from nand
0x1234ABCD
0x7D98ACBA
Set boot params
Boot kernel

测试OK,程序跑起来了。

原文地址:https://www.cnblogs.com/javawebsoa/p/3045693.html