新手發帖,很多方面都是剛入門,有錯誤的地方請大家見諒,歡迎批評指正
????我用的飛淩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:?
0x150x00 0x000xEA 0x140xF0 0x9F0xE5 0x140xF0 0x9F0xE5 0x140xF0 0x9F0xE5
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,橫豎人多力量大,可以提出一同處理。
文章結束給大家分享下程序員的一些笑話語錄: 剎車失靈
有一個物理學家,工程師和一個程序員駕駛著一輛汽車行駛在阿爾卑斯山脈 上,在下山的時候,忽然,汽車的剎車失靈了,汽車無法控制地向下沖去, 眼看前面就是一個懸崖峭壁,但是很幸運的是在這個懸崖的前面有一些小樹 讓他們的汽車停了下來, 而沒有掉下山去。 三個驚魂未定地從車里爬了出來。
物理學家說, “我覺得我們應該建立一個模型來模擬在下山過程中剎車片在高 溫情況下失靈的情形”。
工程師說, “我在車的后備廂來有個扳手, 要不我們把車拆開看看到底是什么 原因”。
程序員說,“為什么我們不找個相同的車再來一次以重現這個問題呢?”
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
