嵌入式开发实战4——内核的编译之三增加对NAND支持编译


2012-05-31 21:20:10|  分类: ARM开发|举报|字号 订阅

参照友善之壁的内核移植文档,会有错误,通过百度,发现了解决的方法,在这里转载一下,
希望各位遇到同样问题的人有帮助。

嵌入式开发实战4——内核的编译之三增加对NAND支持编译

要让内核支持nand flash就得增加对其支持的代码,大家可以参看一下arch/arm/plat-s3c24xx/common-smdk.c,这个文件,其实在移植到自己的mach-mini2440.c中的很关于对nandflash的支持都是依照着它,然后对照着友善的板子的实际分区环境(其它的移植也要注意这些,一定要和对应的硬件相匹配)来设置的。

好,按照SMDK进行修改如下:

;以下蓝色部分为说明文字

static struct mtd_partition mini2440_default_nand_part[] = {

        [0] = {

                .name   = "supervivi", ;这里是 bootloader 所在的分区,可以放置 u-boot, supervivi 等内容,对应

/dev/mtdblock0

                .size   = 0x00040000,

                .offset = 0,

        },

        [1] = {

                .name   = "param", ;这里是 supervivi 的参数区,其实也属于 bootloader 的一部分,如果 u-boot 比较

大,可以把此区域覆盖掉,不会影响系统启动,对应/dev/mtdblock1

                .offset = 0x00040000,

                .size   = 0x00020000,

        },

        [2] = {

                .name   = "Kernel",  ;内核所在的分区,大小为 5M,足够放下大部分自己定制的巨型内核了,比如内核

使用了更大的 Linux Logo 图片等,对应/dev/mtdblock2

                .offset = 0x00060000,

                .size   = 0x00500000,

        },

        [3] = {

                .name   = "root", ;文件系统分区,友善之臂主要用来存放 yaffs2 文件系统内容,对应/dev/mtdblock3

                .offset = 0x00560000,

                .size   = 1024 * 1024 * 1024, //

        },

        [4] = {

                .name   = "nand", ;此区域代表了整片的 nand flash,主要是预留使用,比如以后可以通过应用程序访

问读取/dev/mtdblock4 就能实现备份整片 nand flash 了。

                .offset = 0x00000000,

                .size   = 1024 * 1024 * 1024, //

        }

};

;这里是开发板的 nand flash 设置表,因为板子上只有一片,因此也就只有一个表

static struct s3c2410_nand_set mini2440_nand_sets[] = {

        [0] = {

                .name           = "NAND",

                .nr_chips       = 1,

                .nr_partitions  = ARRAY_SIZE(mini2440_default_nand_part),

                .partitions     = mini2440_default_nand_part,

        },

};

;这里是 nand flash 本身的一些特性,一般需要对照 datasheet 填写,大部分情况下按照以下参数填写即可

static struct s3c2410_platform_nand mini2440_nand_info = {

        .tacls          = 20,

        .twrph0         = 60,

        .twrph1         = 20,

        .nr_sets        = ARRAY_SIZE(mini2440_nand_sets),

        .sets           = mini2440_nand_sets,

        .ignore_unset_ecc = 1,

};

下面一定要注意加上你对NAND的支持注册到系统中,其实也很简单:

 

static struct platform_device *mini2440_devices[] __initdata = {

  &s3c_device_usb,

&s3c_device_lcd,

  &s3c_device_wdt,

  &s3c_device_i2c0,

  &s3c_device_iis,

  &s3c_device_nand, ;把 nand flash 设备添加到开发板的设备列表结构 

};

 

然后make zImage,不太顺利,报了一大片错,在修改的文件上:

arch/arm/mach-s3c2440/mach-mini2440.c:189: error: array type has incomplete element type 
arch/arm/mach-s3c2440/mach-mini2440.c:190: error: array index in non-array initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:190: error: (near initialization for 'smdk_default_nand_part') 
arch/arm/mach-s3c2440/mach-mini2440.c:191: error: field name not in record or union initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:191: error: (near initialization for 'smdk_default_nand_part')

arch/arm/mach-s3c2440/mach-mini2440.c:193: error: unknown field 'tacls' specified in initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:193: warning: excess elements in struct initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:193: warning: (near initialization for 'mini2440_nand_info') 
arch/arm/mach-s3c2440/mach-mini2440.c:194: error: unknown field 'twrph0' specified in initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:194: warning: excess elements in struct initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:194: warning: (near initialization for 'mini2440_nand_info') 
arch/arm/mach-s3c2440/mach-mini2440.c:195: error: unknown field 'twrph1' specified in initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:195: warning: excess elements in struct initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:195: warning: (near initialization for 'mini2440_nand_info') 
arch/arm/mach-s3c2440/mach-mini2440.c:196: error: unknown field 'nr_sets' specified in initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: type defaults to 'int' in declaration of 'type name' 
arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: type defaults to 'int' in declaration of 'type name' 
arch/arm/mach-s3c2440/mach-mini2440.c:196: error: negative width in bit-field '<anonymous>' 
arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: excess elements in struct initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: (near initialization for 'mini2440_nand_info') 
arch/arm/mach-s3c2440/mach-mini2440.c:197: error: unknown field 'sets' specified in initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:197: warning: excess elements in struct initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:197: warning: (near initialization for 'mini2440_nand_info') 
arch/arm/mach-s3c2440/mach-mini2440.c:198: error: unknown field 'ingnore_unset_ecc' specified in initializer 
arch/arm/mach-s3c2440/mach-mini2440.c:198: warning: excess elements in struct initializer

看错误像是代码敲错了,可是仔细对照过,没有问题,后来查资料发现是缺少头文件:

增加:

#include <linux/mtd/mtd.h> 
#include <linux/mtd/nand.h> 
#include <linux/mtd/nand_ecc.h> 
#include <linux/mtd/partitions.h> 
#include <plat/nand.h> 

编译通过,但是,这里还有一个隐含的BUG,也就是前面写那么多的NAND的INFO,结果你看一下,却没有用,所以,还要在函数void __init smdk_machine_init(void)(有的说在static void __init mini2440_map_io(void) ,其实只要在初始化前都可以)中,增加:

s3c_device_nand.dev.platform_data = &mini2440_nand_info;

这样再make zImage,手头没板子,不知道自己的对不对,有时间回家验证下。

顺道把其它朋友遇到的错误罗列一下,以供参考:

具体方法参考移植手册,常见问题如下。

 

错误一:

 

NOW, Booting Linux......

Uncompressing Linux...................................................................................... done, booting the kernel.

 

 

停止的情况

 

下面的是tools/mach-types中关于体系的参数定义

 

s3c2440            ARCH_S3C2440        S3C2440           362

 

mini2440        MACH_MINI2440        MINI2440        1999

 

解决方法:linux机器码要与bootloader一致,否则出现这个错误!

 

2.内核的配置

 

1..[*] Enable loadable module support --->

 

       [*]   Module unloading

 

 2. System Type ---->

       [*] S3C2410 DMA support       [*] Support ARM920T processor

            S3C2440 Machines --->

               [*] SMDK2440

               [*] SMDK2440 with S3C2440 CPU moduleq

 

其他的比如2410,2443相关的全部去掉

 

3.Boot options   --->

将 (root=/dev/hda1 ro init=/bin/bash console=ttySAC0) Default kernel command string

 

改成    (noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 )

其中 mtdblock2 表示 MTD 分区的第二个分区存文件系统; Linuxrc 为启动的首个脚本。

 

4关掉nand ecc .因为bootload中已经有ecc校验算法

 

Device Drivers --->

       <*> Memory Technology Device (MTD) support --->

               [*]   MTD partitioning support

               <*> NAND Device Support --->

                       <*>   NAND Flash support for S3C2410/S3C2440 SoC

                       [ ]     S3C2410 NAND Hardware ECC     // 这个要去掉

 

3.添加nand flash驱动(可参考arm/plat-s3c24xx/common-smdk.c)

 

  在arm/mach-mini2440.c

 

错误二:

 

//注意结构和函数的顺序

 

中添加static struct mtd_partition mini2440_default_nand_part[] = {

    [0] = {

        .name    = "supervivi",

        .size    =  0x00040000,//dev/mdkbloack0

        .offset    = 0,

    },

    [1] = {

        .name    = "param",

        .offset = 0x00040000,

        .size    = 0x00020000,

    },

    [2] = {

        .name    = "Kernel",

        .offset = 0x00560000,

        .size    =1024 * 1024 * 1024,

    },

    [3] = {

        .name    = "nand",

        .offset    = 0x00000000,

        .size    = 1024 * 1024 * 1024,

    },

   

   

};

 

 

static struct s3c2410_nand_set mini2440_nand_sets[] = {

    [0] = {

        .name        = "NAND",

        .nr_chips    = 1,

        .nr_partitions    = ARRAY_SIZE(mini2440_default_nand_part),

        .partitions    =mini2440_default_nand_part,

    },

};

 

static struct s3c2410_platform_nand mini2440_nand_info = {

    .tacls        = 20,

    .twrph0        = 60,

    .twrph1        = 20,

    .nr_sets    = ARRAY_SIZE(mini2440_nand_sets),

    .sets        = mini2440_nand_sets,

    .ignore_unset_ecc = 1,

};

 

错误三:

Unable to handle kernel NULL pointer dereference at virtual address 00000018

pgd = c0004000

[00000018] *pgd=00000000

Internal error: Oops: 5 [#1]

 

make zIamge下载后报错

 

 

解决办法:

 

static void __init mini2440_machine_init(void)

{

    s3c24xx_fb_set_platdata(&mini2440_fb_info);

    s3c_i2c0_set_platdata(NULL);

   s3c_device_nand.dev.platform_data = &mini2440_nand_info;  //这个函数手册上没有,但得加

 

    platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));

   //smdk_machine_init();

}

 

static struct platform_device *mini2440_devices[] __initdata = {

 

&s3c_device_usb,

 

&s3c_device_lcd,

 

&s3c_device_wdt,

 

&s3c_device_i2c0,

 

&s3c_device_iis,

 

&s3c_device_nand,   // 把 nand flash 设备添加到开发板的设备列表结构

 

};

 

更改drivers/mtd/nand/s3c2410.c关闭ecc校验

 

    chip->ecc.mode        = NAND_ECC_SOFT;

 

 改为:chip->ecc.mode        = NAND_ECC_NONE;

 

 

错误四:

 

arch/arm/mach-s3c2440/mach-mini2440.c:84: error: array type has incomplete element type

arch/arm/mach-s3c2440/mach-mini2440.c:85: error: array index in non-array initializer

arch/arm/mach-s3c2440/mach-mini2440.c:85: error: (near initialization for 'mini2440_nand_sets')

arch/arm/mach-s3c2440/mach-mini2440.c:86: error: field name not in record or union initializer

arch/arm/mach-s3c2440/mach-mini2440.c:86: error: (near initialization for 'mini2440_nand_sets')

arch/arm/mach-s3c2440/mach-mini2440.c:87: error: field name not in record or union initializer

 

在macn-mini2440中添加头文件

 

#include <plat/common-smdk.h>

#include <linux/mtd/mtd.h>

#include <linux/mtd/nand.h>

#include <linux/mtd/nand_ecc.h>

#include <linux/mtd/partitions.h>

#include <plat/nand.h>//这个也不能少的哦 

 

编译后下载:

 

affs: dev is 32505858 name is "mtdblock2"

yaffs: passed flags ""

yaffs: Attempting MTD mount on 31.2, "mtdblock2"

yaffs: auto selecting yaffs2

yaffs_read_super: isCheckpointed 0

VFS: Mounted root (yaffs filesystem) on device 31:2.

Freeing init memory: 128K

 

错误五:

Kernel panic - not syncing: Attempted to kill init

 

解决办法: 这个时候懵了,哪里错呢~ 没办法,只能对照着友善的配置一个个大模块对着来改

当改到Kernel Features的时候错误消失了,原来需要选上

Use the ARM EABI to compile the kernel

Allow old ABI binaries to run with thie Kernel

为什么呢?~ Google了一下,原来友善的根文件系统在编译的时候也启用了EABI特性,内核和文件系统需要对上

文件系统用了EABI 内核也要用EABI 内核不用EABI 也只能读取不用EABI的文件系统

 

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-03/33805p2.htm

以上错误来处上述网址,非常感谢这位朋友的分享。

你们的分享,是前进的最大动力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值