OK6410裸板更新程序_update

来源:互联网 发布:淘宝店铺信誉度 编辑:程序博客网 时间:2024/06/06 03:17

我用的飞淩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, =0x70000000orr r0, r0, #0x13mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)/*1.关看门狗*/        ldr r0, =0x7E004000mov r1, #0str r1, [r0]ldr sp, =8*1024/*2.设置时钟*/bl  clock_init/*3.初始化SDRAM DDR*/bl  ddr_init/*4.重定位:把代码从flash复制到他的链接地址*/ldr sp, =0x58000000bl  nand_initmov r0, #0ldr r1, =_startldr r2, =__bss_startsub r2, r2, r1bl copy_code_to_sdrambl clear_bss/*5.执行main*/ldr lr, =haltldr pc, =mainhalt:b   halt
文件clock.S:

.globl clock_initclock_init:/* 1.设置LOCK_TIME */ldr r0, =0x7E00F000  /* APLL_LOCK */ldr r1, =0x0000FFFFstr r1, [r0]str r1, [r0, #4] /* MPLL_LOCK */str r1, [r0, #8] /* EPLL_LOCK */#define OTHERS0x7e00f900@ set async mode  /* 当CPU时钟 != HCLK时,要设为异步模式 */ldr r0, =OTHERSldr r1, [r0]bic r1, r1, #0xc0/* 1100,0000 */str r1, [r0]loop1:/* 等待,直到CPU进入异步模式 */ldr r0, =OTHERSldr r1, [r0]and r1, r1, #0xf00cmp r1, #0bne 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, =0x7E00F00Cldr r1, =APLL_CON_VALstr 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, =0x7E00F010ldr r1, =MPLL_CON_VALstr r1, [r0]/* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  *//* 3.选择PLL的输出作为时钟源 */ldr r0, =0x7E00F01Cldr r1, =0x03str r1, [r0]mov pc, lr
文件sdram.c:

//#include <common.h>#define MEMCCMD0x7e001004#define P1REFRESH0x7e001010#define P1CASLAT0x7e001014#define MEM_SYS_CFG0x7e00f120#define P1MEMCFG0x7e00100c#define P1T_DQSS0x7e001018#define P1T_MRD0x7e00101c#define P1T_RAS0x7e001020#define P1T_RC0x7e001024#define P1T_RCD0x7e001028#define P1T_RFC0x7e00102c#define P1T_RP0x7e001030#define P1T_RRD0x7e001034#define P1T_WR0x7e001038#define P1T_WTR0x7e00103c#define P1T_XP0x7e001040#define P1T_XSR0x7e001044#define P1T_ESR0x7e001048#define P1MEMCFG20X7e00104c#define P1_chip_0_cfg0x7e001200#define P1MEMSTAT0x7e001000#define P1MEMCCMD0x7e001004#define P1DIRECTCMD0x7e001008#define HCLK133000000#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 configureset_val( MEMCCMD, 0x4 );// set refresh periodset_val( P1REFRESH, nstoclk(7800) );// set timing paraset_val( P1CASLAT, ( 3 << 1 ) );  set_val( P1T_DQSS, 0x1 );// 0.75 - 1.25set_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 initset_val( P1DIRECTCMD, 0xc0000 ); // NOPset_val( P1DIRECTCMD, 0x000 );// prechargeset_val( P1DIRECTCMD, 0x40000 );// auto refreshset_val( P1DIRECTCMD, 0x40000 );// auto refreshset_val( P1DIRECTCMD, 0xa0000 ); // EMRSset_val( P1DIRECTCMD, 0x80032 ); // MRSset_val( MEM_SYS_CFG, 0x0 );// set dramc to "go" statusset_val( P1MEMCCMD, 0x000 );// wait readywhile( !(( 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);      elseputc('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);      elseputc('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-gccLD      = arm-linux-ld AR      = arm-linux-arOBJCOPY = arm-linux-objcopyOBJDUMP = arm-linux-objdumpCFLAGS := -Wall -O2CPPFLAGS   := -nostdinc -nostdlib -fno-builtinobjs := start.o clock.o sdram.o init.o main.oupdate.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 #####
[n] 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了。发现啥问题尽量提,一起解决它。