准备分析
资源工具
着手写程序
(1) void board_init_f_nand ((unsigned long bootflag)) ,负责调用copy_uboot_to_ram_nand()和uboot = (void *)0xd0024010;
(2) int copy_uboot_to_ram_nand (void),判断NandFlash类型页的大小。调用int nandll_read_blocks。
(3) int nandll_read_blocks (ulong dst_addr, ulong size, int large_block),读一块大小。
(4) int nandll_read_page (uchar *buf, ulong addr, int large_block),读一页大小,并通过串口打印出NFDATA8_REG寄存器的值。
具体的实现:
- void board_init_f_nand(unsigned long bootflag)
- {
- __attribute__((noreturn)) void (*uboot)(void);
- copy_uboot_to_ram_nand();
- /* Jump to U-Boot image */
- uboot = (void *)0xd0024010;
- (*uboot)();
- /* Never returns Here */
- }
- int copy_uboot_to_ram_nand (void)
- {
- int large_block = 0;
- int i;
- vu_char id;
- NAND_CONTROL_ENABLE();
- NAND_ENABLE_CE();
- NFCMD_REG = NAND_CMD_READID;
- NFADDR_REG = 0x00;
- /* wait for a while */
- for (i=0; i<200; i++);
- id = NFDATA8_REG;
- id = NFDATA8_REG;
- if (id > 0x80)
- large_block = 1;
- if(id == 0xd5)
- { //page_size = 8k
- large_block = 3;
- }
- /* read NAND Block.
- * 128KB ->240KB because of U-Boot size increase. by scsuh
- * So, read 0x3c000 bytes not 0x20000(128KB).
- */
- //return nandll_read_blocks(CONFIG_SYS_TEXT_BASE, COPY_BL2_SIZE, large_block);
- return nandll_read_blocks(0xd0024000, 0x4000, large_block);
- }
- /*
- * Read data from NAND.
- */
- static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
- {
- uchar *buf = (uchar *)dst_addr;
- int i;
- uint page_shift = 9;
- if (1 == large_block)
- {
- page_shift = 11;
- /* Read pages */
- for (i = (0x6000>>page_shift); i < (size>>page_shift); i++, buf+=(1<<page_shift))
- {
- nandll_read_page(buf, i, large_block);
- }
- }
- else if(3 == large_block)
- {
- page_shift = 13;
- for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1)))
- {
- nandll_read_page(buf, i, large_block-1);
- }
- }
- return 0;
- }
- /*
- * address format
- * 17 16 9 8 0
- * --------------------------------------------
- * | block(12bit) | page(5bit) | offset(9bit) |
- * --------------------------------------------
- */
- static int nandll_read_page (uchar *buf, ulong addr, int large_block)
- {
- int i;
- volatile char c;
- int page_size = 512;
- if (1 == large_block)
- page_size = 2048;
- else if (2 == large_block)
- page_size = 4096;
- else if (3 == large_block)
- page_size = 8192;
- NAND_ENABLE_CE();
- NFCMD_REG = NAND_CMD_READ0;
- /* Write Address */
- NFADDR_REG = 0;
- if (large_block)
- NFADDR_REG = 0;
- NFADDR_REG = (addr) & 0xff;
- NFADDR_REG = (addr >> 8) & 0xff;
- NFADDR_REG = (addr >> 16) & 0xff;
- if (large_block)
- NFCMD_REG = NAND_CMD_READSTART;
- NF_TRANSRnB();
- /* for compatibility(2460). u32 cannot be used. by scsuh */
- for(i=0; i < page_size; i++)
- {
- c = NFDATA8_REG;
- *buf++ = c;
- puthex(c);
- putc(' ');
- }
- NAND_DISABLE_CE();
- return 0;
- }
下载运行
同《
S5PV210的LED应用(一)》
运行调试
对比如图所示:
得到结论,前16k代码在NandFlash存储方式如下: