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

 

记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([email protected])),从百度文库中找到的: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);
   
}

你可能感兴趣的:(linux,image,Flash,byte,hex,编译器)