Chinaunix首页 | 论坛 | 博客
  • 博客访问: 450150
  • 博文数量: 133
  • 博客积分: 3259
  • 博客等级: 中校
  • 技术积分: 1255
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-14 13:49
文章存档

2012年(6)

2011年(112)

2010年(16)

分类: 嵌入式

2010-05-04 15:51:57

移植yaffs2文件系统到mini2440过程详解
2009-10-28 22:57
本文参考了
hi.baidu.com/jiajingtao126/blog/item/4671c9604cdac1d78db10dd8.html
hi.baidu.com/xqs83/blog/item/70cc09cf5febab39f9dc6146.html
blog.ednchina.com/bluelemon135/242292/message.aspx
blog.sina.com.cn/s/blog_5fe42fc90100cp4z.html

玩mini2440有一段时间了,用的都是自带的完善的linux系统。用别人的总是感到良心不安啊!于是也想自已做个文件系统。

一,文件系统的选择--YAFFS2=====================================
YAFFS , Yet Another Flash File System ,是一种类似于 JFFS/JFFS2 的专门为 Flash 设计的嵌入式文件系统。与 JFFS 相比,它减少了一些功能,因此速度更快、占用内存更少。 YAFFS 和 JFFS 都提供了写均衡,垃圾收集等底层操作。它们的不同之处在于:
1 )、 JFFS 是一种日志文件系统,通过日志机制保证文件系统的稳定性。 YAFFS 仅仅借鉴了日志系统的思想,不提供日志机能,所以稳定性不如 JFFS ,但是资源占用少
2 )、 JFFS 中使用多级链表管理需要回收的脏块,并且使用系统生成伪随机变量决定要回收的块,通过这种方法能提供较好的写均衡,在 YAFFS 中是从头到尾对块搜索,所以在垃圾收集上 JFFS 的速度慢,但是能延长 NAND 的寿命
3 )、 JFFS 支持文件压缩,适合存储容量较小的系统YAFFS 不支持压缩,更适合存储容量大的系统。
YAFFS 还带有 NAND 芯片驱动,并为嵌入式系统提供了直接访问文件系统的 API ,用户可以不使用 Linux 中的 MTD 和 VFS ,直接对文件进行操作。 NAND Flash 大多采用 MTD+YAFFS 的模式。 MTD ( Memory Technology Devices ,内存技术设备)是对 Flash 操作的接口,提供了一系列的标准函数,将硬件驱动设计和系统程序设计分开。YAFFS2 是 YAFFS 的升级版,YAFFS2 能够更好的支持大容量的NAND FLASH芯片
       与之不同的是JFFS1/2 文件系统最初是针对NOR FLASH的应用场合设计的,而NOR FLASH NAND FLASH本质上有较大的区别,所以尽管JFFS1/2 文件系统也能应用于NAND FLASH,但由于它在内存占用和启动时间方面针对NOR 的特性做了一些取舍,所以对NAND来说通常并不是最优的方案.

二,内核中加入对YAFFS2的支持====================================
1. 获取yaffs 源码

选择yaffs目录,点击左下脚的Download GNU tarball 就可以下载yaffs的压缩文档
2. 获取linux内核源码,移植linux2.6.29.6内核

a.修改顶层Makefile文件

直接将Makefile文件里面的
ARCH ?= $(SUBARCH)
  CROSS_COMPILE ?=

改为
:
   ARCH ?= arm
CROSS_COMPILE ?=arm-linux-

然后用S3C2410的默认配置文件
#make s3c2410_defconfig        //
此命令 configuration written to .config  
//
要先按上面方法修改完成Makefile文件才能执行这一步

b.修改时钟,不修改超级终端中会出现乱码
修改Arch/arm/mach-s3c2440/mach-smdk2440.c        ln163
S3c24xx_init_clocks(16934400);
改为
:
S3c24xx_init_clocks(12000000);

c.修改对nand的分区信息。要让内核知道nand flash的分区信息,设置成跟bootloader一致。

arch/arm/plat-s3c24xx/common-smdk.c中修改smdk_default_nand_part[]

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition friendly_arm_default_nand_part[] = {
[0] = {
.name = "supervivi",
.size = 0x00030000,
.offset = 0,
},
[1] = {
.name = "Kernel",
.offset = 0x00050000,
.size = 0x00200000,
},
[2] = {
.name = "root",
.offset = 0x00250000,
.size = 0x03dac000,
}
};

d.修改CPUID,不修改将会出现无法进入内核由于CPU mach_type 不对应找不到对应的CPU

    arch/arm/tools/mach-types  这个文件打开修改对应CPU  ID

    修改 S3C2440 对应为 782

e.修改drivers/mtd/nand/s3c2410.c
     NAND_ECC_SOFT
----NAND_ECC_NONE;

3.在内核中添加对yaffs 的支持
进到yaffs2 的目录下执行:
有可执行文件patch-ker.sh
看参数格式:
usage:  ./patch-ker.sh  c/l kernelpath
 if c/l is c, then copy. If l then link        


#./patch-ker.sh c /home/abc/tmp/linux-2.6.29.6
此时到内核源码的“fs/”目录下面您将看到新添加了一个名为“yaffs2”的目录,同时fs/目录下面的Makefile 文件和Kconfig 文件也添加了yaffs2 的配置和编译条件。
如下所示:(以下3点是执行patch-ker.sh后自动完成的)
1)修改内核fs/Kconfig 增加一行:source "fs/yaffs2/Kconfig"
(2)修改内核fs/Makefile 增加一行ojb-$(CONFIG_YAFFS_FS) +=yaffs2/
(3)在内核fs/目录下创建yaffs2目录将yaffs2源码目录下面的Makefile.kernel文件复制为内核fs/yaffs2/Makefie;   将yaffs2 源码目录的Kconfig文件复制到内核fs/yaffs2目录下; 将yaffs2源码目录下的*.c *.h文件复制到内核fs/yaffs2目录下.

在命令行输入:make menuconfig,进入配置单,然后配置如下所示:
File systems --->
<*> Kernel automounter support
<*> Kernel automounter version 4 support (also supports v3)
<*> Filesystem in Userspace support
CD-ROM/DVD Filesystems --->
<*> ISO 9660 CDROM file system support
DOS/FAT/NT Filesystems --->
<*> MSDOS fs support
<*> VFAT (Windows-95) fs support
(437) Default codepage for FAT
(iso8859-1) Default iocharset for FAT
Pseudo filesystems --->
[*] Virtual memory file system support (former shm fs)
[*] Tmpfs POSIX Access Control Lists
<*> Userspace-driven configuration filesystem
Miscellaneous filesystems --->
<*> YAFFS2 file system support
-*- 512 byte / page devices
[*] Lets Yaffs do its own ECC
-*- 2048 byte (or larger) / page devices
[*] Disable lazy loading
[*] Turn off wide tnodes
[*] Force chunk erase check
-*- Native language support --->
--- Native language support
(iso8859-1) Default NLS Option
<*> Codepage 437 (United States, Canada)
<*> Simplified Chinese charset (CP936, GB2312)
<*> NLS ISO 8859-1 (Latin 1; Western European Languages)
<*> NLS UTF-8

             修改Kernel Features  --->
[*] Use the ARM EABI to compile the kernel                  
[*]   Allow old ABI binaries to run with this kernel (EXPERIMENTA)

如果不选启动时会出现
Kernel panic - not syncing: Attempted to kill init!

配置好之后,保存,编译出镜像。
make zImage

在/linux2.6.29.6/arch/arm/boot就可以找到zImage文件了

到此已以把yaffs2 文件系统移植完毕了.

三.制做文件系统=================================================

文件系统要包含这些必须有的目录:/dev、/bin、/usr、/sbin、/lib、/etc、/proc、/sys
/dev是devfs(设备文件系统)或者udev的挂在点所在。在使用devfs的内核里如果没有/dev,根本见不到Shell启动的信 息,因为内核找不到/dev/console;在使用udev的系统里,也事先需要在/dev下建立console和null这两个节点。关于devfs 和udev的区别,网上很多文章说。当然如果你的内核已经不支持devfs了(2.6.12以后),可以使用纯纯的静态节点。也就是用mknod人工生 成。
/bin、/usr/bin、/usr/sbin、/sbin是编译Busybox这个Shell时候就有的,用于存放二进制可执行文件,就不多解释了。
/lib用于存放动态链接库。网上很多文章都说静态编译Busybox,可以省去建库的麻烦过程。这样做只能让Busybox启动,我们自己写 的,或者是编译的软件包还是需要动态库的。除非全部静态编译,你可以试试,一个Hello world就要几百k。关于库的内容后面仔细说。
/etc是用来存放初始化脚本和其他配置文件的。关于初始化脚本的内容后面仔细说。
/proc是用来挂载存放系统信息虚拟文件系统——“proc文件系统”,“proc文件系统”在内核里面可以选。如果没有“proc文件系 统”,很多Shell自己的命令就没有办法运行,比如ifconfig。“proc文件系统”不像devfs可以自动挂载,它需要使用初始化脚本挂载。另 外,udev也需要“proc文件系统”的支持。
/sys用于挂载“sysfs文件系统”,“sysfs文件系统”在内核里面可以选。目前我认为它就是给udev提供支持的,呵呵。“sysfs文件系统”也需要使用初始化脚本挂载。
1. 获取BusyBox 源码

我用的是busybox-1.15.2.tar.bz2 。
2 修改并配置BusyBox
解压busybox,使用命令#tar jxvf busybox-1.15.2.tar.bz2 –C /home/abc/tmp/
然后进到源码中,修改Makefile 文件
ARCH ? =arm
CROSS_COMPILE ?=/usr/local/arm/4.3.2/bin/arm-linux-

然后输入:#make menuconfig,进入配置单:
然后配置如下:(没有列出的选项,可以采用默认,也可以根据自己的需要添加。)
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
Busybox Library Tuning --->
(
[*] vi-style line editing commands
[*] Fancy shell prompts
Linux Module Utilities --->
(/lib/modules) Default directory containing modules
(modules.dep) Default name of modules.dep
[*] insmod
[*] rmmod
[*] lsmod
[*] modprobe
--- Options common to multiple modutils
然后退回到根配置单,选择“Save Configuration to an Alternate File”选项,保存刚刚的配置为
mini2440busy_config(自己随便取的名字),编译时调用的是.config文件.

3 .编译并安装BusyBox
在命令行输入:make;make install,编译结束后会在busybox-1.15.2
  根目录下面生成一个名为“_install”的目录。
完成busybox 的编译之后,我们就可以进行文件系统的构建了。
在“/home/abc/tmp/”目录下面建立一个“rootfs”的目录,复制刚刚编译出来的busybox 的“bin”
目录、“sbin”目录、“usr”目录和“linuxrc”到“rootfs”目录下,然后新建“dev”、“etc”、“home”、 “lib”、“mnt”、“opt”、“proc”、“root”、“sys”、“tmp”、“var”和“web”目录,并在原有的“usr”目录下面 新建一个“lib”目录。
4. 添加内容
“dev”目录
下面的内容在内核挂载完毕文件系统后,系统会使用mdev 自动建立。
不过mdev 是调用init 进程来启动的,在使用mdev 构建“dev”目录前,init 进程需要用到“/dev/console”和“/dev/null”这两个设备文件,所以,我们需要在制作文件系统时静态创建这两个设备文件,方法如下:
#mknod console c 5 1
#mknod null c 1 3

如果不创建这两个设备文件,在文件系统启动时会出现错误信息.大概是不能初始化控制台。

“etc”目录
用来存放系统的配置文件。
在“etc”目录下面有如下常用的文件:
fstab:指明需要挂载的文件系统;
group:用户组;
inittab:init 进程的配置文件;
passwd:密码文件;
profile:用户环境配置文件;
mdev.conf:因为2.6.18 版本开始linux 放弃使用devfs 而采用udev(mdev 是udev 的简化版本),这里的
mdev.conf 文件可以是空,也可以按照一定规则来编写,这里我采用了为空;
resolv.conf:存放DNS 信息的文件,访问外网时需要DNS 的信息。
常用的目录有:
init.d 目录:启动文件目录,该目录下面有个“rcS”的文件,里面存放了系统启动时配置以及自启动加载
的进程等;
sysconfig 目录:在我们的文件系统里面,该目录下面存放了名为“HOSTNAME”的文件,该文件内容为:
Embed_jiajintao,这句话就是我们在文件系统里面看到那个“[root@ Embed_jiajintao /]” rc.d 目录:在我们的文件系统里面用来存放一些自启动所要调用的脚步等;
boa 目录:我们的文件系统特有的目录,用来存放web 服务器的配置脚本。
下面分别列出“etc”下面各个文件的内容。
【fstab】:
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
var /dev tmpfs defaults 0 0
【group】:
root:*:0:
daemon:*:1:
bin:*:2:
sys:*:3:
adm:*:4:
tty:*:5:
disk:*:6:
lp:*:7:lp
mail:*:8:
news:*:9:
uucp:*:10:
proxy:*:13:
kmem:*:15:
dialout:*:20:
fax:*:21:
voice:*:22:
cdrom:*:24:
floppy:*:25:
tape:*:26:
sudo:*:27:
audio:*:29:
ppp:x:99:
500:x:500:jiajintao
501:x:501:jiajintao
【inittab】:参考busybox 源码下面的“examples/inittab”文件
# /etc/inittab
::sysinit:/etc/init.d/rcS
s3c2410_serial0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
注意:上面红色部分在busybox 的参考文件中是ttySAC0,而在s3c24xx 系列芯片的串口驱动里面我们用了s3c2410_serial 做为设备名(在内核源码的“drivers/serial/s3c2410.c”文件的949 行),然后我们又是用的串口0 作为控制台的,所以这里我们使用s3c2410_serial0。
【passwd】:
root::0:0:root:/:/bin/sh
ftp::14:50:FTP User:/var/ftp:
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
nobody:*:99:99:Nobody:/:
jiajintao:$1$8GIZx6d9$L2ctqdXbYDzkbxNURpE4z/:502:502:Linux User,,,:/home/jiajintao:/bin/sh

【profile】:
# Ash profile
# vim: syntax=sh
# No core files by default
#ulimit -S -c 0 > /dev/null 2>&1
USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]# '
PATH=$PATH
HOSTNAME=`/bin/hostname`
export USER LOGNAME PS1 PATH
【mdev.conf】:
暂时空
【resolv.conf】:
nameserver 202.96.128.166
【init.d/rcS】:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir -p /var/lock
/bin/hostname -F /etc/sysconfig/HOSTNAME
注意:在上面红色部分是关于mdev 的使用,请参考busybox 的“docs/mdev.txt”文件。
最后还要改变它的属性使它能够执行。chmod +x etc/init.d/rcS
【rc.d/init.d/httpd】:
#!/bin/sh
base=boa
# See how we were called.
case "$1" in
start)
/sbin/$base
;;
stop)
pid=`/bin/pidof $base`
if [ -n "$pid" ]; then
kill -9 $pid
fi
;;
esac
exit 0
【boa/boa.conf】:

【sysconfig/HOSTNAME】:
Embed_jiajintao

“home”目录
存放用户文件的目录,在这里,我建立了一个名为“jiajintao”的目录,前面的passwd 文里面有个用户名就是对应jiajintao这个目录
“lib”目录
常用的库文件,获取库文件的方法:
#cp -f /usr/local/arm/3.4.5/arm-linux/lib/*so* lib –a 
(库文件自己找吧,我是在开发板送的系统内copy来的,这路径只是举例)
这里拷贝了常用的库文件,如果需要特殊的库,需要再从相应的位置复制过来。
“mnt”目录
我们一般用来挂载的U 盘之类的外设,这里建立两个目录“udisk”和“sd”,分别用来挂载U 盘和SD卡。
“opt”目录

“proc”目录
提供一些目录和虚拟文件系统。
“root”目录
超级用户的目录。
“sys”目录
“tmp”目录
存放临时文件的目录。
“var”目录
存放临时文件的目录。
“web”目录
存放web 服务器的相关文件的目录,建议直接从以前制做好的文件系统中拷贝过来。

到此,文件系统的框架就基本搭好了,然后把它做出yaffs 文件系统格式的镜像就可以使用了。使用如下命令制作:
#mkyaffs2image /home/abc/root_yaffs2.img
阅读(1648) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~