您的位置:首页 > 编程语言 > PHP开发

记2416移植2.6.36内核和yaffs根文件系统时遇到的一些问题

2011-05-13 15:51 453 查看
记2416上移植2.6.36内核和yaffs文件系统时遇到的一些问题



参考文章:
http://blog.sina.com.cn/s/blog_77aea4c60100qsa1.html

一、uboot中将内核uImage烧进nand flash后,启动内核时报如下错误:



# Booting kernel from Legacy Image at 30008000 ...

Image Name: Linux-2.6.36

Created: 2011-01-21 2:28:54 UTC

Image Type: ARM Linux Kernel Image (uncompressed)

Data Size: 2799972 Bytes = 2.7 MiB

Load Address: 30008000

Entry Point: 30008000

Verifying Checksum ... OK

XIP Kernel Image ... OK

OK

Starting kernel ...

data abort

pc : [<30008008>] lr : [<33f23fa4>]

sp : 33dffb50 ip : 00000000 fp : 30008000

r10: 33f4603c r9 : 00000695 r8 : 33dfffe0

r7 : 33dfffc4 r6 : 33e01355 r5 : 30000124 r4 : 00000000

r3 : 00000000 r2 : 30000100 r1 : 00000695 r0 : 00000000

Flags: nzCv IRQs off FIQs off Mode SVC_32

Resetting CPU ...

析:

很有可能是Load Address: 30008000和Entry Point: 30008000一样导致的。

解决办法:重新编译内核

make zImage;

mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n "linux-2.6.36" -d ./arch/arm/boot/zImage uImage

mkimage给zImage添加一个信息头header,生成uImage

-A arm 架构是arm

-O linux 操作系统是linux

-T kernel 类型是kernel

-C none 压缩类型为无压缩

-a 30008000 image的载入地址(hex)

-e 30008040 内核的入口地址(hex),因为信息头的大小是0x40

-n linux-2.6.36 image的名字

-d zImage 无头信息的image文件名

uImage 加了头信息之后的image文件名

二、在uboot下,命令write.yaffs 30000000 500000 1080840,将用yaffs2/utils里的工具mkyaffs2image.c生成的文件系统镜像,烧到nand flash上面,reset重启后报错Kernel panic:

[ 0.680000] NAND device: Manufacturer ID: 0xad, Chip ID: 0xf1 (Hynix NAND 128MiB 3,3V 8-bit)

[ 0.685000] Scanning device for bad blocks

[ 0.695000] Bad eraseblock 41 at 0x000000520000

[ 0.695000] Bad eraseblock 42 at 0x000000540000

…………中间很多的Bad eraseblock…………

[ 2.025000] Bad eraseblock 441 at 0x000003720000

[ 2.030000] Bad eraseblock 442 at 0x000003740000

[ 2.080000] Creating 4 MTD partitions on "NAND":

[ 2.080000] 0x000000000000-0x000000100000 : "u-boot"

[ 2.090000] 0x000000100000-0x000000500000 : "kernel"

[ 2.095000] 0x000000500000-0x000002500000 : "rootfs"

[ 2.100000] 0x000002500000-0x000008000000 : "work"

析:

出现如此多的Bad eraseblock,好好的nand flash不可能突然会有那么多的坏块,应该是软件误认为坏块。

Nand flash中(大页2k+64B)每页2k有64Bytes的spare data,用来记录ECC校验和坏块等信息,这里很有可能是mkyaffs2image把Block status byte坏块标志位误写成是坏块了。64Bytes spare data中,第00 Byte(offset=00)就是Block status byte坏块标志位,第01 Byte保留,而0x02 Byte到0x27 Byte共38Bytes用来存储其它信息(oobfree),0x28~0x3F存储ECC校验,这些体现在结构体yaffs_ExtendedTags中。

如果第00 Byte中有任何一位为0,则认为是坏块,问题很有可能就出现在这里,回头看mkyaffs2image.c中write_chunk函数,发现它将0x02~0x27Byte的内容写到0x00Byte开始的地方,故需要后移两位,从0x02开始写,重新制作文件系统,并在uboot下用nand scrub檫除全部后烧写,OK

参考文章:
http://blog.csdn.net/pottichu/archive/2009/07/23/4372593.aspx

http://topic.csdn.net/u/20100225/09/dd14d827-e92a-46ed-b4ad-c5a9f4b90a65.html

三、移植内核和文件系统时报错:



[ 0.895000] yaffs: dev is 32505858 name is "mtdblock2" rw

[ 0.900000] yaffs: passed flags ""

[ 1.380000] VFS: Mounted root (yaffs2 filesystem) on device 31:2.

[ 1.380000] devtmpfs: mounted

[ 1.385000] Freeing init memory: 160K

[ 1.385000] Failed to execute /linuxrc. Attempting defaults...

[ 1.400000] Kernel panic - not syncing: No init found. Try passing init= option to kernel.

See Linux Documentation/init.txt for guidance.

[ 1.405000] [<c0037314>] (unwind_backtrace+0x0/0xfc) from [<c0034f18>] (dump_stack+0x1c/0x20)

析:

1、有可能是/linuxrc文件出问题;2、我遇到的是:首先在kernel源码drivers/mtd/nand/s3c2410.c函数s3c2410_nand_init_chip中,将chip->ecc.mode = NAND_ECC_SOFT;改为chip->ecc.mode = NAND_ECC_NONE;,然后在内核配置make menuconfig中禁止Samsung S3C NAND Hardware ECC

这样就使内核从nand flash中读数据的时候不做任何ECC。在内核启动时将会得到如下警告:

[ 0.695000] NAND_ECC_NONE selected by board driver. This is not recommended !!

四、移植好内核和文件系统后,在shell命令行下执行上层应用程序,报Segmentation fault段错误

析:


1、一般情况下Segmentation fault段错误是由于应用程序的问题,关于此类错误的总结,网上一篇文章很经典(Author: ZX_WING(xing5820@163.com)),从百度文库中找到的:http://wenku.baidu.com/view/8ea6f500bed5b9f3f90f1cb9.html

2、实际情况中,应用程序在NFS根文件系统中(移植前)是运行良好的,移植后就变成这种情况了,一直以为是应用程序出了问题,在调试应用程序郁闷了好几天,最后才怀疑到库,原来是自己在移植过程中更换了交叉编译器,但是库没有跟着变换,将库更换后,重新用相同的交叉编译器编译应用程序后OK。

所以还是要细心啊!细心的话会少走很多弯路。

五、移植好内核和文件系统已烧进nand中后,启动时报错:

[ 1.690000] VFS: Mounted root (yaffs2 filesystem) on device 31:2.

[ 1.690000] devtmpfs: mounted

[ 1.695000] Freeing init memory: 152K

/linuxrc: /lib/libc.so.6: version `GLIBC_2.7' not found (required by /linuxrc)

/linuxrc: /lib/libc.so.6: version `GLIBC_2.8' not found (required by /linuxrc)

/linuxrc: /lib/libc.so.6: version `GLIBC_2.11' not found (required by /linuxrc)

[ 1.890000] Kernel panic - not syncing: Attempted to kill init!

析:

错误中可以知道,根文件系统已经成功挂接,在执行初始化init=/linuxrc时出错,很有可能是/lib/中不存在libc.so.6或者由于更换了交叉编译引起的库不一样。

解决方法:

1、确认/lib中存在libc.so.6;

2、如果没有或一时找不到libc.so.6,可以使libc.so.6软链接到libc.so去;

3、还不行的话,更换整个/lib中的库,库应该和你的交叉编译器的一致

附:mkyaffs2image.c的write_chunk函数

参考文章http://blog.csdn.net/itismine/archive/2009/11/11/4799770.aspx

itismine “mkyaffs2image工具解析”

static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes)

{

yaffs_ExtendedTags t;

yaffs_PackedTags2 pt;

/*-------------------------change------------------------------*/

__u8 spare_buf[spareSize];

memset(spare_buf,0,spareSize);/**/

/*---------------------*/

error = write(outFile,data,chunkSize);

if(error < 0) return error;

yaffs_InitialiseTags(&t);

t.chunkId = chunkId;

//t.serialNumber = 0;

t.serialNumber = 1; // **CHECK**

t.byteCount = nBytes;

t.objectId = objId;

t.sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;

//added NCB **CHECK**

t.chunkUsed = 1;

if (convert_endian)

{

little_to_big_endian(&t);

}

yaffs_PackTags2(&pt,&t,1);

/*-----------------------change--------------------------------*/

memset(spare_buf, 0xff, sizeof(spare_buf));/*00byte必须为0xff,标志为好块*/

nand_mtd2_pt2buf(spare_buf, &pt);/*按照oob_layout拷贝到spare_buf中*/

yaffs_PutDataECC(data, &spare_buf[0]);/*重新计算ECC*/

/*---------------------*/

nPages++;

//return write(outFile,&pt,sizeof(yaffs_PackedTags2));

return write(outFile,spare_buf,spareSize);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: