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

uboot之nand flash相关(1)

发布时间:2020-12-15 17:58:59 所属栏目:百科 来源:网络整理
导读:这几天在做和nandflash相关的东西,之前uboot中nandflash部分搞得模模糊糊。这次就将uboot中nand flash相关部分分析清楚 。本文uboot版本1.3.3 按照uboot的执行流程,在lib_arm/board.c文件中的start_armboot函数中会调用到nand初始化。 初始化的调用流程大
这几天在做和nandflash相关的东西,之前uboot中nandflash部分搞得模模糊糊。这次就将uboot中nand flash相关部分分析清楚
。本文uboot版本1.3.3

按照uboot的执行流程,在lib_arm/board.c文件中的start_armboot函数中会调用到nand初始化。
初始化的调用流程大致为:
start_armboot
nand_init //driver/mtd/nand/nand.c
nand_init_chip //driver/mtd/nand/nand.c
board_nand_init //cpu/sep4020/nand_flash.c
nand_scan //driver/mtd/nand/nand_base.c
start_armboot函数中,nand初始化部分

点击(此处)折叠或打开

  1. #if?defined(CONFIG_CMD_NAND)?/*有nand的板都会定义CONFIG_CMD_NAND*/
  2. puts?("NAND: ");
  3. nand_init(;?*?go init the NAND?/
  4. #endif
nand_init()在driver/mtd/nand/nand.c文件中定义,此为nand初始化入口函数。

点击(此处)折叠或打开

  1. void nand_init(void)
  2. {
  3. int?i;
  4. unsigned?int?size?=?0;
  5. for?(i?;?i?<?CFG_MAX_NAND_DEVICE;?i+{?(1)
  6. nand_init_chip&nand_info[i],?&nand_chip(2)
  7. size?=?nand_info.size(3if?(nand_curr_device?==?-1)
  8. nand_curr_device?=?i}
  9. printf"%lu MiBn"/?(1024?*?1024;

  10. #ifdef CFG_NAND_SELECT_DEVICE
  11. *
  12. *?Select?the chip?in?the board/cpu specific driver
  13. /
  14. board_nand_select_device(nand_info[nand_curr_device.priv;
  15. #endif
  16. }
(1)CFG_MAX_NAND_DEVICE,nand的数量,一般板上有一个nand,就定义为1
(2)此函数初始化一个nand flash。首先看函数参数的3个变量。
参数1 nand_info[i],其定义如
nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; //driver/mtd/nand/nand.c
定义了一个nand_info_t类型的全局数组,当然这里其CFG_MAX_NAND_DEVICE等于1,只有一个成员,再看nand_info_t定义
typedef struct mtd_info nand_info_t; //include/Nand.h
mtd_info定义在include/linux/mtd/mtd.h中,它表示一个mtd设备的结构体,包含了mtd属性和其操作函数。

点击(此处)折叠或打开

  1. struct mtd_info?{
  2. u_char type;
  3. u_int32_t flags;
  4. u_int32_t size*?Total size of the MTD?/

  5. *?"Major"?erase?size?for?the device.?Na飗e users may take this
  6. to?be the only?erase?size availableor?may use the more detailed
  7. *?information below?if?they desire
  8. /
  9. u_int32_t erasesize;

  10. u_int32_t oobblock*?Size of OOB blocks?(e.g.?512/
  11. u_int32_t oobsize*?Amount of OOB data per block?.?16/
  12. u_int32_t oobavail*?Number of bytes?in?OOB area available?for?fs?/
  13. u_int32_t ecctype;
  14. u_int32_t eccsize;


  15. *?Kernel-only stuff starts here.?/
  16. char?*name;
  17. int?index;

  18. *?oobinfo?is?a nand_oobinfo structureset?by iotcl?(MEMSETOOBINFO/
  19. struct nand_oobinfo oobinfo*?Data?for?variable?erase?regionsIf?numeraseregions?is?zero*?it means that the whole device has erasesize as given above.
  20. /
  21. int?numeraseregions;
  22. struct mtd_erase_region_info?*eraseregions*?This really shouldn't be here.?It can go away?in?2.5?/
  23. u_int32_t bank_size;

  24. int?erase(struct mtd_info?*mtd*instr*?This stuff?for?eXecute-In-Place?*point?size_t?len*retlen*mtdbuf*?We probably shouldn't allow XIP?if?the unpoint isn't a?NULL?/
  25. void?*unpoint*?addr;


  26. *read*buf*writetoconst?u_char?*read_ecc*eccbuf*oobsel*write_ecc*read_oob*write_oob*?Methods?to?access the protection register areain?some
  27. *?flash devices.?The user data?is?one?time?programmable but the
  28. *?factory data?is?read only*read_user_prot_reg*read_fact_prot_reg*?This?function?is?not?yet implemented?*write_user_prot_reg*?Sync?*sync*?Bad block management functions?*block_isbad*block_markbad;

  29. void?*priv;

  30. struct module?*ownerint?usecount};
参数2 nand_chip[i] ,如下
static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE];
再看struct nand_chip定义,当前文件(driver/mtd/nand/nand.c)包含nand.h(include目录),nand.h又包含#include <linux/mtd/nand.h>,所以nand_chip的定义是linux/mtd/nand.h中的。不是nand_legacy.h。这个结构体表示一个nand flash其包含所有属性和操作函数。

点击(此处)折叠或打开

  1. *?struct nand_chip?-?NAND?Private?Flash Chip Data
  2. *?@IO_ADDR_R:?[BOARDSPECIFIC]?address?to?read the 8 I/O lines of the flash device
  3. *?@IO_ADDR_Wto?write the 8 I*?@read_byte[REPLACEABLE]?read one byte from the chip
  4. *?@write_byte]?write one byte?to?the chip
  5. *?@read_word]?read one word from the chip
  6. *?@write_word]?write one word?*?@write_buf]?write data from the buffer?*?@read_buf]?read data from the chip into the buffer
  7. *?@verify_buf]?verify buffer contents against the chip data
  8. *?@select_chip]?select?chip nr
  9. *?@block_bad]?checkif?the block?is?bad
  10. *?@block_markbad]?mark the block bad
  11. *?@hwcontrol]?hardwarespecific?for?accesing control-lines
  12. *?@dev_readyfor?accesing device ready/busy line
  13. If?set?to?NULL?no access?to?ready/busy?is?available?and?the ready/busy information
  14. is?read from the chip status register
  15. *?@cmdfuncfor?writing commands?*?@waitfuncfor?wait?on?ready
  16. *?@calculate_eccfor?ecc calculation?or?readback from ecc hardware
  17. *?@correct_datafor?ecc correctionto?ecc generator?(sw/hw*?@enable_hweccto?enable?(reset)?hardware ecc generator.?Must only
  18. *?be provided?if?a hardware ECC?is?available
  19. *?@erase_cmd[INTERNerase?command write?functionAND?support
  20. *?@scan_bbtto?scan bad block table
  21. *?@eccmode]?mode of ecc*?@eccsize]?databytes used per ecc-calculation
  22. *?@eccbytes]?number of ecc bytes per ecc-calculation?step
  23. *?@eccsteps]?number of ecc calculation steps per page
  24. *?@chip_delay]?chip dependent delay?for?transfering data from?array?to?read regs?(tR*?@chip_lock]?spinlock used?to?protect access?to?this structure?and?the chip
  25. *?@wq]?wait queue?to?sleep?on?if?a NAND operation?in?progress
  26. *?@state]?the current state of the NAND device
  27. *?@page_shift]?number of address bits?in?a page?(column address bits*?@phys_erase_shiftin?a physical eraseblock
  28. *?@bbt_erase_shiftin?a bbt entry
  29. *?@chip_shiftin?one chip
  30. *?@data_buf]?internal buffer?for?one page?+?oob
  31. *?@oob_buf]?oob buffer?for?one eraseblock
  32. *?@oobdirty]?indicates that oob_buf must be reinitialized
  33. *?@data_poi]?pointer?to?a data buffer
  34. *?@options]?various chip options.?They can partly be?to?inform nand_scan about
  35. *?special functionality.?See the defines?for?further explanation
  36. *?@badblockpos]?position of the bad block marker?in?the oob area
  37. *?@numchips]?number of physical chips
  38. *?@chipsize]?the size of one chip?for?multichip arrays
  39. *?@pagemask]?page number mask?=?number of?(pages?/?chip-?1
  40. *?@pagebuf]?holds the pagenumber which?is?currently?in?data_buf
  41. *?@autooob]?the default?(auto)placement scheme
  42. *?@bbt]?bad block table pointer
  43. *?@bbt_td]?bad block table descriptor?for?flash lookup
  44. *?@bbt_md]?bad block table mirror descriptor
  45. *?@badblock_pattern]?bad block scan pattern used?for?initial bad block scan
  46. *?@controller[OPTIONAL]?a pointer?to?a hardware controller structure which?is?shared among multiple independend devices
  47. *?@privprivate?chip?date
  48. /

  49. struct nand_chip?{
  50. void __iomem?*IO_ADDR_R;
  51. void __iomem?*IO_ADDR_W;

  52. u_char?*read_byte;
  53. void?*write_byte;
  54. u16?*read_word*write_word*write_bufint?*read_buf*verify_buf*select_chipint?chip*block_badint?getchip*hwcontrolint?cmd*dev_ready*cmdfuncint?columnint?page_addr*waitfunc*thisint?state*calculate_ecc*dat*ecc_code*correct_data*calc_ecc*enable_hweccint?mode*erase_cmdint?page*scan_bbtint?eccmodeint?eccsizeint?eccbytesint?eccstepsint?chip_delay;
  55. #if?0
  56. spinlock_t chip_lock;
  57. wait_queue_head_t wq;
  58. nand_state_t state;
  59. #endif
  60. int?page_shiftint?phys_erase_shiftint?bbt_erase_shiftint?chip_shift;
  61. u_char?*data_buf*oob_bufint?oobdirty*data_poiint?optionsint?badblockposint?numchips;
  62. unsigned long chipsizeint?pagemaskint?pagebuf;
  63. struct nand_oobinfo?*autooob;
  64. uint8_t?*bbt;
  65. struct nand_bbt_descr?*bbt_td*bbt_md*badblock_pattern;
  66. struct nand_hw_control?*controller 参数3 base_address[i],如下
static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST;
CFG_NAND_BASE_LIST如下,
#ifndef CFG_NAND_BASE_LIST
#define CFG_NAND_BASE_LIST { CFG_NAND_BASE }
#endif
CFG_NAND_BASE是在include/configs/UB4020.h中配置为
#define CFG_NAND_BASE 0x11000200 (nand FIFO 数据寄存器)
(3)计算出总共nandflash多少容量,在紧随其后的printf语句中打印出来。
接着看同文件(driver/mtd/nand/nand.c)中nand_init_chip函数的分析

点击(此处)折叠或打开

  1. static void nand_init_chip*nand{
  2. mtd>priv?=?nand;

  3. nand>IO_ADDR_R?>IO_ADDR_W?(void __iomem?)base_addr(board_nand_init(nand(nand_scan(mtd!mtd>name/这个名字在nand_scan中设置,如果在table中找到就有了。
  4. mtd>name?(char?)default_nand_name}?else
  5. mtdNULLelse?;
  6. mtd>size?}

  7. (1)从上面的nand_chip结构体中写道IO_ADDR_R,IO_ADDR_W是nand flash的读写地址, base_add这里设置为0x11000200,正好的nand FIFO的数据寄存器,读写flash的接口寄存器。
(2)此函数设置相关的nand 初始化,它和具体的体现结构有关系,不是共性的东西,在cpu/xxx/Nand_flash.c文件中。
(3) 此函数设置通用默认处理,获得flash id,并匹配等等。
这里我们分析的是sep4020 cpu的board_nand_init() 在cpu/sep4020/nand_flash.c

点击(此处)折叠或打开

  1. int?board_nand_init(?struct nand_chip?*chip?{
  2. memset)?chip?sizeof(struct nand_chip;

  3. INTC_IMR?=?0XFFFFFFFF(REGW(INTC_BASE+0X008)IRQ中断屏蔽寄存器 置1为屏蔽 0为通过
  4. INTC_IMR?=?0X00000000;?

  5. EMI_NAND_CONF1?=?0x06402857)
  6. EMI_NAND_CONF2?=?0x00d14353)

  7. vaddr?=?malloc(2112)
  8. oob64?;?
  9. memset(vaddr2112;
  10. memset(oob64int?erasepage*设置nand_chip结构中的各个函数指针/
  11. Set?address of NAND IO lines?/
  12. chip(void?)?EMI_NAND_DATA_RAW/设置nand flash读写寄存器地址,其实在调用函数中已经设置过了
  13. chipSet?address of hardware control?>hwcontrol?=?sep4020_hwcontrol*?15 us command delay?time?>dev_ready?=?sep4020_nand_dev_ready;
  14. chip>chip_delay?=?15>write_buf?=?sep4020_nand_write_buf>read_buf?=?sep4020_nand_read_buf>write_byte?=?sep4020_nand_write_byte>read_byte?=?sep4020_nand_read_byte>eccmode?=?NAND_ECC_SOFT>select_chip?=?sep4020_nand_select_chip;

  15. chip>cmdfunc?=?sep4020_nand_command>erase_cmd?=?sep4020_nand_cmd_erase*?Return happy?/
  16. return 0;
  17. (1)NAND FLASH的配置器存器1 110-0--100--000000--101000--0101--0111 可查看芯片手册,其中一项设置成5级地址
(2)NAND FLASH的配置器存器2 1--1--0--100--010100--0011--01--01--00--11 可查看芯片手册,页大小配置为2K
(3)分配一个整页空间,后续的读写操作中会用到它来暂存一页数据。

(编辑:李大同)

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

    推荐文章
      热点阅读