Chinaunix首页 | 论坛 | 博客
  • 博客访问: 302058
  • 博文数量: 63
  • 博客积分: 1482
  • 博客等级: 上尉
  • 技术积分: 1185
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-12 19:06
个人简介

hello world!

文章分类

全部博文(63)

分类: LINUX

2011-03-13 23:17:20

一、NAND Flash关键硬件知识
    采用k9f2g08x0a NAND Flash芯片 :(其芯片手册可在网上下载)
Organization
    - Memory Cell Array : (256M 8M) x 8bit
    - Data Register : (2K 64) x 8bit
Automatic Program and Erase
    - Page Program : (2K 64)Byte
    - Block Erase : (128K 4K)Byte
Page Read Operation
   - Page Size : (2K 64)Byte

                               图1 NAND Flash 结构组织

                            图2  NAND Flash命令表 

 

二、NAND Flash 控制寄存器
    NAND FLASH 还是 NOR Flash 配置,硬件电路已设计好,仅供加深理解。
  
                    图3  PIN CONFIGURATION
                           

NFCONF 0x4E000000 R/W  NAND flash configuration register  0x0000100X

 推荐值TACLS=0  TWRPH0=6  TWRPH1=2 buswitdth 8bit (TACLS+TWRPH0+TWRPH1>=50ns)

NFCONT 0x4E000004 R/W NAND flash control register 0x0384

推荐值 (1<<4) | (1<<1) | (1<<0) 

 

 

 

 

 

NFCMMD 0x4E000008 R/W NAND flash command set register 0x00

NFCMMD [7:0]     NAND flash memory command value      0x00

NFADDR 0x4E00000C R/W NAND flash address set register 0x0000XX00

NFADDR [7:0]      NAND flash memory address value       0x00

NFDATA 0x4E000010 R/W NAND flash data register 0xXXXX

可8bit 16bit 32bit访问 如图4

NFDATA [31:0]  NAND flash read/program data value for I/O    0xXXXX

                  Note: Refer to data register configuration in Page 6-5.

 

                                                     图4

NFSTAT 0x4E000020 R/W NAND flash operation status register 0xXX00

三、硬件电路图

   

                图4 NAND Flash管脚连接图

四、NAND Flash 读操作

    K9F2G08U0A的一页为(2K+64)字节(加号前面的2K表示的是main区容量,加号后面的64表示的是spare区容量),它的一块为64页,而整个设备包括了2048个块。这样算下来一共有2112M位容量,如果只算main区容量则有256M字节(即256*8位)。要实现用8个IO口来要访问这么大的容量,K9F2G08U0A规定了用5个周期来实现。第一个周期访问的地址为A0~A7;第二个周期访问的地址为A8~A11,它作用在IO0~IO3上,而此时IO4~IO7必须为低电平;第三个周期访问的地址为A12~A19;第四个周期访问的地址为A20~A27;第五个周期访问的地址为A28,它作用在IO0上,而此时IO1~IO7必须为低电平。前两个周期传输的是列地址,后三个周期传输的是行地址。通过分析可知,列地址是用于寻址页内空间行地址用于寻址页,如果要直接访问块,则需要从地址A18开始。

                           图4 读操作时序图

五、源代码

   start.S  //引导程序

 

  1. /*
  2. *************************************************************************
  3. *
  4. * lcl bootloader
  5. *
  6. *************************************************************************
  7. */
  8. .globl _start
  9. _start: b start_code
  10. start_code:
  11. /*
  12. * set the cpu to SVC32 mode
  13. */
  14. mrs r0, cpsr
  15. bic r0, r0, #0x1f
  16. orr r0, r0, #0xd3
  17. msr cpsr, r0
  18. #define pWTCON 0x53000000
  19. #define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
  20. #define INTSUBMSK 0x4A00001C
  21. #define CLKDIVN 0x4C000014 /* clock divisor register */
  22. #define CLK_CTL_BASE 0x4C000000 /* clock base address */
  23. #define MDIV_405 0x7f << 12 /* MDIV 0x7f*/
  24. #define PSDIV_405 0x21 /* PDIV SDIV 0x2 0x1 */
  25. /* turn off the watchdog */
  26. ldr r0, =pWTCON
  27. mov r1, #0x0
  28. str r1, [r0]
  29. /*
  30. * mask all IRQs by setting all bits in the INTMR - default
  31. */
  32. ldr r1, =0x7fff
  33. ldr r0, =INTSUBMSK
  34. str r1, [r0]
  35. /* FCLK:HCLK:PCLK = 1:4:8 */
  36. ldr r0, =CLKDIVN
  37. mov r1, #5 //1:4:8
  38. str r1, [r0]
  39. mrc p15, 0, r1, c1, c0, 0
  40. orr r1, r1, #0xc0000000
  41. mcr p15, 0, r1, c1, c0, 0
  42. mov r1, #CLK_CTL_BASE
  43. mov r2, #MDIV_405
  44. add r2, r2, #PSDIV_405
  45. str r2, [r1, #0x04] /* MPLLCON address Mpll=405MHZ */
  46. nop
  47. nop
  48. nop
  49. nop
  50. nop
  51. nop
  52. nop
  53. nop
  54. nop
  55. /*
  56. *MMU and SDRAM initialize
  57. */
  58. bl cpu_init_crit
  59. /*
  60. *call c function . sp is 0x34000000
  61. */
  62. mov fp, #0 // no previous frame, so fp=0
  63. ldr sp, =0x34000000
  64. bl NandInit
  65. bl ReadImageFromNand
  66. /*
  67. *run in sdram
  68. */
  69. ldr lr, =halt_loop @设置返回地址
  70. ldr pc, =Main //0x30000834
  71. halt_loop:
  72. b halt_loop
  73. .globl ReadPage512
  74. ReadPage512: //读512字节
  75. stmfd sp!, {r2-r7}
  76. mov r2, #0x200
  77. 1:
  78. ldr r4, [r1] //取出32bit,按8bit字访问
  79. ldr r5, [r1] //取出32bit
  80. ldr r6, [r1] //取出32bit
  81. ldr r7, [r1] //取出32bit
  82. stmia r0!, {r4-r7} //存 64bit 到buffer中
  83. ldr r4, [r1]
  84. ldr r5, [r1]
  85. ldr r6, [r1]
  86. ldr r7, [r1]
  87. stmia r0!, {r4-r7} //存 64bit 到buffer中
  88. ldr r4, [r1]
  89. ldr r5, [r1]
  90. ldr r6, [r1]
  91. ldr r7, [r1]
  92. stmia r0!, {r4-r7} //存 64bit 到buffer中
  93. ldr r4, [r1]
  94. ldr r5, [r1]
  95. ldr r6, [r1]
  96. ldr r7, [r1]
  97. stmia r0!, {r4-r7} //存 64bit 到buffer中
  98. subs r2, r2, #64 //减去已读出的64byte
  99. bne 1b; //循环读出直到512byte
  100. ldmfd sp!, {r2-r7}
  101. mov pc,lr //返回
  102. cpu_init_crit:
  103. /*
  104. * flush v4 I/D caches
  105. */
  106. mov r0, #0
  107. mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
  108. mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
  109. /*
  110. * disable MMU stuff and caches
  111. */
  112. mrc p15, 0, r0, c1, c0, 0
  113. bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
  114. bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
  115. orr r0, r0, #0x00000002 @ set bit 2 (A) Align
  116. orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
  117. mcr p15, 0, r0, c1, c0, 0
  118. /*
  119. * before relocating, we have to setup RAM timing
  120. * because memory timing is board-dependend, you will
  121. * find a lowlevel_init.S in your board directory.
  122. */
  123. mov ip, lr
  124. bl memsetup /* memory control configuration */
  125. mov lr, ip
  126. mov pc, lr
  127. memsetup:
  128. /* memory control configuration */
  129. /* make r0 relative the current location so that it */
  130. /* reads SMRDATA out of FLASH rather than memory ! */
  131. #define MEM_CTL_BASE 0x48000000
  132. mov r1,#MEM_CTL_BASE
  133. adr r2,mem_cfg_val
  134. add r3,r1,#52
  135. 1:
  136. ldr r4, [r2], #4
  137. str r4, [r1], #4
  138. cmp r1, r3
  139. bne 1b
  140. mov pc,lr
  141. .align 4
  142. /* the literal pools origin */
  143. mem_cfg_val:
  144. .long 0x22011110
  145. .long 0x00000700
  146. .long 0x00000700
  147. .long 0x00000700
  148. .long 0x00000700
  149. .long 0x00000700
  150. .long 0x00000700 @BANK5
  151. .long 0x00018005
  152. .long 0x00018005
  153. .long 0x00ac03f4 @REFRESH // 12MHZ 0x00ac07a3
  154. .long 0x000000B1
  155. .long 0x00000030
  156. .long 0x00000030

  def.h

 

  1. #ifndef __DEF_H__
  2. #define __DEF_H__

  3. #define U32 unsigned int
  4. #define U16 unsigned short
  5. #define S32 int
  6. #define S16 short int
  7. #define U8 unsigned char
  8. #define    S8 char

  9. #endif /*__DEF_H__*/

nand.h

 

  1. #ifndef __NAND_H
  2. #define __NAND_H

  3. void NandInit(void);
  4. int NandIsGoodBlock(U32 addr);
  5. int NandReadOneSector(U8 * buffer, U32 addr);

  6. void Uart_SendString(char *);

  7. #define PAGE_UNKNOWN 0
  8. #define PAGE512 1
  9. #define PAGE2048 2 //本芯片为2K一页

  10. #define BYTE_SECTOR_SHIFT (g_page_type == PAGE512 ? 9 : 11) //2K a page=11bit

  11. #define SECTOR_BLOCK_SHIFT (g_page_type == PAGE512 ? 5 : 6) //64 pages=6bit

  12. #define SECTOR_SIZE (1 << BYTE_SECTOR_SHIFT) //2K

  13. #define BLOCK_SIZE (SECTOR_SIZE << SECTOR_BLOCK_SHIFT) //128K

  14. extern int g_page_type;

  15. #endif /*__NAND_H*/

nand.c

 

  1. #include "def.h"
  2. #include "nand.h"

  3. /***********nand flash address*********************/
  4. #define __REGb(x)    (*(volatile unsigned char *)(x))
  5. #define __REGw(x)    (*(volatile unsigned short *)(x))
  6. #define __REGi(x)    (*(volatile unsigned int *)(x))
  7. #define NF_BASE        0x4e000000

  8. #define NFCONF        __REGi(NF_BASE + 0x0)
  9. #define NFCONT        __REGi(NF_BASE + 0x4)
  10. #define NFCMD        __REGb(NF_BASE + 0x8)
  11. #define NFADDR        __REGb(NF_BASE + 0xc)
  12. #define NFDATA        __REGb(NF_BASE + 0x10)
  13. #define NFSTAT        __REGb(NF_BASE + 0x20)
  14. /***********nand flash address end*********************/

  15. #define NF_MECC_UnLock() {NFCONT&=~(1<<5);}
  16. #define NF_MECC_Lock() {NFCONT|=(1<<5);}

  17. #define NF_CMD(cmd)            {NFCMD=cmd;}
  18. #define NF_ADDR(addr)        {NFADDR=addr;}
  19. #define NF_nFCE_L()            {NFCONT&=~(1<<1);}
  20. #define NF_nFCE_H()            {NFCONT|=(1<<1);}
  21. #define NF_RSTECC()            {NFCONT|=(1<<4);}
  22. #define NF_RDDATA8()         (NFDATA)

  23. #define NF_WAITRB()         {while(!(NFSTAT&(1<<1)));}
  24.                              //wait tWB and check F_RNB pin.

  25. // RnB Signal

  26. #define NF_CLEAR_RB()     {NFSTAT |= (1<<2);}    // Have write '1' to clear this bit.

  27. #define NF_DETECT_RB()     {while(!(NFSTAT&(1<<2)));}

  28. #define TACLS        0    // 1-clk(0ns)

  29. #define TWRPH0        6    // 3-clk(25ns)

  30. #define TWRPH1        2    // 1-clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns



  31. #define ECC_VERIFY    0

  32. int g_page_type = PAGE_UNKNOWN;

  33. extern void ReadPage512(U8* buf, volatile unsigned char *nf_data_ptr);

  34. static inline void NandReset(void)
  35. {
  36.     NF_nFCE_L();
  37.     NF_CLEAR_RB();
  38.     NF_CMD(0xFF);        //reset command

  39.     NF_DETECT_RB();
  40.     NF_nFCE_H();

  41. }

  42. static inline void delay(void)
  43. {
  44. #if 0
  45.     volatile int i;
  46.     for (i = 0; i < 1000; i++);
  47. #endif
  48. }

  49. static inline U32 NandCheckId(void)
  50. {
  51.     U8 Mid, Did, DontCare, id4th;

  52.     NF_nFCE_L();

  53.     NF_CMD(0x90);
  54.     NF_ADDR(0x0);

  55.     delay();

  56.     Mid = NF_RDDATA8();
  57.     Did = NF_RDDATA8();
  58.     DontCare = NF_RDDATA8();
  59.     id4th = NF_RDDATA8();

  60.     NF_nFCE_H();

  61.     switch(Did) { /*选择各种支持的芯片类型*/
  62.     case 0x76:
  63.         g_page_type = PAGE512;/* Samsung K91208 * *Hynix HY27US08121A*/
  64.         break;
  65.     case 0xF1:    /* Samsung K9F1G08U0B */
  66.     case 0xD3: /* Samsung K9K8G08 */
  67.     case 0xDA: /* Samsung K9F2G08U0B */
  68.     case 0xDC:
  69.         g_page_type = PAGE2048;
  70.         break;
  71.     default:
  72.         ;
  73.     }


  74.     return (U32) ((Mid << 24) | (Did << 16) | (DontCare << 8) | id4th);
  75. }

  76. void NandInit(void)
  77. {
  78.     NFCONF = (TACLS << 12) | (TWRPH0 << 8) | (TWRPH1 << 4) | (0 << 0);
  79.     NFCONT =
  80.      (0 << 13) | (0 << 12) | (0 << 10) | (0 << 9) | (0 << 8) | (0 << 6) |
  81.      (0 << 5) | (1 << 4) | (1 << 1) | (1 << 0);
  82.     NFSTAT = 0;
  83.     NandReset();
  84.     NandCheckId();
  85.     return ;
  86. }

  87. static inline int NandIsGoodBlockP512(U32 addr)
  88. {
  89.     U32 sector = addr >> 9;
  90.     U8 bad_value;

  91.     NandReset();
  92.     NF_nFCE_L();
  93.     NF_CLEAR_RB();
  94.     NF_CMD(0x50);
  95.     NF_ADDR(5);
  96.     NF_ADDR(sector & 0xff);
  97.     NF_ADDR((sector >> 8) & 0xff);
  98.     NF_ADDR((sector >> 16) & 0xff);

  99.     delay();
  100.     NF_DETECT_RB();

  101.     bad_value = NF_RDDATA8();

  102.     NF_nFCE_H();

  103.     if (bad_value == 0xFF) {
  104.         return 1;
  105.     }

  106.     return 0;
  107. }

  108. static inline int NandIsGoodBlockP2048(U32 addr)
  109. {
  110.     U32 sector = addr >> 11;
  111.     U8 bad_value;

  112.     NandReset();
  113.     NF_nFCE_L();
  114.     NF_CLEAR_RB();
  115.     NF_CMD(0x0);
  116.     NF_ADDR(2048 & 0xFF);
  117.     NF_ADDR((2048 >>8) & 0xff);
  118.     NF_ADDR(sector & 0xff);
  119.     NF_ADDR((sector >> 8) & 0xff);
  120.     NF_ADDR((sector >> 16) & 0xff);
  121.     NF_CMD(0x30);
  122.     delay();
  123.     NF_DETECT_RB();

  124.     bad_value = NF_RDDATA8();

  125.     NF_nFCE_H();

  126.     if (bad_value == 0xFF) {
  127.         return 1;
  128.     }

  129.     return 0;
  130. }

  131. int NandIsGoodBlock(U32 addr)
  132. {
  133.     int ret;
  134.     
  135.     switch(g_page_type) {
  136.     case PAGE512:
  137.         {
  138.             unsigned int i;
  139.             // for ugly method of Chen Yongqiang

  140.             for (i = 0; i < 128 * 1024; i+= 16 * 1024) {
  141.                 ret = NandIsGoodBlockP512(addr / (128 * 1024) * (128 * 1024) + i );
  142.                 if (!ret) {
  143.                     break;
  144.                 }
  145.             }
  146.         }
  147.         break;
  148.     case PAGE2048:
  149.         ret = NandIsGoodBlockP2048(addr);
  150.         break;
  151.     default:
  152.         for(;;);
  153.     }
  154.     return ret;
  155. }

  156. static inline int NandReadOneSectorP512(U8 * buffer, U32 addr)
  157. {
  158.     U32 sector;
  159.     sector = addr >> 9;

  160.     NandReset();
  161. #if 0
  162.     NF_RSTECC();
  163.     NF_MECC_UnLock();
  164. #endif
  165.     NF_nFCE_L();

  166.     NF_CLEAR_RB();
  167.     NF_CMD(0x00);

  168.     NF_ADDR(0x00);
  169.     NF_ADDR(sector & 0xff);
  170.     NF_ADDR((sector >> 8) & 0xff);
  171.     NF_ADDR((sector >> 16) & 0xff);

  172.     delay();
  173.     NF_DETECT_RB();

  174.     ReadPage512(buffer, &NFDATA);
  175. #if 0
  176.     NF_MECC_Lock();
  177. #endif
  178.     NF_nFCE_H();

  179.     return 1;
  180. }


  181. static inline int NandReadOneSectorP2048(U8 * buffer, U32 addr)
  182. {
  183.     U32 sector;
  184.     sector = addr >> 11;

  185.     delay();
  186.     NandReset();
  187. #if 0
  188.     NF_RSTECC();
  189.     NF_MECC_UnLock();
  190. #endif
  191.     NF_nFCE_L();

  192.     NF_CLEAR_RB();
  193.     NF_CMD(0x00);

  194.     NF_ADDR(0x00);
  195.     NF_ADDR(0x00);
  196.     NF_ADDR(sector & 0xff);
  197.     NF_ADDR((sector >> 8) & 0xff);
  198.     NF_ADDR((sector >> 16) & 0xff);
  199.     NF_CMD(0x30);

  200.     delay();
  201.     NF_DETECT_RB();

  202.     ReadPage512(buffer + 0 * 512, &NFDATA);
  203.     ReadPage512(buffer + 1 * 512, &NFDATA);
  204.     ReadPage512(buffer + 2 * 512, &NFDATA);
  205.     ReadPage512(buffer + 3 * 512, &NFDATA);

  206. #if 0
  207.     NF_MECC_Lock();
  208. #endif
  209.     NF_nFCE_H();

  210.     return 1;
  211. }


  212. int NandReadOneSector(U8 * buffer, U32 addr)
  213. {
  214.     int ret;
  215.     
  216.     switch(g_page_type) {
  217.     case PAGE512:
  218.         ret = NandReadOneSectorP512(buffer, addr);
  219.         break;
  220.     case PAGE2048:
  221.         ret = NandReadOneSectorP2048(buffer, addr);
  222.         break;
  223.     default:
  224.         for(;;);
  225.     }
  226.     return ret;
  227. }

  228. void ReadImageFromNand(void)
  229. {
  230.     unsigned int Length;
  231.     U8 *RAM;
  232.     unsigned BlockNum;
  233.     unsigned pos;

  234.     Length = 0x100000;/*将拷贝NAND Flash 中1M的内容到SDRAM中*/
  235.     Length = (Length + BLOCK_SIZE - 1) >> (BYTE_SECTOR_SHIFT + SECTOR_BLOCK_SHIFT) << (BYTE_SECTOR_SHIFT + SECTOR_BLOCK_SHIFT); // align to Block Size

  236.               /*长度对齐,这很关键*/
  237.     BlockNum = 0x00000 >> (BYTE_SECTOR_SHIFT + SECTOR_BLOCK_SHIFT);//拷贝的起始地址,地址对齐,这很关键不然会使拷贝的程序无法运行

  238.     RAM = (U8 *)0x30000000; //拷贝至SDRAM的起始处

  239.     for (pos = 0; pos < Length; pos += BLOCK_SIZE) {
  240.         unsigned int i;
  241.         // skip badblock

  242.         for (;;) {
  243.             if (NandIsGoodBlock
  244.              (BlockNum <<
  245.              (BYTE_SECTOR_SHIFT + SECTOR_BLOCK_SHIFT))) {
  246.                 break;
  247.             }
  248.             BlockNum++;    //try next

  249.         }
  250.         for (i = 0; i < BLOCK_SIZE; i += SECTOR_SIZE) {
  251.             int ret =
  252.              NandReadOneSector(RAM,
  253.                      (BlockNum <<
  254.                      (BYTE_SECTOR_SHIFT +
  255.                         SECTOR_BLOCK_SHIFT)) + i);
  256.             RAM += SECTOR_SIZE;
  257.             ret = 0;

  258.         }

  259.         BlockNum++;
  260.     }
  261.     return ;
  262. }

main.c

 

  1. /*
  2. GPBCON 0x56000010 Port B control
  3. GPBDAT 0x56000014 Port B data
  4. GPBUP 0x56000018 Pull-up control B

  5. LED1 GPB5 LED2 GPB6 LED3 GPB7 LED4 GPB8

  6. GPB8 [17:16] 00 = Input 01 = Output
  7.              10 = nXDREQ1 11 = Reserved
  8. GPB7 [15:14] 00 = Input 01 = Output
  9.              10 = nXDACK1 11 = Reserved
  10. GPB6 [13:12] 00 = Input 01 = Output
  11.              10 = nXBREQ 11 = reserved
  12. GPB5 [11:10] 00 = Input 01 = Output
  13.              10 = nXBACK 11 = reserved
  14. #define S3C24X0_GPIO_BASE        0x56000000

  15. GPGCON = 0000 0000 1000 0000 1010 1000 1000 0010=0x80a882

  16. GPG0 Input/output EinT8 – – K1
  17. GPG3 Input/output EinT11 nSS1 –     K2
  18. GPG5 Input/output EinT13 SPIMISO1 – k3
  19. GPG6 Input/output EinT14 SPIMISO1 – k4
  20. GPG7 Input/output EinT15 SPICLK1 – k5
  21. GPG11 Input/output EinT19 TCLK1 – k6
  22. */

  23. #define GPBCON (*(volatile unsigned long *) 0x56000010)
  24. #define GPBDAT (*(volatile unsigned long *) 0x56000014)
  25. #define GPBUP (*(volatile unsigned long *) 0x56000018)

  26. #define GPGCON (*(volatile unsigned long *) 0x56000060)
  27. #define GPGDAT (*(volatile unsigned long *) 0x56000064)
  28. #define GPGUP (*(volatile unsigned long *) 0x56000068)

  29. #define GPX_up 0x00000000

  30. #define GPB5_out (1<<(5*2))
  31. #define GPB6_out (1<<(6*2))
  32. #define GPB7_out (1<<(7*2))
  33. #define GPB8_out (1<<(8*2))

  34. #define GPG0_in ~(3<<(0*2))
  35. #define GPG3_in ~(3<<(3*2))
  36. #define GPG5_in ~(3<<(5*2))
  37. #define GPG6_in ~(3<<(6*2))

  38. static inline void leds_init()
  39. {
  40.     GPBCON = (GPB5_out | GPB6_out | GPB7_out | GPB8_out);
  41.     GPBUP     = GPX_up;
  42. }
  43. static inline void buttons_init()
  44. {
  45.     GPGCON = (GPG0_in & GPG3_in & GPG5_in & GPG6_in);
  46.     GPGUP     = GPX_up;
  47. }

  48. int Main()
  49. {
  50.     unsigned long dwDat;
  51.     leds_init();
  52.     buttons_init();

  53.     while (1)
  54.     {
  55.         dwDat=GPGDAT;
  56.         if(dwDat & (1<<0))
  57.             GPBDAT |=(1<<5);
  58.         else
  59.             GPBDAT &=~(1<<5);    

  60.         if(dwDat & (1<<3))
  61.             GPBDAT |=(1<<6);    
  62.         else
  63.             GPBDAT &=~(1<<6);    

  64.         if(dwDat & (1<<5))
  65.             GPBDAT |=(1<<7);
  66.         else
  67.             GPBDAT &=~(1<<7);    

  68.         if(dwDat & (1<<6))
  69.             GPBDAT |=(1<<8);    
  70.         else
  71.             GPBDAT &=~(1<<8);                
  72.     }

  73.     return 0;
  74. }

sdram.lds  //运行地址与实时分配

 

  1. SECTIONS {
  2.   firtst     0x00000000 : { start.o nand.o}
  3.   second     0x30001000 : AT(4096) { main.o }
  4. }

Makefile

 

  1. objs := start.o nand.o main.o

  2. nand_sdram.bin : $(objs)
  3.     arm-linux-ld -Tsdram.lds -o nand_sdram_elf $^
  4.     arm-linux-objcopy -O binary -S nand_sdram_elf $@
  5.     arm-linux-objdump -D -m arm nand_sdram_elf > nand_sdram.dis

  6. %.o:%.c
  7.     arm-linux-gcc -Wall -c -O2 -o $@ $<

  8. %.o:%.S
  9.     arm-linux-gcc -Wall -c -O2 -o $@ $<

  10. clean:
  11.     rm -f nand_sdram.dis nand_sdram.bin nand_sdram_elf *.o
以下为能直接运行的二进制文件,下载到Nand Flash 的 Black0 直接以Nand Flash运行。
阅读(2109) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~