3.移植uboot-使板卡支持nor、nand

发布者:剑戟辉煌最新更新时间:2021-07-30 来源: eefocus关键字:移植  uboot  nor  nand 手机看文章 扫描二维码
随时随地手机看文章

在上一章,我们添加了nor,nand启动后,uboot启动出如下图所示:

上面的Flash: *** failed *** 是属于uboot第二阶段函数board_init_r()里的代码, 代码如下所示(位于arch/arm/lib/board.c):


/*第二阶段*/

void board_init_r(gd_t *id, ulong dest_addr)        //gd    uboot重定位地址

{

     ... ...

  puts("Flash: ");                        //打印flash:

  flash_size = flash_init();                    //初始化nor_flash

  if (flash_size > 0)

  {

       ... ...

       print_size(flash_size, "n");            //打印nor_flash的大小

  }

  else

  {

    puts(failed);                //打印数组failed[]="*** failed ***n";

    hang();                        //进入while中,并打印: ### ERROR ### Please RESET the board ###     

  }

#if defined(CONFIG_CMD_NAND)

       puts("NAND:  ");                                      //打印NAND:

       nand_init();                                               //初始化nand_flah

... ...

}


从上面代码看出, board_init_r()会来初始化nor,由于新的uboot不支持nor,所以flash_init()初始失败,然后打印一串错误代码后,等待复位.


由于2440在nand启动时,会自动装载nand的前4k内容,所以不支持norflash,因为nor的前4k内容被nand占用.


所以修改上面代码,避免nand启动一直卡住,将:


else

{

  puts(failed);                //打印数组failed[]="*** failed ***n";

  hang();                        //进入while中,并打印: ### ERROR ### Please RESET the board ###     

}


改为:


else

{

  puts("0  KBrn");                //打印0 KB

}


1.接下来,下章便来修改代码,使uboot支持读写norflash


1.1首先在include/common.h中添加:


#define DEBUG     //调试模式


然后使用nor启动新的uboot,打印出调试信息:

打印出norflash的厂家ID=0xC2,设备ID=0x2249,显然uboot匹配读出的ID没有成功.


搜索JEDEC PROBE字段,找到位于board_init_r()->flash_init()->flash_detect_legacy():

如上图所示,该函数会进入board_init_r()->flash_init()->flash_detect_legacy()->jedec_flash_match(),里面会通过两个ID来匹配jedec_table[].


1.2接下来向jedec_table[]里添加norflash:MT29LV160DB(位于drivers/mtd/jedec_flash.c)


代码如下:


     /*MX29LV160DB*/

       {

       .mfr_id         = (u16)MX_MANUFACT,        //厂家ID0x00C200C2 (读nor,便是0xc2)

       .dev_id         = 0x2249,                          //设备ID

       .name           = "MXIC MX29LV160DB",

       .uaddr          = {

           [1] = MTD_UADDR_0x0555_0x02AA /* 数组[1]表示是16位nor,解锁地址为:0x555,0x2AA */

        },

       .DevSize        = SIZE_2MiB,

       .CmdSet         = P_ID_AMD_STD,

       .NumEraseRegions= 4,                      //4种不同的扇区规格

       .regions        = {

       ERASEINFO(16*1024, 1),

       ERASEINFO(8*1024, 2),

       ERASEINFO(32*1024, 1),

       ERASEINFO(64*1024, 31),

                          }

           },


重新烧写看打印信息,出现这么一段ERROR:


ERROR:too many flash sectors


说flash的扇区太多了,搜索找到位于drivers/mtd/jedec_flash.c中:

显然是CONFIG_SYS_MAX_FLASH_SECT宏小于我们flash的扇区,所以打印ERROR。


所以修改CONFIG_SYS_MAX_FLASH_SECT宏定义(位于include/configs/smdk2440.h),并去掉之前定义的DEBUG调试宏(位于include/common.h)


1.3然后重新烧写


输入flinfo命令(flash info),就能查看flash的信息了:

然后通过uboot命令,检测nor的读写是否正确:


protect off all 

erase 80000 +7ffff              

cp.b 30000000 80000 1000             //烧写在另一个位置

cmp.b 30000000 80000 1000              //比较,是否读写正确


2.接下来继续修改代码,使uboot支持NandFlash


2410的NandFlash位于drivers/mtd/nand/s3c2410_nand.c


2.1 首先复制s3c2410_nand.c,改为s3c2440_nand.c


改Makefile,如下图所示:

2.2 在上一章分析过CONFIG_NAND_S3C2410宏,位于include/configs/smdk2440.h:

如上图所示,其中CONFIG_CMD_NAND宏:表示uboot是否支持nand,在上章里,我们把它屏蔽了,接下来便取消屏蔽CONFIG_CMD_NAND宏。


2.3继续添加对CONFIG_NAND_S3C2440宏的支持,将:


#ifdef CONFIG_CMD_NAND

#define CONFIG_NAND_S3C2410

#define CONFIG_SYS_S3C2410_NAND_HWECC

#define CONFIG_SYS_MAX_NAND_DEVICE  1

#define CONFIG_SYS_NAND_BASE              0x4E000000

#endif


#ifdef CONFIG_CMD_NAND


 

#ifdef CONFIG_S3C2410          

#define CONFIG_NAND_S3C2410

#define CONFIG_SYS_S3C2410_NAND_HWECC

#else                                                                   // CONFIG_S3C2440      

#define CONFIG_NAND_S3C2440    

#define CONFIG_SYS_S3C2440_NAND_HWECC

#endif


#define CONFIG_SYS_MAX_NAND_DEVICE      1

#define CONFIG_SYS_NAND_BASE            0x4E000000

#endif


由于smdk2410.h中定义的是CONFIG_S3C2410,而smdk2440.h中定义的是CONFIG_S3C2440,所以便会根据上面的#ifdef来动态定义宏


 


2.4 然后来看看nand的流程(和linux的nand驱动有很多相似的地方):


1)uboot重定位后进入第二阶段board_init_r():


void board_init_r(gd_t *id, ulong dest_addr)        //gd    uboot重定位地址

{

  ... ...

#if defined(CONFIG_CMD_NAND)                      //需要定义CONFIG_CMD_NAND宏

       puts("NAND:  ");

       nand_init();            /* go init the NAND */

#endif

 ... ...

}


2)进入nand_init():


void nand_init(void)

{

... ...

for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)      //在2.3小节里,该宏为1

nand_init_chip(i);                     

printf("%lu MiBn", total_nand_size / 1024);

... ...

}


3)进入nand_init()->nand_init_chip(0):


static void nand_init_chip(int i)

{

    struct mtd_info *mtd = &nand_info[i];      //mtd_info属于软件的一部分,实现用户层读写等操作

    struct nand_chip *nand = &nand_chip[i];     //属于底层,保存对nand的硬件相关操作,它是mtd_info结构体的priv私有成员

    ulong base_addr = base_address[i];           //获取nand寄存器基地址,等于0x4E000000

    int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;


    if (maxchips < 1)

           maxchips = 1;


    mtd->priv = nand;     //设置私有成员nand_chip

    ... ...

    if (board_nand_init(nand))                   //位于s3c2440_nand.c,该函数会设置nand_chip结构体的成员

           return;


    if (nand_scan(mtd, maxchips)) //通过mtd->priv来开启nand片选,来获取nand的型号,类型等.并填充mtd结构体下其它的成员.

           return;


    nand_register(i);     //注册nand,使uboot支持对nand的读写操作

}


这个nand_chip结构体和我们之前学的linux下的nand驱动章节里的nand_chip一摸一样,流程也非常相似.


由于在2.1小节里,该函数所在的文件s3c2440_nand.c是从s3c2410_nand.c复制过来的,所以接下来便修改s3c2440_nand.c (位于drivers/mtd/nand目录下)


2.5 修改s3c2440_nand.c(参考2410数据手册和2440数据手册)


1)首先将所有带2410字的变量都替换为2440


2)修改board_nand_init()


参考以前写的nand驱动,将


  tacls = 4;

    twrph0 = 8;

    twrph1 = 8;

    cfg = S3C2440_NFCONF_EN;                       //启动nand控制器

    cfg |= S3C2440_NFCONF_TACLS(tacls - 1);

    cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);

    cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);

    writel(cfg, &nand_reg->nfconf);


改为:


    tacls = 0;                      //10ns    

    twrph0 = 1;                  //20ns

    twrph1 = 0;                  //10ns


    nand_reg->nfconf = (tacls<<12) | (twrph0<<8) | (twrph1<<4); //设置时序

    nand_reg->nfcont=(1<<1)|(1<<0); // bit1:关闭片选(),       bit0:开启nand flash 控制器


2)添加nand_chip结构体成员


nand->select_chip=s3c2440_select_chip;             //设置CE


然后并写一个s3c2440_select_chip()函数


/*nand flash  :CE */


static void s3c2440_select_chip(struct mtd_info *mtd, int chipnr)

{

        if(chipnr==-1)          //CE Disable

       {

        my_regs->nfcont|=(0x01<<1);               //bit1置1

       }

        else                         //CE Enable

       {

        my_regs->nfcont&=~(0x01<<1);        //bit1置0 

       }           


}


3)屏蔽带硬件ECC的相关操作


将:


#ifdef CONFIG_S3C2410_NAND_HWECC

nand->ecc.hwctl = s3c2440_nand_enable_hwecc;

nand->ecc.calculate = s3c2440_nand_calculate_ecc;

nand->ecc.correct = s3c2440_nand_correct_data;

nand->ecc.mode = NAND_ECC_HW;

nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;

nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;

#else

nand->ecc.mode = NAND_ECC_SOFT;

#endif


改为:


nand->ecc.mode = NAND_ECC_SOFT;               //使用软件ECC

[1] [2]
关键字:移植  uboot  nor  nand 引用地址:3.移植uboot-使板卡支持nor、nand

上一篇:4.移植uboot-使uboot支持DM9000网卡
下一篇:2.移植uboot-添加2440单板,并实现NOR、NAND启动

推荐阅读最新更新时间:2024-11-13 05:55

NBT选择Nordic SiP作为物联网平台基础
德国公司Next Big Thing AG (NBT) 推出了一个基于物联网传感器的开发平台“Prometheus”,旨在为基于蜂窝物联网和云的解决方案的开发人员简化原型设计并加快上市时间。该平台支持广泛的工业应用程序的开发,包括制造、制药和物流行业。 “Prometheus”开发平台由 Nordic 的 nRF9160 低功耗系统级封装 (SiP) 提供支持,集成了 LTE-M/NB-IoT 调制解调器和 GNSS。nRF9160 SiP 的 64MHz Arm® Cortex®-M33 专用应用处理器提供足够的计算能力,不仅可以监控 LTE-M/NB-IoT 调制解调器的蜂窝连接,还可以监控所有其他产品功能。SiP封装的
[物联网]
NBT选择<font color='red'>Nor</font>dic SiP作为物联网平台基础
移植Linux-2.6.30.4内核之根文件系统构建
上一次只移植完成了linux-2.6.30.4内核,用的是天嵌自带的根文件系统,这次尝试自己制根文件系统。可以按照以下步骤来进行: 1、移植yaffs2文件系统 现在内核里边还不支持yaffs2文件系统,需要在内核中添加对yaffs2的支持 下载yaffs2的源码,之前天嵌给的源码网址早就不能用了,后来找了好久才下载到。 得到源码后,然后打上 yaffs2 的补丁,方法如下: #cd yaffs2/ (进到 yaffs2 的补丁目录下) #./patch-ker.sh c m ~ /sky/kernel-2.6/linux-2.6.30.4/ (执行补丁脚本,打补丁到内核中) 注意第二个参数m/s,要特别注意如果不是最新的
[单片机]
<font color='red'>移植</font>Linux-2.6.30.4内核之根文件系统构建
S5PV210之Nand flash驱动编写
大家好,又到了天嵌【嵌入式分享】的时间,相对于前几期【嵌入式分享】做的主要是TQ335X开发板的技术分享,本期决定做同是cortex-a8系列的TQ210开发板的技术分享。本期是关于TQ210开发板的Nand flash驱动编写,可能源码部分会比较多,本文由博主girlkoo编写,感谢他的分享。 跟裸机程序一样,S5PV210(TQ210)的Nand flash模块跟S3C2440(TQ2440)的Nand flash模块非常相似,如果不引入ECC,驱动程序的编写也非常简单,我是使用的Linux-3.8.6(Linux-3.8.3也一样)内核,驱动的API函数有些变化,不过原理是相通的,稍微看一下内核源码并参考下其他平台的相关代码
[单片机]
S3C6410移植u-boot-2010.3(5)Dnw for linux
  现在开始记录在linux上安装dnw功能   想要源代码,可以到这里fork https://github.com/Qunero/dnw4linux   详细的使用,README里面讲得很清楚了,不加赘述了。   这里只讲一下怎么使用。   1、加载模块.ko文件 $ cd secbulk_driver/ $ insmod secbulk.ko   然后确认一下已经加载 $ lsmod | grep secbulk //若正确加载了,应该有回显 secbulk 12728 0   2、插入USB to miniUSB线   然后查看一下系统信息 $ dmesg //正常情况下应
[单片机]
Linux帧缓冲设备驱动程序框架及图形界面GUI的移植
硬件平台   S3C2410X是三星公司的基于ARM920T的S3C2410X芯片。S3C2410X集成了一个LCD控制器(支持STN和TFT带有触摸屏的液晶显示屏)、SDRAM、触摸屏、USB、SPI、SD和MMC等控制器,4个具有PWM功能的计时器和1个内部时钟,8通道的10位ADC,117位通用I/O口和24位外部中断源,8通道10位AD控制器,处理器工作频率最高达到203MHz。   S3C2410中的LCD控制器可支持单色/彩色LCD显示器。支持彩色TFT时,可提供4/8/12/16位颜色模式,其中16位颜色模式下可以显示65536种颜色。配置LCD控制器重要的一步是指定显示缓冲区,显示的内容就是从缓冲区中读出的,其大小
[单片机]
linux2.6.32.2移植到ARM平台(mini2440)
1、指定交叉编译变量 即修改顶层Makefile文件,vim打开,修改如下: 原 export KBUILD_BUILDHOST := $(SUBARCH) ARCH ?= $(SUBARCH) CROSS_COMPILE ?= 改为 export KBUILD_BUILDHOST := $(SUBARCH) ARCH ?= arm //指定目标平台为ARM CROSS_COMPILE ?= arm-linux- //指定交叉编译器,此处是系统默认的,若指定其他的需要把路径完整列出 修改完毕之后,先编译一下,看是否能通过, # make s3c2410_defconfig # make 2、
[单片机]
U-boot 在 mini2440-S3C2440 上的移植(1)-开发环境搭建-交叉编译工具链的安装
编译U-boot给mini2440时,要编译出能在ARM平台上使用的可执行文件-bin,首先要在ubuntu 中安装交叉编译工具链,因为我使用的是友善之臂的开发板,所以我使用的已经制作好的工具链,当然也可以自己制作工具链:如基于GCC和glibc制作工具链,可以使用cross tools编译; 我使用的工具链的版本是arm-linux-gcc-4.3.3版本,下载地址:下载地址 1.在pc端下载好以后,将压缩包用xftp传输到Ubuntu;当然也可以用其他软件上传;上传后把它放在根目录下的/usr/local文件夹中新建一个arm文件夹,然后把压缩包复制到这个文件夹;注意先建好文件夹再上传,可以减少很多工作量; 一定要上传压缩包,
[单片机]
U-boot 在 mini2440-S3C2440 上的<font color='red'>移植</font>(1)-开发环境搭建-交叉编译工具链的安装
消息称三星下代 400+ 层 V-NAND 2026 年推出,0a DRAM 采用 VCT 结构
10 月 29 日消息,《韩国经济日报》表示,根据其掌握的最新三星半导体存储路线图,三星电子将于 2026 年推出的下代 V-NAND 堆叠层数超过 400,而预计于 2027 年推出的 0a nm DRAM 则将采用 VCT 结构。 三星目前最先进的 NAND 和 DRAM 工艺分别为第 9 代 V-NAND 和 1b nm(12 纳米级)DRAM。 报道表示三星第 10 代(即下代) V-NAND 将被命名为 BV(Bonding Vertical) NAND,这是因为这代产品将调整 NAND 结构,从目前的 CoP 外围上单元改为分别制造存储单元和外围电路后垂直键合,整体思路与长江存储 Xtacking、铠侠-西部数据
[手机便携]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved