内核编译器版本: 3.4.1
编译busybox-1.7.0的交叉编译器:3.4.1
注:兄弟们都说内核编译器版本和编译busybox的编译器要同一个版本,我没有验证过,就直接用同一个版本的编译器
Busybox版本:1.7.0 (下载地址:我的博客下载原文件)
Yaffs2 :(下载地址:我的博客下载原文件)
一. 做文件系统的脉络介绍
(1) 为什么我们要用busybox,利用他干什么?
我们利用busybox主要是生成文件系统的4个主要文件:bin sbin usr linuxrc这4个文件就是我们要构建的文件系统的主体部分,这个时候busybox对于我们来说就没有什么作用了,我们一般的做法是在其他的地方再建立一个文件夹,然后将bin sbin usr linuxrc拷贝过去,以后我们做的文件系统就是这个新建的文件夹里边的部分。
(2) 用yaffs2生成一个做文件系统镜象的工具
在yaffs2里边有个文件夹叫utils,在这个里边3个文件,Makefile ,mkyaffsimage.c mkyaffs2image.c ,在这个里边按道理是直接make就可以搞定,实际需要加两个文件,这两个文件是处理ECC的。然后在make 就可以生成两个工具文件:mkyaffsimage 和mkyaffs2image
(注:如果在移植的过程就不用看这个东西了,因为要是我在移植的时候一看到这个就觉的烦了,呵呵!这个是给第一次用busybox的兄弟们看的)
二. 具体做的步骤
解压busybox1.7.0,然后在该目录下用make menuconfig 出现配置界面,有几个地方在配置的时候要注意一下:
(1) Miscellaneous Utilities --->
[] taskset要去掉
如果不去掉,出错信息:
miscutils/taskset.c:17: error: parse error before ''*'' token
miscutils/taskset.c:18: warning: function declaration isn''t a prototype
miscutils/taskset.c: In function `__from_cpuset'':
miscutils/taskset.c:22: error: `CPU_SETSIZE'' undeclared (first use in this function)
miscutils/taskset.c:22: error: (Each undeclared identifier is reported only once
miscutils/taskset.c:22: error: for each function it appears in.)
miscutils/taskset.c:26: warning: implicit declaration of function `CPU_ISSET''
miscutils/taskset.c:26: error: `mask'' undeclared (first use in this function)
miscutils/taskset.c: In function `taskset_main'':
miscutils/taskset.c:47: error: `cpu_set_t'' undeclared (first use in this function)
miscutils/taskset.c:47: error: parse error before "mask"
miscutils/taskset.c:68: warning: implicit declaration of function `CPU_ZERO''
miscutils/taskset.c:68: error: `new_mask'' undeclared (first use in this function)
miscutils/taskset.c:69: error: `CPU_SETSIZE'' undeclared (first use in this function)
miscutils/taskset.c:71: warning: implicit declaration of function `CPU_SET''
miscutils/taskset.c:78: error: `mask'' undeclared (first use in this function)
(2) Linux Module Utilities --->
[]Support version 2.2.x to 2.4.x Linux kernels 要去掉
如果不去掉的话,出错信息:
modutils/lib.a(insmod.o)(.text.insmod_main+0x360): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x394): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x440): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x494): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x570): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0xc10): In function `insmod_main'':
: undefined reference to `create_module''
collect2: ld returned 1 exit status
其他的配就可以了,这两个地方要是不去掉的话,编译不过。
(3)用make install命令来安装,就会产生一个文件夹_install,在这个文件家里边有4个文件----- bin sbin usr linuxrc,然后我们在其他目录在用mkdir 建一个文件夹,将这4个文件拷贝过去。这是我们要转到拷贝的目录来完善我们的文件系统。(注:我在根目录下建了一个名字为filesystem_install的文件夹)
(4)在filesystem_install文件夹下面用mkdir建立文件夹: dev etc home lib mnt proc root sys tmp var
(5)我们在etc下面要写两个文件fstab inittab 和一个文件夹init.d
(a) Fstab的内容是:
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
(b) fstab文件的作用
文 件/etc/fstab存放的是系统中的文件系统信息。当正确的设置了该文件,则可以通过"mount /directoryname"命令来加载一个文 件系统,每种文件系统都对应一个独立的行,每行中的字段都有空格或tab键分开。同时fsck、mount、umount的等命令都利用该程序。
Inittab的内容是:
#/etc/inittab
::sysinit:/etc/init.d/rcS
ttySAC0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
(c) init.d\rcS文件的内容:
#!/bin/sh
ifconfig eth0 192.168.1.17
mount –a
(d)记的要将rcS文件的属性改成可执行的,就是rcS的颜色变成绿色了就可以了,这一步很重要,必须改。
改变其属性:chmod +x etc/init.d/rcS
(e)我在配置busybox的时候用的是动态库,所以要把/usr/local/arm/3.4.1/arm-linux/lib下面的3个库文件和一个加载器拷贝到/filesystem_install/lib下:ld-2.3.2.so ld-linux.so.2 libc.so.6 libcrypt.so.1 libm.so.6
(f)在/filesystem_install/dev下建立设备节点:
Console mtdblock0 mtdblock1 mtdblock2 null ttySAC0
用这样的命令建立:
sudo mknod console c 5 1
sudo mknod null c 1 3
三. 修改制作yaffs映象文件的工具
在 yaffs 源码中有个 utils 目录,里面是工具 mkyaffsimage 和 mkyaffs2image的源代码,前者用来制作 yaffs1 映象文件,后者用来制作 yaffs2 映象文件。目前 mkyaffsimage 工具只能生成老格式的yaffs1 映象文件,需要修改才能支持新格式。
(1)下载的yaffs2解压出来是这样的一个目录/Development下面有两个文件夹:yaffs yaffs2,我们需要进入yaffs2,然后再进入utils,这个下面有3个文件,我们需要加两个文件,nand-ecc.c yaffs_packedtags1.c ,yaffs_packedtags1.c这个文件是从上一节目录拷贝过来的,nand-ecc.c的原码如下:
#include
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
static const u_char nand_ecc_precalc_table[] = {
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
};
int nand_calculate_ecc(const u_char *dat, u_char *ecc_code)
{
uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
int i;
reg1 = reg2 = reg3 = 0;
for(i = 0; i < 256; i++) {
idx = nand_ecc_precalc_table[*dat++];
reg1 ^= (idx & 0x3f);
if (idx & 0x40) {
reg3 ^= (uint8_t) i;
reg2 ^= ~((uint8_t) i);
}
}
tmp1 = (reg3 & 0x80) >> 0;
tmp1 |= (reg2 & 0x80) >> 1;
tmp1 |= (reg3 & 0x40) >> 1;
tmp1 |= (reg2 & 0x40) >> 2;
tmp1 |= (reg3 & 0x20) >> 2;
tmp1 |= (reg2 & 0x20) >> 3;
tmp1 |= (reg3 & 0x10) >> 3;
tmp1 |= (reg2 & 0x10) >> 4;
tmp2 = (reg3 & 0x08) << 4;
tmp2 |= (reg2 & 0x08) << 3;
tmp2 |= (reg3 & 0x04) << 3;
tmp2 |= (reg2 & 0x04) << 2;
tmp2 |= (reg3 & 0x02) << 2;
tmp2 |= (reg2 & 0x02) << 1;
tmp2 |= (reg3 & 0x01) << 1;
tmp2 |= (reg2 & 0x01) << 0;
#ifdef CONFIG_MTD_NAND_ECC_SMC
ecc_code[0] = ~tmp2;
ecc_code[1] = ~tmp1;
#else
ecc_code[0] = ~tmp1;
ecc_code[1] = ~tmp2;
#endif
ecc_code[2] = ((~reg1) << 2) | 0x03;
return 0;
}
EXPORT_SYMBOL(nand_calculate_ecc);
static inline int countbits(uint32_t byte)
{
int res = 0;
for (;byte; byte >>= 1)
res += byte & 0x01;
return res;
}
int nand_correct_data(u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{
uint8_t s0, s1, s2;
#ifdef CONFIG_MTD_NAND_ECC_SMC
s0 = calc_ecc[0] ^ read_ecc[0];
s1 = calc_ecc[1] ^ read_ecc[1];
s2 = calc_ecc[2] ^ read_ecc[2];
#else
s1 = calc_ecc[0] ^ read_ecc[0];
s0 = calc_ecc[1] ^ read_ecc[1];
s2 = calc_ecc[2] ^ read_ecc[2];
#endif
if ((s0 | s1 | s2) == 0)
return 0;
if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
uint32_t byteoffs, bitnum;
byteoffs = (s1 << 0) & 0x80;
byteoffs |= (s1 << 1) & 0x40;
byteoffs |= (s1 << 2) & 0x20;
byteoffs |= (s1 << 3) & 0x10;
byteoffs |= (s0 >> 4) & 0x08;
byteoffs |= (s0 >> 3) & 0x04;
byteoffs |= (s0 >> 2) & 0x02;
byteoffs |= (s0 >> 1) & 0x01;
bitnum = (s2 >> 5) & 0x04;
bitnum |= (s2 >> 4) & 0x02;
bitnum |= (s2 >> 3) & 0x01;
dat[byteoffs] ^= (1 << bitnum);
return 1;
}
if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
return 1;
return -1;
}
在mkyaffsimage.c里边修改原码为:
加这个头文件:#include "yaffs_packedtags1.h"
static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes)
{
#ifdef CONFIG_YAFFS_9BYTE_TAGS
yaffs_Tags t;
yaffs_Spare s;
error = write(outFile,data,512);
if(error < 0) return error;
memset(&t,0xff,sizeof (yaffs_Tags));
memset(&s,0xff,sizeof (yaffs_Spare));
t.chunkId = chunkId;
t.serialNumber = 0;
t.byteCount = nBytes;
t.objectId = objId;
if (convert_endian)
{
little_to_big_endian(&t);
}
yaffs_CalcTagsECC(&t);
yaffs_LoadTagsIntoSpare(&s,&t);
yaffs_CalcECC(data,&s);
nPages++;
return write(outFile,&s,sizeof(yaffs_Spare));
#else
yaffs_PackedTags1 pt1;
yaffs_ExtendedTags etags;
__u8 ecc_code[6];
__u8 oobbuf[16];
error = write(outFile,data,512);
if(error < 0) return error;
etags.chunkId = chunkId;
etags.serialNumber = 0;
etags.byteCount = nBytes;
etags.objectId = objId;
etags.chunkDeleted = 0;
yaffs_PackTags1(&pt1, &etags);
yaffs_CalcTagsECC((yaffs_Tags *)&pt1);
memset(oobbuf, 0xff, 16);
memcpy(oobbuf+8, &pt1, 8);
nand_calculate_ecc(data, &ecc_code[0]);
nand_calculate_ecc(data+256, &ecc_code[3]);
oobbuf[0] = ecc_code[0];
oobbuf[1] = ecc_code[1];
oobbuf[2] = ecc_code[2];
oobbuf[3] = ecc_code[3];
oobbuf[6] = ecc_code[4];
oobbuf[7] = ecc_code[5];
nPages++;
return write(outFile, oobbuf, 16);
#endif
}
修改Makefile文件:
MKYAFFSSOURCES = mkyaffsimage.c yaffs_packedtags1.c nand-ecc.c
yaffs_packedtags1.c和nand-ecc.c是我们加上去的
这样我们就可以用make命令来生成工具文件了:mkyaffsimage 和mkyaffs2image
现在我们来制作镜象文件,把目录转到我们文件系统的文件夹上一个目录,我是转到根目录,因为我是在根目录创建了filesystem_install目录,为了方便用mkyaffsimage命令,我们直接把mkyaffsimage拷贝到根目录的bin里边,这样这个命令就可以用了,这样我们就可以用下面的命令来生成镜象文件了:mkyaffsimage filesystem_install (自己命个名字给镜象文件,但是后缀一定是yaffs,比如:myyaffs.yaffs),
这样我们就全部搞定了一个根文件系统yaffs,这样我们就可以下载的板上面去测试,我这样的做的,是完全成功的,在环境变量里边还有设置个变量:bootargs=noinitrd console=ttySAC0 root=/dev/mtdblock2 rootfstype=yaffs到此为止,全部搞定。如果有什么问题,可以一起交流,我的QQ:276290142,欢迎大家来交流。联系客服