文章目录
前言
通过前面两篇博客,我们已经将U-Boot移植进行了一半。使我们的U-Boot同时支持S3C2410和S3C2440两款芯片。支持我们的xmodem串口协议,支持网卡芯片CS8900。
今天的这篇博客我们将U-BOOT移植剩下的内容分析完
第四步:支持NAND Flash
第五步:支持烧写yaffs文件系统映象
第六步:修改默认参数以便使用
支持NAND Flash
U-Boot 1.1.6中对NAND Flash的支持有新旧两套代码,新代码在drivers/nand目录下,旧代码在drivers/nand_legacy目录下。
要让U-Boot支持NAND Flash,首先在配置文件include/configs/100ask24x0.h,的宏CONfig_COMMANDS中增加CFG_CMD_NAND,如下所示:
使用旧代码时,需要实现drivers/nand_legacy/nand_legacy.c中使用到的各种宏,比如:
#define WRITE_NAND_COMMAND(d,adr) //写NAND Flash命令,代码依赖于具体的开发板
参考书籍采用新代码,下面分析移植过程。
代码的移植没有现成的文档,可以配置文件include/configs/100ask24x0.h的宏CONfig_COMMANDS中增加CFG_CMD_NAND后就编译代码,然后一个一个地解决出现地错误
nand.h:412: error:'NAND_MAX_CHIPS' undeclared here (not in a function)
nand.c:35: error: 'CFG_MAX_NAND_DEVICE' undeclared here (not in a function)
nand.c:38:error: 'CFG_NAND_BASE' undeclared here (not in a function)
nand.c:35:error: storage size of 'nand_info' isn't kNown
nand.c:37:error: storage size of 'nand_chip' isn't kNown
nand.c:38:error: storage size of 'base_address' isn't kNown
nand.c:37:warning : 'nand_chip' defined but not used
nand.c:38:warning: 'base_address' defined but nnot used
在配置文件include/configs/100ask24x0.h增加如下3个宏就可以解决上述错误。在Flash的驱动程序中,设备是逻辑上的概念,表示一组相同结构,访问函数相同的Flash芯片。在参考书籍所用的开发板中,只有一个NAND Falsh芯片,所以设备数是1,芯片数也是1。
修改文件后再次编译,现在只有一个错误了,“board_nand_init函数未定义”,如下
nand.c:50: undefined reference to 'board_nand_init'
调用board_nand_init函数的过程为:NAND Flash的初始化入口函数是nand_init,它在lib_arm/board.c的start_armboot函数中被调用;nand_init函数在drivers/nand/nand.c中实现,它调用相同文件中的nand_init_chip函数:nand_init_chip函数首先调用board_nand_init函数来初始化NAND Flash设备,最后才是统一的识别过程。
从board_nand_init函数的名称就可以知道它是平台/开发板相关的函数,需要自己编写。
在cpu/arm920t/s3c24x0目录下新建一个文件nand_flash.c,在里面针对S3C2410,S3C2440实现了统一的board_nand_init函数。
在编写board_nand_init函数之前,需要针对S3C2410,S3C2440NAND Flash控制器的不同来定义一些数据结构和函数;
1、在include/s3c24x0.h文件中增加S3C2440_NAND数据结构
2、在include/s3c2410.h 文件仿造S3C2410_GetBase_NAND函数定义S3C2440_GetBase_NAND函数
既然新的NAND Flash代码是从Linux内核2.6.12中移植来的,那么cpu/arm920t/s3c24x0/nand_flash.c文件也可以仿照内核中对S3C2410,S3C2440的NAND Flash进行初始化的drivers/mtd/nand/s3c2410.c文件来编写。为了方便阅读,先把cpu/arm920t/s3c24x0/nand_flash.c文件的代码全部列出来,如下所示(因为太长,我就使用书籍上的直接分析)
最后,只要将新建的nand_flash.c文件编入U-Boot就可以擦除,读写NAND Flash了。如下修改cpu/arm920t/s3c24x0/Makefle文件即可
修改前:
修改后:
支持烧写yaffs文件系统映象
在实际生产中,可以通过烧片器等手段将内核,文件系统映象烧入固态存储设备中,Bootloader不需要具备烧写功能。但是为了方便开发,通常在Bootloader中增加烧写内核、文件系统映象文件的功能。
增加了NAND Flash功能的U-Boot 1.16已经可以通过 “nand write…”,“nand write.jffs2…”等命令来烧写内核,烧写cramfs,jffs2文件系统映象文件。但是在NAND Flash上,yaffs文件系统的性能更佳,下面增加 "nand write。yaffs…"命令以烧写yaffs文件系统映象文件。
"nand write.yaffs…"字样的命令中,“nand”是具体的命令,“write.yaffs…”是参数。nand命令在common/cmd_nand.c中实现如下:
第354行~379行就是针对命令“nand read.yaffs…”、“nand write.yaffs…”增加的代码。有兴趣的朋友可以自己分析 “if(read)”分支的代码,下面只讲解“else”分支,即"nand write.yaffs…"命令的实现。
NAND Flash每一页大小为(512+16)字节(还有其他格式的NAND Flash,比如每页大小为(256+8),(2048+64)等),其中的512字节就是一般存储数据的区域,16字节称为OBB(OUT OF BAND)区。通常在OBB区存放环块标记,前面512字节的ECC校验码等。
cramfs,jffs2文件系统映象文件中并没有OBB区的内容,如果将他们烧入nor Flash中,则是简单的“平铺关系”;如果将他们烧入NAND Flash中,则NAND Flash的驱动程序首先根据OBB的标记略过环块,然后将一页数据(512字节)写入后,还会计算这512字节的ECC检验码,最后将它写入OBB区,如此循环。cramfs,jffs文件系统映象文件的大小通常是512的整数倍。
而yaffs文件系统映象文件的格式跟他们不同,文件本身就包含了OBB区的数据(里面有环块标记,ECC校验码,其他yaffs相关信息)。所以烧写时,不需要在计算ECC值,首先检查是否环块(是则跳过),然后写入512字节的数据,最后写入16字节的OBB数据,如此循环。yaffs文件系统映象文件的大小是(512+16)地整数倍。
(注意:烧写yaffs文件系统映象时,分区上第一个可用地(不是环块)块也要跳过)
下面分析369~371行设置地源地址,目的地址,长度。烧写yaffs文件系统映象前,一般通过网络将它下载到内存某个地址处(比如0x30000000),然后通过类似“nand write.yaffs 0x300000000 0x00A00000 $(filesize)”的命令烧写到NAND Flash的便宜地址0x00A00000处。这对于这个命令第369行中opts.buffer等于0x30000000,第270行opts.length= $ (filesize)的值,就是前面下载的文件的大小,第371行中的opts.offset等于0x00A00000。
这里列出不使用的第372行,是因为opts.forceyaffs这个名字很有欺骗性,它其实是指计算ECC校验码的一种方法。烧写yaffs文件系统映象时,不需要计算ECC校验码。
第373,374行指定烧写数据时不计算ECC校验码,而是烧入文件中的OBB数据。
第375行指定“逻辑块”的大小,“逻辑块”可以由多个“物理块”组成,在yaffs文件系统映象中,它们是1:1的关系。
第377行的opts.shipfirstblk是新加项,nand_write_options_t结构中没有shipfirstblk成员。它表示烧写时跳过第一个可用的逻辑块,这是由yaffs文件系统的特性决定的。
既然skipfirstblk是在nand_write_options_t结构中新加的项,那么就要重新定义nand_write_options_t结构,并在下面调用的nand_write_opts函数中对他进行处理。
首先在include/nand.h中进行如下的修改,增加skipfirstblk成员
进行了上面的移植后,U-Boot已经可以烧写yaffs文件系统映象了。由于前面设置“opts.noecc =1”不使用ECC校验码,在烧写过程中会出现很多的提示信息,如下
writing data without ECC to NAND-FlASH is not recommended
可以修改drivers/nand/nand_base.c文件的nand_write_page函数,将它去掉。
修改前:
修改默认配置参数以方便使用
前面移植网卡芯片CS8900时,已经设置过默认IP地址等。为了使用U-Boot时减少一些设置,现在修改配置文件include/configs/100ask24x0.h,增加默认配置参数,其中一些在移植过程中已经增加的选项这里也再次说明。
Linux启动参数
增加如下3个宏:
自动启动命令
增加如下两个宏:
默认网络设置
总结
U-Boot的移植完结了,下一篇博客分析U-Boot的常用命令。
希望这些博客也能帮助到您。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。