1,按照《Mini2440_Linux移植开发实战指南》一文进行nandflash驱动的移植出现了一些问题,记录下,备后用:
arch/arm/mach-s3c2440/mach-mini2440.c:155: error: array type has incomplete element type
arch/arm/mach-s3c2440/mach-mini2440.c:156: error: array index in non-array initializer
arch/arm/mach-s3c2440/mach-mini2440.c:156: error: (
near
initialization for'
mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:158: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:158: error: (near initialization for 'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:160: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:160: error: (near initialization for 'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:162: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:162: error: (near initialization for 'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:165: error: array index in non-array initializer
arch/arm/mach-s3c2440/mach-mini2440.c:165: error: (near initialization for'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:166: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:166: error: (near initialization for'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:168: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:168: error: (near initialization for 'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:170: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:170: error: (near initialization for'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:173: error: array index in non-array initializer
arch/arm/mach-s3c2440/mach-mini2440.c:173: error: (near initialization for'mini2440_default_nand_part')
arch/arm/mach-s3c2440/mach-mini2440.c:174: error: field name not in record or union initializer
arch/arm/mach-s3c2440/mach-mini2440.c:174: error: (near initialization for'mini2440_default_nand_part')
………………
arch/arm/mach-s3c2440/mach-mini2440.c:211: warning: excess elements in struct initializer
arch/arm/mach-s3c2440/mach-mini2440.c:211: warning: (
near initialization for'mini2440_nand_info')
是因为没有添加相应的头文件:
#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>
把以上头文件添加上以后
,再编译:make zImage
,成功!
2,通过以上的更改,make zImage编译时通过了,可是下载到开发板里面,运行内核时,又报错了:
S3C24XX NAND Driver
, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=4
, 39ns Twrph0=8 79ns
, Twrph1=8 79ns
Unable to handle kernel NULL pointer dereference at virtual address 00000018
pgd = c0004000
[00000018] *pgd=00000000
Internal error: Oops: 5 [#1]
与三星的NAND的时序对比:
S3C24XX NAND Driver
, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=3
, 29ns Twrph0=7 69ns
, Twrph1=3 29ns
与调试的信息不符合。再在drivers/mtd/nand/中查找NAND的驱动程序:s3c2410.c
static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
{
struct s3c2410_platform_nand *plat = info->platform;
int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4;
int tacls
, twrph0
, twrph1;
unsigned long clkrate = clk_get_rate(info->clk);
unsigned long uninitialized_var(set)
, cfg
, uninitialized_var(mask);
unsigned long flags;
/* calculate the timing information
for the controller */
info->clk_rate = clkrate;
clkrate /= 1000; /* turn clock into kHz
for ease of use */
if (plat != NULL) {
tacls = s3c_nand_calc_rate(plat->tacls
, clkrate
, tacls_max);
twrph0 = s3c_nand_calc_rate(plat->twrph0
, clkrate
, 8);
twrph1 = s3c_nand_calc_rate(plat->twrph1
, clkrate
, 8);
} else {
/* default timings */
tacls = tacls_max;
twrph0 = 8;
twrph1 = 8;
}
if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
dev_err(info->device
, "cannot get suitable timings\n");
return -EINVAL;
}
dev_info(info->device
, "Tacls=%d
, %dns Twrph0=%d %dns
, Twrph1=%d %dns\n"
,
tacls
, to_ns(tacls
, clkrate)
, twrph0
, to_ns(twrph0
, clkrate)
, twrph1
, to_ns(twrph1
, clkrate));
switch (info->cpu_type) {
case TYPE_S3C2410:
mask = (S3C2410_NFCONF_TACLS(3) |
S3C2410_NFCONF_TWRPH0(7) |
S3C2410_NFCONF_TWRPH1(7));
set = S3C2410_NFCONF_EN;
set |= S3C2410_NFCONF_TACLS(tacls - 1);
set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
break;
case TYPE_S3C2440:
case TYPE_S3C2412:
mask = (S3C2440_NFCONF_TACLS(tacls_max - 1) |
S3C2440_NFCONF_TWRPH0(7) |
S3C2440_NFCONF_TWRPH1(7));
set = S3C2440_NFCONF_TACLS(tacls - 1);
set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
set |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
break;
default:
BUG();
}
local_irq_save(flags);
cfg = readl(info->regs + S3C2410_NFCONF);
cfg &= ~mask;
cfg |= set;
writel(cfg
, info->regs + S3C2410_NFCONF);
local_irq_restore(flags);
dev_dbg(info->device
, "NF_CONF is 0x%lx\n"
, cfg);
return 0;
}
其中并没有使用我们在mach-mini2440.c中我们为NAND 初始化的信息mini2440_nand_info,而是使用了默认配置:
{
/* default timings */
tacls = tacls_max;
twrph0 = 8;
twrph1 = 8;
}
所以我们在static void __init mini2440_machine_init(void)(此函数在mach-mini2440.c中)中添加
s3c_device_nand.dev.platform_data=&mini2440_nand_info;
将配置的信息传递给驱动。
重新编译
,下载内核
,就可以了。