尊天命,尽人事
分类: 嵌入式
2011-08-29 14:35:11
uboot与yaffs2的集成
1 实验目的
通过将uboot和yaffs集成在一起来实现内核在nand flash中的任意位置存放
2 实验背景
目前很多的嵌入式操作系统内核都放置在flash的0地址开始的一段空间中,如果我们重新编译了一个内核,我们还要写到这段空间内,而且每次启动我们都要读这段区域,频繁的读写某一固定区域会造成硬件故障;一般情况下,这段区域的大小是固定的,如果我们要把内核的长度变大,就有可能覆盖其他的数据。如果我们要把一个内核写到flash的任意位置而且在启动的时候还能够找到它的所在位置,我们就需要一个bootloader用来加载内核,还需要一个文件系统来查找内核。我们可以选用uboot作为我们的bootloader,但是uboot目前并没有文件系统可以组织nand flash,我们采用专门为nand flash设计的文件系统yaffs,现在的工作就是让uboot支持yaffs。
2.1 Uboot与Yaffs2简介
Uboot是一个目前被普遍采用的bootloader,尤其是在一些嵌入式系统当中。Bootloader的主要作用就是在硬件系统自检之后,设置目标平台环境,装载一个可引导的映像到存储器,然后将控制权交给操作系统,而不必让操作系统来判断具体的目标平台,对操作系统也是一种解放,目前比较经常使用的一些bootloader还有如Redboot,Sandstone等等。 Yaffs(yet another Flash File System)是一种专门为 Nand Flash开发的文件系统,至于Yaffs的优点及产生的原因可以在Yaffs的官方文档中看到。
3 实验准备
3.1 从官方网站下载yaffs的压缩包
3.2 安装交叉编译环境arm-linux-gcc
3.3 配置一个tftp服务器以便与在机器和实验板之间传输文件
3.4 将实验板和机器互联(串口连接,网络连接)
本机器的操作系统为Fedora 6 编译器为arm-linux-gcc 3.4.1
4 实验步骤
4.1 设置目录
把yaffs的包解压缩后拷贝到uboot的fs目录下面,假设为uboot/fs,拷贝完之后是uboot/fs/yaffs
4.2 修改Makefile规则
修改文件uboot/config.mk如下:
文章中只要出现”Tsai”的地方就表示我做过修改
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
-DKERNEL -DTEXT_BASE=$(TEXT_BASE) \
-I$(TOPDIR)/include \
-I$(TOPDIR)/include/asm-arm \ //added by Tsai
-I$(TOPDIR)/fs/yaffs \ //added by Tsai
-fno-builtin -ffreestanding -nostdinc -isystem \
$(gccincdir) -pipe $(PLATFORM_CPPFLAGS)
修改这个地方的目的就是为了在编译的时候让yaffs下面的程序能够找到相应的头文件
修改文件uboot/Makefile如下:
CROSS_COMPILE = /usr/local/arm/3.4.1/bin/arm-linux-
这个修改依赖于自己的交叉编译环境
修改uboot/fs/Makefile如下:
SUBDIRS := jffs2 cramfs fdos fat reiserfs ext2 yaffs
修改uboot/fs/yaffs/Makefile如下:
LIB = libyaffs2.a
AOBJS =
COBJS = yaffsfs.o yaffs_ecc.o yaffs_guts.o yaffs_packedtags2.o yaffs_qsort.o yaffscfg.o yaffs_flashif.o
COBJS += yaffs_tagscompat.o yaffs_tagsvalidity.o yaffs_checkptrw.o yaffs_nand.o yaffs_ramdisk.o yaffs_mtdif.o yaffs_mtdif2.o yaffs_packedtags1.o
OBJS = $(AOBJS) $(COBJS)
如果想对yaffs有任何修改的话,一般都需要修改这个文件,例如要使用yaffs_packedtags2.c
中的某一个方法而不是调用yaffs_packedtags1.c中的方法,就可以把yaffs_packedtags1.o
删除掉
以上只是对Make规则的一些修改,只是为了让uboot能够找到文件系统
4.3 yaffs文件分析
在yaffs目录下还有一个目录direct,即uboot/fs/yaffs/direct,yaffs提供了两种不同
的用途,一种是作为内核空间的一部分,在重新编译内核后,yaffs会成为它的文件系统,这种方式和普通的系统一样;还有一种方式就是把已经存在了一个嵌入式系统,而且不需要重新编译内核,直接把编译好的文件系统作为该系统的一个应用程序来使用,这种方式称为YDI(yaffs direct interface),由于uboot并不是一个通用操作系统,我们就采用YDI方式。我们可以看一下direct目录下的文件结构:
Yaffsfs.h定义了一些高层的接口,如用来读取文件的
int yaffs_read(int fd, void *buf, unsigned int nbyte)
yaffsfs.c是对这些定义的实现
yaffscfg.h定义了一些对文件系统初始化时的配置,如bootDev.nBytesPerChunk = 512定义根设备的每个块有512个字节,里面还定义了一些函数如yaffs_lock(),yaffscfg.c则是相应的实现
yaffscfg2k.h中的nand flash每个块是2048个字节,yaffscfg.h中的是512字节,这是唯一的不同点,可以根据自己的设备来具体选择
yaffs_flashif.h定义了一些对nand flash最基本的如读写擦除等操作
yaffs_ramdisk.h则定义了对ram的操作
以上这些文件在集成yaffs的过程中都要用到
yaffs_fileem*.*是对文件操作的模拟,便于测试
dtest.c也是用来测试,这几个文件在编译的过程中并不需要
ydirectenv.h定义了一些环境变量,我们用下面讲到的另一个文件来代替它
下面是uboot/fs/yaffs
Devextras.h定义了一些用到的环境变量,开始的时候可以不用改动这个文件,在编译的过程中根据相应的出错信息来修改它
Yportenv.h里面也定义了一些环境变量,需要包含进去
Moduleconfig.h在YDI模式下用不到
Yaffs_fs.h定义了高层的封装,不过和内核相关,不用
Yaffs_guts.h定义了yaffs文件系统的算法,如如何查找一个文件,编译的时候必须包含
Yaffs_guts.c是对定义的实现
Yaffs_nand.h定义了对nand的操作与direct目录下的yaffs_flashif.h不同的地方是,yaffs_nand.h里面引用了mtd 的接口
Yaffs_mtdif.h定义了mtd接口,在编译的时候可以选择编译,也可以不选择
Yaffs_mtdif2.h和Yaffs_mtdif.h之间的区别在于nand flash块的大小
其他的文件就是对yaffs功能的一些扩展,还有一些是为了兼容yaffs和yaffs2
我们所包含的文件从uboot/fs/yaffs/Makefile中就可以找到
4.4 在uboot/common目录下添加一个文件cmd_yaffs.c,其中的内容如下:
加这个文件的目的是为了给uboot的shell一个调用yaffs的接口
//all below added by Tsai
void do_yaffs_init(const char *mountpt)
{
yaffs_StartUp();
yaffs_mount(mountpt);
}
void do_yaffs_write(char *path,char *buf,int len,int mode)
{
int fd;
int ret;
if(len<=0) return;
else if(mode<0||mode>1) return;
else if(mode==0){
fd=yaffs_open(path,O_CREAT|O_RDWR,S_IREAD | S_IWRITE);
ret=yaffs_write(fd,buf,len);
}//(mode==0)
else{
return;
//add code to extend the functionality
}
}
U_BOOT_CMD(
yinit, 1, 0, do_yaffs_init,
"yaffs_init\n",
);
U_BOOT_CMD(
ywrite, 4, 0, do_yaffs_write,
"yaffs_write\n",
);
4.5 编译过程
然后就可以make了,不过会遇到上百个错误,慢慢修正就可以了,更正的地方也有很多在援文件中可以根据我做的注释来找到。
4.6 其他的测试工作
生成u-boot.bin,可以下载到目标板去执行,不过由于Nand flash还无法测试,因此还无法实现yaffs的一些功能
5 试验总结
5.1 文件系统和内核可以完全独立,可以仅仅作为一个应用程序来使用
5.2 内核也是可以在任意位置存取的
6 提示
实验中所用到的文件均可以在网站 上得到
用户名:sword
密码 :king
在本文中除有版本比较的地方之外,yaffs就是指的yaffs2