uboot norflash 驱动移植

本文介绍如何在U-Boot 1.1.6中移植NorFlash驱动以支持SSTVF16012MB芯片。主要内容包括:修改配置文件以启用SSTVF16012MB支持,调整flash.c中的函数实现,以及更新flash.h以增加对新芯片的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无意中想起前一段时间在优酷上放了个关于mdk调试ro base的设置,上去优酷"巡查"了一翻.看到竟然有一个评价心里乐滋滋的总算有一个同学给于我肯定!so昨天写 mirco2440移植u-boot-1.1.6 (一)写到一点也觉得没啥所谓了...因为我得到肯定!

 

        费话小说,这个教程目的也很明确:我们的uboot识别出Nor Flash(mirco 2440上的Nor Flash 是SST VF1601 2MB)并能对Nor Flash进行写操作!(未识别出Nor Flash uboot 并不能对Nor Flash进行写操作).当然我们这是在uboot能在mirco 2440跑起来的基础(跑不起来的可参考http://blog.163.com/ds_liang/blog/static/1619822122010511114351608/ )上做进行的.

1)很不幸uboot-1.1.6不支持SST V1601芯片,我们必须自己写相关的函数(幸好board/dave开发板中有相关代码我们复制过来做一点修改就行了)

$ cp board/dave/common/flash.c board/ds_liang2440/flash.c
$ vi board/dave/B2/flash.c

把 board/dave/B2/flash.c 中的unsigned long flash_init (void)函数拷贝到board/ds_liang2440/flash.c文件的最后,把条件编译去掉

  

          dest2[i] = data2[i];

            /* re-enable interrupts if necessary */
            if (flag)
              enable_interrupts();

            /* data polling for D7 */
            start = get_timer (0);
            while ((dest2[i] & (CFG_FLASH_WORD_SIZE)0x00800080) !=
                   (data2[i] & (CFG_FLASH_WORD_SIZE)0x00800080)) {
              if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
                return (1);
              }
            }
          }

        return (0);
}

/*-----------------------------------------------------------------------
 */

unsigned long flash_init (void)
{

// #ifdef __DEBUG_START_FROM_SRAM__
//       return CFG_DUMMY_FLASH_SIZE;
//#else


        unsigned long size_b0;
        int i;

        /* Init: no FLASHes known */
        for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
                flash_info[i].flash_id = FLASH_UNKNOWN;
        }

        /* Static FLASH Bank configuration here - FIXME XXX */

        size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);

        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
                printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
                        size_b0, size_b0<<20);
        }

        /* Setup offsets */
        flash_get_offsets (0, &flash_info[0]);

        /* Monitor protection ON by default */
        (void)flash_protect(FLAG_PROTECT_SET,
                            -CFG_MONITOR_LEN,
                            0xffffffff,
                            &flash_info[0]);

        flash_info[0].size = size_b0;

        return (size_b0);

// #endif
}

 

2)因为本来uboot默认使用amd_lv400,我们把它去了加上SST VF1601的配置

$ vi include/configs/ds_liang2440.h
令:

#define CONFIG_AMD_LV400        1       /* uncomment this if you have a LV400 flash */
#if 0
#define CONFIG_AMD_LV800        1       /* uncomment this if you have a LV800 flash */
#endif
为:

#define CONFIG_SST_VF160        1      

 

#ifdef  CONFIG_SST_VF160

#define PHYS_FLAHS_SIZE         0x00200000

#define CFG_MAX_FLASH_SECT      (32)

#define CFG_ENV_ADDR            (CFG_FLASH_BASE + 0x030000)

#define FLASH_BANK_SIZE         0x01000000

#define CFG_FLASH_ADDR0         0x5555

#define CFG_FLASH_ADDR1         0x2AAA

#define CFG_FLASH_WORD_SIZE     unsigned short

#define CFG_FLASH_READ0         0x0000

#define CFG_FLASH_READ1         0x0001

#define CFG_FLASH_READ2         0x0002

#define CFG_MONITOR_LEN         (256*1024)

#define CFG_MONITOR_BASE        TEXT_BASE

#endif


#if 0

#define CONFIG_AMD_LV400        1       /* uncomment this if you have a LV400 flash */
#define CONFIG_AMD_LV800        1       /* uncomment this if you have a LV800 flash */
#endif

3)修改flash.c中的函数

$ vi board/ds_liang2440/flash.c

在flash_erase函数中

令:

if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
                        addr2[0] = (CFG_FLASH_WORD_SIZE)0x00500050;  /* block erase */
为:

if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0080;
                        addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
                        addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
                        addr2[0] = (CFG_FLASH_WORD_SIZE)0x0050;  /* block erase */

令:

 if (sect == s_first) {
                            addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
                            addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
                            addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
                            addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
                            addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
                        }
                        addr2[0] = (CFG_FLASH_WORD_SIZE)0x00300030;  /* sector erase */
为:

 if (sect == s_first) {
                            addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
                            addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
                            addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0080;
                            addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
                            addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
                        }
                        addr2[0] = (CFG_FLASH_WORD_SIZE)0x0030;  /* sector erase */

令:

 addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);
        while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x00800080) != (CFG_FLASH_WORD_SIZE)0x00800080)

为:

 addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);
        while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x0080) != (CFG_FLASH_WORD_SIZE)0x0080)

令:

        addr[0] = (CFG_FLASH_WORD_SIZE)0x00F000F0;      /* reset bank */
为:

        addr[0] = (CFG_FLASH_WORD_SIZE)0x00F0;      /* reset bank */

在flash_get_size函数中:

令:

        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
        addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00900090;

为:

        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
        addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
        addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0090;

  在第二个switch中加入:

case (CFG_FLASH_WORD_SIZE)SST_ID_xF1601:
                info->flash_id += FLASH_SST1601;
                info->sector_count = 32;
                info->size = 0x00200000;
                break;  

 

在write_buff函数中:

令全部#ifdef CONFIG_B2改写为#ifdef CONFIG_SMDK2410

 

在flash_print_info函数中:

switch个添加

case FLASH_SST1601:      printf ("SST39LF/VF1601(16 Mbit, bottom boot sect)\n");
                                break;

4)在include/flash.h中添加

#define FLASH_SST1601 0x0048

(加在SST那组)

 

Nor Flash驱动就到此结束了

$ make clean

$ make ds_liang2440_config

$ make all

当前目录生成的u-boot.bin文件支持nor flash 的写操作

串口输出中多了

如:

pro off all

//解除保护,不解除不能进行擦除操作

erase all


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值