根据《Mini2440_Linux移植开发实战指南》一文进行nandflash驱动的移植出现了不少问题
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 于是在自己的mach-mini2440.c中加入 #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> 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] last sysfs file: Modules linked in: 因为 mini2440的 flash的参数应该是:
S3C24XX NAND Driver, (c) 2004 Simtec Electronics s3c2440-nand s3c2440-nand: Tacls=3, 29ns Twrph0=7 69ns, Twrph1=3 29ns 从以上差别可以看出我们 按照友善提供的Linux移植开发实战所修改的下面一个结构体里设置的参数并没有生效: 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, }; 以上的结构体是mini2440开发板上使用的nand flash的一些配置信息,其中包括芯片操作时序信息。 查看nand flash相应的datasheet里面对nand flash控制器的NFCONF寄存器有如下描述 CLE/ALE是高电平使能 而TACLS是CLE/ALE使能的持续时间,也就是CLE/ALE信号线高电平持续的时间; nWE是低电平使能 TWRPH0对应于nWE的使能持续时间,也就是nWE信号线低电平的持续时间; 而TWRPH1对应于nWE信号线高电平的持续时间。 具体如下图:
而 通过内核打印信息+Source Insight查找到输出
S3C24XX NAND Driver, (c) 2004 Simtec Electronics s3c24xx-nand s3c2440-nand: Tacls=4, 39ns Twrph0=8 79ns, Twrph1=8 79ns 语句信息的函数在内核源码中nand flash驱动程序里的drivers/mtd/nand/s3c2410.c文件中。 分析Linux内核中的nand flash驱动drivers/mtd/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; ………… 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)); 由以上内容可以看出,内核并没有使用我们的mini2440_nand_info结 构体中的配置,而是使用了它的默认配给,即 } else { /* default timings */ tacls = tacls_max; twrph0 = 8; twrph1 = 8; } 中的配置信 息。这点和我们改的内核输出s3c24xx-nand s3c2440-nand: Tacls=4, 39ns Twrph0=8 79ns, Twrph1=8 79ns完全符合。 因此可以判断我们需要在mach-mini2440.c的mini2440_machine_init()函数中增加s3c_device_nand.dev.platform_data = &mini240_nand_info; http://xliuning.spaces./blog/cns!C9DB9E35C9DE3752!329.entry |
|