加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

bootloader---14.nand flash 读取bootloader

发布时间:2020-12-15 20:00:55 所属栏目:百科 来源:网络整理
导读:?一、 TQ2440上的nand flash是K9F2G08U0B 1.1 Page Block Device三者的关系(见datasheet P6) 1Page = (2k+64)Bytes 1Block = 64*Pages = 64*(2K+64)Byte=(128K+4k)Byte 1Device = 2048*Blocks = 2048*(64*Pages)Bytes 1.2 nand flash初始化 对于 K9F2G08U0A

?一、 TQ2440上的nand flash是K9F2G08U0B


1.1 Page Block Device三者的关系(见datasheet P6)

1Page = (2k+64)Bytes

1Block = 64*Pages = 64*(2K+64)Byte=(128K+4k)Byte

1Device = 2048*Blocks = 2048*(64*Pages)Bytes

1.2 nand flash初始化

对于K9F2G08U0A的初始化,几乎所有的帖子都说:需要TACLS+TWRPH0+TWRPH1>=46ns,(其中TACLS = tCLS(12)+tALS(12) ?TWRPH0 = tWP(12) ?TWRPH1 = tCLH(5)+tALH(5)),所以TACLS?=0,TWRPH0=3,TWRPH1=0,?+TWRPH0+TWRPH1=50ns,满足要求。

但是修改nand flash的初始化配置:将TACLS=0;TWRPH0=1;TWRPH1=0; 也是正常的。但是TACLS=0;TWRPH0=0;TWRPH1=1;就不正常了。这三者需要满足的关系十分不解,还望高手指教。

1.3?读取数据时地址的发送

从K9F2G08X0B 电路图中可以看出:

? ? ? ??

NCON = 1 ; // 1: Advance NAND flash(1KWords/2KBytes page size,4/5 address cycle)

GPG13 = 1 ; // 1: Page=2KBytes(NCON = 1)

GPG14 = 1 ;? // 1: 5 address cycle(NCON = 1)

GPG15 = 0 ;? // 0: 8-bit bus width

从上述硬件连接中可以看出,需要5个时钟周期才发送一个完整的地址。

上图中column address(A0-A11 12位) Row Address(A12-A28 17位)

column address:

? ? 即页内的地址(0-2112) 1Page=(2k+64)Bytes,所以需要12位,但实际上不访问后面64个字节的,所以只需要11位即可

Row Address:

? ? 页地址,一共有2048*64=0x20000个页,需要17位指定。

二、代码

root@ubuntu:~/myboot# tree

.├── main.c├── Makefile├── nand.c├── sdram.c├── start.S└── u-boot.lds

2.1 start.S

点击(此处)折叠或打开

  1. .text
  2. .global _start
  3. _start:
  4. _TEXT_BASE:
  5. ????.word 0x33d80000

  6. .globl _armboot_start
  7. _armboot_start:
  8. ????.word _start

  9. ????ldr r0,=0x53000000????
  10. ????mov r1,#0x0
  11. ????str r1,[r0]

  12. #define COCKTIME????0x4C000000????
  13. #define MPLLCON????????0x4C000004
  14. #define UPLLCON????????0x4C000008
  15. #define CLKCON????????0x4C00000C
  16. #define CLKSLOW????????0x4C000010
  17. #define CLKDIVN ????0x4C000014
  18. #define CAMDIVN ????0x4C000018
  19. ????/*FCLK:HCLK:PCLK=1:4:8*/
  20. ????ldr r0,=CLKDIVN
  21. ????mov r1,#0x05
  22. ????str r1,0)">
  23. ????mrc p15,r0,c1,c0,0
  24. ????orr r0,#0xc0000000
  25. ????mcr p15,0

  26. ????/*MPLL=(2*m*Fin)/(P*(1<<s)),m="(MDIV+8)," p="PDIV+2" s="SDIV*/
  27. ????ldr r0,=MPLLCON
  28. ????ldr r1,=((0x5C<<12)|(0x01<<4)|(0x01))
  29. ????str r1,[r0]
  30. ????
  31. ????ldr r0,=0x10000
  32. 1:
  33. ????sub r0,#1
  34. ????bne 1b

  35. ????/*UPLL=(m*Fin)/(P*(1<<s))," p="(PDIV+2)," s="SDIV*/
  36. ????ldr r0,=UPLLCON
  37. ????ldr r1,=((0x10<<12)|(0x01<<4)|(0x01))
  38. ????str r1,[r0]

  39. ????ldr r0,=0x10000
  40. 1:
  41. ????sub r0,#1
  42. ????bne 1b

  43. ????ldr sp,=1024*4
  44. ????bl init_sdram

  45. ????/*设置栈指向内存地址 (0x33d80000+128k)*/
  46. ????ldr sp,=0x33dA0000

  47. ????/*dest=0x33d80000 src=0x0 size=16k*/
  48. ????bl nand_init ;初始化nand flash
  49. ????ldr r0,=0x33d80000
  50. ????mov r1,#0x0
  51. ????ldr r2,=1024*16
  52. ????bl nand_read_page;将nand flash上的boot读到内存0x33d80000处,大小为16k
  53. ????
  54. ????ldr pc,_main;跳转到内存中的main中执行
  55. loop:
  56. ????b loop
  57. _main: .word main
2.2 nand.c


点击(此处)折叠或打开

  • #define NFCONF ???????? (*(volatile unsigned int *) 0x4E000000)
  • #define NFCONT ???????? (*(volatile unsigned int *) 0x4E000004)
  • #define NFCMMD ???????? (*(volatile unsigned int *) 0x4E000008)
  • #define NFADDR ???????? (*(volatile unsigned int *) 0x4E00000C)
  • #define NFDATA ???????? (*(volatile unsigned char *) 0x4E000010) //注意:类型char
  • #define NFMECCD0 ???? (*(volatile unsigned int *) 0x4E000014)
  • #define NFMECCD1 ???? (*(volatile unsigned int *) 0x4E000018)
  • #define NFSECCD ???? (*(volatile unsigned int *) 0x4E00001C)
  • #define NFSTAT ???????? (*(volatile unsigned int *) 0x4E000020)
  • #define NFESTAT0 ???? (*(volatile unsigned int *) 0x4E000024)
  • #define NFESTAT1 ???? (*(volatile unsigned int *) 0x4E000028)
  • #define NFMECC0 ???? (*(volatile unsigned int *) 0x4E00002C)
  • #define NFMECC1 ???? (*(volatile unsigned int *) 0x4E000030)
  • #define NFMECC ???????? (*(volatile unsigned int *) 0x4E000034)
  • #define NFSBLK ???????? (*(volatile unsigned int *) 0x4E000038)
  • #define NFEBLK ???????? (*(volatile unsigned int *) 0x4E00003C)

  • /*nand command */
  • #define NAND_CMD_RESET ????0xFF

  • #define NAND_PAGE_SIZE????2048
  • #define NAND_PAGE_MASK????(NAND_PAGE_SIZE-1)

  • static void nand_chip_select(void)
  • {
  • ????int i;
  • ????NFCONT &= ~(1<<1);
  • ????for(i=0; i<10; i++);
  • }

  • static void nand_chip_deselect(void)
  • {
  • ????NFCONT |= (1<<1);
  • }

  • static void nand_write_cmd(unsigned char cmd)
  • {
  • ????NFCMMD = cmd;
  • }

  • static void nand_write_addr(unsigned int addr)
  • {
  • ????int col,page;
  • ????int i;
  • ????col = addr & NAND_PAGE_MASK;
  • ????page = addr / NAND_PAGE_SIZE;
  • ????
  • ????NFADDR = col & 0xff;????????????/* Column Address A0~A7 */
  • ????for(i=0; i<10; i++);????????
  • ????NFADDR = (col >> 8) & 0x0f;????????/* Column Address A8~A11 */
  • ????for(i=0; i<10; i++);
  • ????NFADDR = page & 0xff;????????????/* Row Address A12~A19 */
  • ????for(i=0; i<10; i++);
  • ????NFADDR = (page >> 8) & 0xff;????/* Row Address A20~A27 */
  • ????for(i=0; i<10; i++);
  • ????NFADDR = (page >> 16) & 0x03;????/* Row Address A28~A29 */
  • ????for(i=0; i<10; i++);
  • }

  • static void nand_wait_idle(void)
  • {
  • ????while( !(NFSTAT & 0x01))
  • ????????;
  • }

  • static void nand_reset(void)
  • {
  • ????nand_chip_select();
  • ????nand_write_cmd(NAND_CMD_RESET);
  • ????nand_wait_idle();
  • ????nand_chip_deselect();
  • }

  • static unsigned char nand_read_byte(void)
  • {
  • ????return (NFDATA&0xFF);
  • }

  • void nand_init(void)
  • {
  • #define TACLS????0x0
  • #define TWRPH0 ????0x03
  • #define TWRPH1 ????0x0
  • ????NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
  • ????NFCONT = (0x01<<4)|(0x01<<1)|(0x01<<0);
  • ????nand_reset();//初次使用时要先复位一下
  • }

  • /*调用这个函数时要保证size是按页对齐的*/
  • void nand_read_page(unsigned char * dest_addr,unsigned long src_addr,unsigned int size)
  • {
  • ????int i,j;

  • ????NFCONT &= ~(1<<1);
  • ????for(i=0; i<10; i++);
  • ????for(i=0; i<size (nand_page_size);="" i++)="" <="" li="" style="word-wrap: break-word;">
  • ????{
  • ????????nand_write_cmd(0x00);
  • ????????nand_write_addr(src_addr+i*NAND_PAGE_SIZE);
  • ????????nand_write_cmd(0x30);
  • ????????nand_wait_idle();
  • ????????//read one block
  • ????????for(j=0; j<nand_page_size; j++)="" <="" li="" style="word-wrap: break-word;">
  • ????????{
  • ????????????*dest_addr = nand_read_byte();
  • ????????????dest_addr ++;
  • ????????}
  • ????}
  • ????nand_chip_deselect();
  • }
  • 对于nand flash的 NFDATA 寄存器定义时要特别注意,是char而不是int。

    2.3 main.c

    点击(此处)折叠或打开

  • #define GPBCON?(*(volatile unsigned?int?)?0x56000010)
  • #define GPBDAT?)?0x56000014)

  • static inline void delay?(unsigned long loops)
  • {
  • ????__asm__ volatile?("1:n"
  • ????????????"subs %0,%1,#1n"
  • ????????????"bne 1b":"=r"?(loops)"0"?;
  • }

  • /*?led流水灯?/
  • void main(void{
  • ????int?i?=?1;
  • ????GPBCON?=?0x15400;

  • ????while(1)
  • ????{
  • ????????GPBDAT?=?0x7FF&~i<<5;
  • ????????i?=?2;
  • ????????if(16==i)
  • ????????????i?;
  • ????????delay(400000;
  • ????}
  • ????return?}
  • 2.4 sdram.c 没有改动
    2.5 Makefile中OBJS := ?start.o sdram.o nand.o main.o

    ?myboot_nand.rar?? (使用时要将后缀名改为 .tar.gz)

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读