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

bootloader---23.u-boot-2010.06-rc1移植之3nand flash移植

发布时间:2020-12-15 20:00:53 所属栏目:百科 来源:网络整理
导读:增加nand flash 特性 当可以正常启动serial可以显示之后,接下来移植nand flash 1. nand flash的初始化是在 arch/arm/lib/board.c中 arch / arm / lib / board . c? start_armboot? { ????# if ?defined ( CONFIG_CMD_NAND ) ???? ????puts? ( "NAND: " ) ;
增加nand flash 特性

当可以正常启动serial可以显示之后,接下来移植nand flash
1. nand flash的初始化是在 arch/arm/lib/board.c中
  1. arch/arm/lib/board.c?
  2. start_armboot?
  3. {
  4. ????#if?defined(CONFIG_CMD_NAND)????
  5. ????puts?("NAND: ");
  6. ????nand_init(;????????/*?go init the NAND?*/
  7. ????#endif
  8. }
所以需要在include/configs/smdk2410.h中添加: ? #define CONFIG_CMD_NAND ??1

2.nand的初始化

  • #ifndef CONFIG_SYS_NAND_BASE_LIST
  • #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
  • #endif
  • static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
  • //base_address初始化为CONFIG_SYS_NAND_BASE
  • 所以需要在include/configs/smdk2410.h中添加:?#define CONFIG_SYS_NAND_BASE??0x4E000000
  • void nand_init(void)
  • {
  • ????int?i;
  • ????unsigned?int?size?=?0;
  • ????for?(i?;?i?<?CONFIG_SYS_MAX_NAND_DEVICE;?i+)?
  • ? ? {?
  • //CONFIG_SYS_MAX_NAND_DEVICE=1所以只需要进行一次nand_init_chip
  • //初始化nand的
  • ? ? ? ? nand_init_chip&nand_info[i],?&nand_chip;
  • ????????size?=?nand_info.size?/?1024;
  • ????????if?(nand_curr_device?==?-1)
  • ????????????nand_curr_device?=?i}
  • ????printf"%u MiBn";
  • }


  • 3. driver/mtd/nand/nand.c L42
      static void nand_init_chip(struct mtd_info?*mtd*nand
    1. ???????????? ulong base_addr)
    2. {
    3. ????int?maxchips?=?CONFIG_SYS_NAND_MAX_CHIPS;
    4. ????int?__attribute__(unused)?i?;

    5. ????(maxchips?<?1)
    6. ????????maxchips?=?1;
    7. ????mtd->priv?=?nand; //以后要用到nand来控制底层寄存器,这儿先保存起nand来,这个非常重要

    8. ????nand>IO_ADDR_R?>IO_ADDR_W?(void __iomem?)base_addr;//初始化读写指针为0x4E000000,以后真正读写时指针要改变
    9. ????(board_nand_init(nand)?{ //board_nand_init寄存器纸别的初始化
    10. ????????(nand_scan(mtd{ //
    11. ????????????!mtd>name)
    12. ????????????????mtd>name?(char?)default_nand_name;
    13. ? ? ? ??}?else
    14. ????????????mtdNULL;
    15. ????else?{
    16. ????????mtd;
    17. ????????mtd>size?}

    18. }
    4. drivers/mtd/nand/s3c2410_nand.c
    //
  • int?board_nand_init(struct nand_chip?)
  • {
  • ????u_int32_t cfg;
  • ????u_int32_t cnt;
  • ????u_int8_t tacls?twrph1;
  • ????struct s3c2440_nand?*nand_reg?=?s3c2440_get_base_nand;

  • ????debugX(1"board_nand_init()n";

  • ? ??*?initialize hardware?/
  • ????tacls?;
  • ????twrph0?=?4;
  • ????twrph1?=?2;

  • ????cfg?|=?S3C2440_NFCONF_TACLS(tacls;
  • ????cfg?=?S3C2440_NFCONF_TWRPH0(twrph0=?S3C2440_NFCONF_TWRPH1(twrph1;
  • ????writel(cfg&nand_reg>NFCONF/NAND Flash control register
  • ????/bit6:?Lock spare ECC
  • ????/bit4:?Initialize ECC decoder/encoder
  • ????/bit1:?enable chip_select
  • ????/bit0:?nand_enable
  • ????cnt =(1<<6)| (1<<4)|(0<<1)|(1<<0);
  • ????writel(cnt,&nand_reg->NFCONT); //不仅需要配寄存器NFCONF,而且需要配寄存器NFCONT
  • ? ? ??
    ? ? ??//以下初始化函数指针
    1. ????*?initialize nand_chip data structure?/
    2. ????nand(void?>NFDATA;

    3. ????nand>select_chip?=?s3c2440_nand_select_chip*?hwcontrol always must be implemented?>cmd_ctrl?=?s3c2440_hwcontrol>dev_ready?=?s3c2440_dev_ready>ecc.mode?=?NAND_ECC_SOFT //进行软件的ECC校验

    4. ????nand>options? //BUS_WIDTH 8位

    5. ????debugX"end of nand_initn";

    6. ????return 0;
    7. }
    这儿调用了s3c2440_get_base_nand,需要在include/asm/arch-s3c24x0/s3c2410.h中添加这个函数
  • #define S3C24X0_NAND_BASE????????0x4E000000
  • static inline struct s3c2440_nand *s3c2440_get_base_nand(void)
  • {
  • ????return (struct s3c2440_nand *)S3C24X0_NAND_BASE;
  • }
  • 同时 S3C2440_NFCONF_TACLS等这几个宏跟手册上的位置不匹配,所以修改一下
    #define S3C2440_NFCONF_TACLS(x)? <<12)
  • #define S3C2440_NFCONF_TWRPH0 <8)
  • #define S3C2440_NFCONF_TWRPH1<4)

  • #define S3C2440_NFCONT_nCE ????<1)
  • #define S3C2440_NFCONT_MODE_DISABLE????(0<0)
  • #define S3C2440_NFCONT_MODE_ENABLE????)

  • #define S3C2440_NFSTAT_READY ????)

  • #define S3C2440_ADDR_NALE? 0x0C
  • #define S3C2440_ADDR_NCLE? 0x08
  • 5. driver/mtd/nand/nand_base.c L3061
    start_armboot-> nand_init->nand_init_chip
  • int?nand_scanint?maxchipsint?ret;
  • ????ret?=?nand_scan_ident!ret)
  • ????????ret?=?nand_scan_tail;
  • ????return ret}
  • 6. driver/mtd/nand/nand_base.c ? ?L2770
    start_armboot-> nand_init->nand_init_chip->nand_scan
  • int?nand_scan_ident?nand_maf_id;
  • ????struct nand_chip?*chip?=?mtd>priv;//函数nand_init_chip中保存的nand_chip结构体
  • ????struct nand_flash_dev?*type*?Get?buswidth?to?select?the correct functions?/
  • ????busw?=?chip&?NAND_BUSWIDTH_16
  • ????Set?the default functions?/
  • ????nand_set_defaults(chip //对nand_chip结构体进一步初始化

  • ????*?Read the flash type?/
  • ????type?=?nand_get_flash_type&nand_maf_id(IS_ERR(type{
  • #ifndef CONFIG_SYS_NAND_QUIET_TEST
  • ????????printk(KERN_WARNING?"No NAND device found!!!n";
  • #endif
  • ????????chip>select_chip;
  • ????????return PTR_ERR}

  • ????*?Check?for?a chip?array?/
  • ????<?maxchips{
  • ????????chip;
  • ????????*?See comment?in?nand_get_flash_type?for?reset?/
  • ????????chip>cmdfunc*?Send the command?for?reading device ID??0x00*?Read manufacturer?and?device IDs?/
  • ????????(nand_maf_id?!>read_byte|
  • ???????? type>id?)
  • ????????????break}
  • #ifdef DEBUG
  • ????>?1)
  • ????????printk(KERN_INFO?"%d NAND chips detectedn";
  • #endif

  • ????*?Store the number of chips?and?calc total size?for?mtd?/
  • ????chip>numchips?=?i?*?chip>chipsize}
  • 6. driver/mtd/nand/nand_base.c ? ?L2555
    start_armboot>?nand_init>nand_init_chip>nand_scan-->nand_scan_ident
  • //设置默认的函数指针
  • static void nand_set_defaults*chipint?busw{
  • ????*?check?for?proper chip_delay setupset?20us?not?!chip>chip_delay)
  • ????????chip>chip_delay?=?20 //设置延时=20

  • ????*?checkif?a user supplied command?function?given?>cmdfunc?=?nand_command //cmd_func=nand_command,以后就靠它发命令了

  • ????if?a user supplied wait?>waitfunc?=?nand_wait //nand_wait

  • ????=?nand_select_chip //不进入
  • ????>read_byte?=?busw???nand_read_byte16?:?nand_read_byte; //read_byte=nand_read_byte
  • ????>read_word>read_word?=?nand_read_word //read_word=nand_read_word
  • ????>block_bad>block_bad?=?nand_block_bad>block_markbad>block_markbad?=?nand_default_block_markbad>write_buf>write_buf???nand_write_buf16?:?nand_write_buf>read_buf>read_buf???nand_read_buf16?:?nand_read_buf>verify_buf>verify_buf???nand_verify_buf16?:?nand_verify_buf>scan_bbt>scan_bbt?=?nand_default_bbt>controller>controller?&chip>hwcontrol;

  • ????????*?XXX U-BOOT XXX?/
  • #if?0
  • ????????spin_lock_init>lock;
  • ????????init_waitqueue_head>wq;
  • #endif
  • ????}
  • 7.??driver/mtd/nand/nand_base.c ? ?L2603
    *
  • ?Get?the flash?and?manufacturer id?and?lookup?if?the type?is?supported
  • ?/
  • static struct nand_flash_dev?*nand_get_flash_typeint?*maf_id)
  • {
  • ????struct nand_flash_dev?*type??maf_idxint?tmp_id;
  • ? ? ? //以下是读取设备ID的过程:参见K9F2G08U0B的datasheet
    ? ? ? //1. 发送命令0x90 ? 2.发送地址0x00 ?3.读取第一个字节为manufacturer 第二个字节为DEV_ID??
      Select?the device: 设置NFCONT D1=0?*
    1. ?????*?Reset the chip(e.g.?Micron MT29FxGxxxxx)
    2. ?????*?after power-up
    3. ?????/
    4. ? ? //调用nand_command-->s3c2440_hwcontrol向nandflash的NFCMMD寄存器发送0xFF(RESET指令)
    5. ????chip? ??//1. 发送命令0x90 ? 2.发送地址0x00 ? ?
    6. ????chip? ? //返回的第一个字节为0xEC 第二个字节为0xDA
    7. ????*maf_id?;
    8. ????dev_id?*?Try again?to?make sure-hold?or?other
    9. ?????*?interface concerns can cause random data which looks like a
    10. ?????*?possibly credible NAND flash?to?appear.?If?the two results?do
    11. ?????not?match.
    12. ?????? ? ?//重新读取,验证第一次读取的结果是正确的
    13. ????chip/

    14. ????tmp_manf?;
    15. ????tmp_id?(tmp_manf?|?tmp_id?=?dev_id{
    16. ????????printk"%s: second ID read did not match "
    17. ?????????"%02x,%02x against %02x,%02xn"
    18. ?????????;
    19. ????????return ERR_PTR-ENODEV}
    20. ? ? //从nand_flash_ids表中查找 id=0xDA的项
    21. ? ? // ? name ? ? ? ? ? ? ? ? ? ? ?id ??pagesize?chipsize?erasesize?options
    22. ? ? //? {"NAND 256MiB 3,3V 8-bit",?0xDA,? ? ? ?256,? ? 0,? ? ? LP_OPTIONS},
    23. ????*?Lookup the flash id?;?nand_flash_ids.name?{
    24. ????????(dev_id?=?nand_flash_ids.id{
    25. ????????????type?&nand_flash_ids;
    26. ????????????break}
    27. ????!type)
    28. ????????return ERR_PTR)
    29. ????????mtd=?type
    30. ? ? //设定chipsize=256M=256<<20
    31. ????chip>chipsize?(uint64_t)type<?20*?Newer devices have all the information?in?additional id bytes?>pagesize{
    32. //根据K9F2G08U0B的datasheet P29
    33. ????????int?extid*?The 3rd id byte holds MLC?/?multichip data?>cellinfo? //cellinfo=0x10
    34. ????????*?The 4th id byte?is?the important one?/
    35. ????????extid? //extid=0x95
    36. ????????* Calc pagesize,extid的D0-D1是pagesize*/
    37. ????????mtd>writesize?=?1024?<?(extid?&?0x3;
    38. ????????extid?>/* Calc oobsize ?extid的D2位的单位是byte/512byte,所以求oob,需要乘pagesize/512?*/
    39. ????????mtd>oobsize?(8?&?0x01>?9;
    40. ????????/* Calc blocksize. Blocksize is multiples of 64KiB,求block_size,exit的D4-D5位是1的话对应128K的block_size*/
    41. ????????mtd>erasesize?(64?*?1024&?0x03/* Get buswidth information: extid的D6位是buswidth 0--8位的buswidth?*/
    42. ????????busw???NAND_BUSWIDTH_16?:?0*
    43. ?????????*?Old devices have chip data hardcoded?in?the device id table
    44. ?????????/
    45. ????????mtd>erasesize/?32;
    46. ????????busw?*?Try?to?identify manufacturer?(maf_idx?;?nand_manuf_ids[maf_idx.id?=?0x0;?maf_idx(nand_manuf_ids*?Checkif?buswidth?is?correct.?Hardware drivers should?set
    47. ?????*?chip correct?!
    48. ?????(busw?"NAND device: Manufacturer ID:"
    49. ?????????" 0x%02x,Chip ID: 0x%02x (%s %s)n"
    50. ???????? dev_id.name;
    51. ????????printk"NAND bus width %d instead %d bitn"??16?:?8
    52. ???????? busw?-EINVAL*?Calculate the address shift from the page size?>page_shift?=?ffs>writesize-?1*?Convert chipsize?to?number of pages per chip?>pagemask?>?chip>page_shift;

    53. ????chip>bbt_erase_shift?>phys_erase_shift?=
    54. ????????ffs&?0xffffffff>chip_shift?(unsigned)chipelse
    55. ????????chip>?32+?31Set?the bad block position?>badblockpos?>?512??
    56. ????????NAND_LARGE_BADBLOCK_POS?:?NAND_SMALL_BADBLOCK_POSGet?chip options&~NAND_CHIPOPTIONS_MSK;
    57. ????chip&?NAND_CHIPOPTIONS_MSKSet?chip as a default.?Board drivers can override itif?necessary
    58. ?????=?NAND_NO_AUTOINCRif?chip?is?a?not?a samsung deviceDo?not?clear the
    59. ?????*?options?for?chips which are?not?having an extended id=?NAND_MFR_SAMSUNG?&?~NAND_SAMSUNG_LP_OPTIONSAND?chips with 4 page planes?&?NAND_4PAGE_ARRAY>erase_cmd?=?multi_erase_cmd=?single_erase_cmdnot?replace?user supplied command?function?!?&?chip=?nand_command_lp;

    60. ????MTDDEBUG?(MTD_DEBUG_LEVEL0"NAND device: Manufacturer ID:"
    61. ?????
    62. ???? nand_manuf_ids;

    63. ????return type}



    2. 在include/configs/smdk2410.h中添加
    #define CONFIG_CMD_NAND ?? 1
    #define CONFIG_SYS_MAX_NAND_DEVICE ? 1
    #define CONFIG_SYS_NAND_BASE ??? 0x4E000000

    3.start_armboot--> nand_init 在driver/mtd/nand/nand.c中

    nand_init-->nand_init_chip-->board_nand_init

    4. board_nand_init函数在driver/mtd/nand/s3c2410_nand.c中
    不过这需要在?include/configs/smdk2410.h中添加
    #define CONFIG_NAND_S3C2410 1
    5.删除多余的文件
    root@ubuntu:~/u-boot-2010.06-rc1/drivers/mtd/nand# rm atmel_nand.c bfin_nand.c davinci_nand.c fsl_elbc_nand.c fsl_upm.c kb9202_nand.c kirkwood_nand.c kmeter1_nand.c mpc5121_nfc.c mxc_nand.c ndfc.c nomadik.c ?s3c64xx.c spr_nand.c omap_gpmc.c nand_plat.c?
    同时在driver/mtd/nand/Makefile中删除多余的东东,不删也没有关系。
    root@ubuntu:~/uboot/u-boot-2010.06-rc1# vi drivers/mtd/nand/Makefile?
    6. 这里候就可以编译通过了,不过打印的是
    DRAM: ?64 MiB
    Flash: 512 KiB
    NAND: ?No NAND device found!!!
    0 MiB
    *** Warning - bad CRC,using default environment

    7. 修改一下driver/mtd/nand/s3c2410_nand.c中的board_nand_init函数
    a.将driver/mtd/nand/s3c2410_nand.c中所有的2410替换为2440
    8. 在include/asm/arch-s3c24x0/s3c2410.h中添加
    #define S3C24X0_NAND_BASE 0x4E000000

    static inline struct s3c2440_nand *s3c2440_get_base_nand(void)
    {
    return (struct s3c2440_nand *)S3C24X0_NAND_BASE;
    }
    9.?在driver/mtd/nand/s3c2410_nand.c中
      )
    1. {
    2. ????u_int32_t cfg;
    3. ????u_int32_t cnt;
    4. ????u_int8_t tacls;
    5. ????struct s3c2440_nand?;

    6. ????debugX;

    7. ????/writel(readl&clk_power>CLKCON|?(1?<?4/
    8. ????tacls?;
    9. ????twrph0?;
    10. ????twrph1?;

    11. ????cfg?;
    12. ????cfg?;
    13. ????writel/NAND Flash control register
    14. ????:?Lock spare ECC
    15. ????/encoder
    16. ????:?enable chip_select
    17. ????:?nand_enable
    18. ????cnt?<6(cnt>NFCONT/
    19. ????nand;

    20. ????nand;

    21. ????return 0;
    22. }

    (编辑:李大同)

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

      推荐文章
        热点阅读