昨天按照 linux一直开发实战指南 在弄nand flash。可是怎么弄都不成功,具体如下:
load Image of Linux...Uncompressing
Linux...................................................................................................................................
done, booting the kernel.
Linux version 2.6.32.2 (ldomain) (gcc
version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #4 Thu Jun 3 17:01:52 CST
2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU:
VIVT data cache, VIVT instruction cache
Machine: My mini2440
Development board
ATAG_INITRD is deprecated; please update your
bootloader.
Memory policy: ECC disabled, Data cache writeback
CPU
S3C2440A (id 0x32440001)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C244X:
core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
CLOCK:
Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in
Zone order, mobility grouping on. Total pages: 16256
Kernel command
line: noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0
PID
hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash
table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table
entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory:
60500KB available (3672K code, 417K data, 132K init, 0K highmem)
SLUB:
Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical
RCU implementation.
NR_IRQS:85
irq: clearing subpending status
00000002
Console: colour dummy device 80x30
console [ttySAC0]
enabled
Calibrating delay loop... 201.93 BogoMIPS (lpj=504832)
Mount-cache
hash table entries: 512
CPU: Testing write buffer coherency: ok
NET:
Registered protocol family 16
S3C2440: Initialising architecture
S3C2440:
IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec
Electronics
DMA channel 0 at c4808000, irq 33
DMA channel 1 at
c4808040, irq 34
DMA channel 2 at c4808080, irq 35
DMA channel 3
at c48080c0, irq 36
S3C244X: Clock Support, DVS off
bio: create
slab
at 0
usbcore: registered new interface driver
usbfs
usbcore: registered new interface driver hub
usbcore:
registered new device driver usb
s3c-i2c s3c2440-i2c: slave address
0x10
s3c-i2c s3c2440-i2c: bus frequency set to 98 KHz
s3c-i2c
s3c2440-i2c: i2c-0: S3C I2C adapter
NET: Registered protocol family 2
IP
route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP
established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind
hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables
configured (established 2048 bind 2048)
TCP reno registered
NET:
Registered protocol family 1
RPC: Registered udp transport module.
RPC:
Registered tcp transport module.
RPC: Registered tcp NFSv4.1
backchannel transport module.
JFFS2 version 2.2. (NAND) 漏 2001-2006
Red Hat, Inc.
ROMFS MTD (C) 2007 Red Hat, Inc.
msgmni has been set
to 118
alg: No test for stdrng (krng)
io scheduler noop
registered
io scheduler anticipatory registered (default)
io
scheduler deadline registered
io scheduler cfq registered
Console:
switching to colour frame buffer device 60x53
fb0: s3c2410fb frame
buffer device
s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq
= 70) is a S3C2440
s3c2440-uart.1: s3c2410_serial1 at MMIO
0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: s3c2410_serial2 at
MMIO 0x50008000 (irq = 76) is a S3C2440
brd: module loaded
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:
CPU: 0 Not tainted (2.6.32.2 #4)
PC is at
s3c24xx_nand_probe+0x2d8/0x514
LR is at
s3c24xx_nand_probe+0x1a4/0x514
pc : [] lr :
[] psr: 60000013
sp : c3823f08 ip : 00000000 fp :
00000001
r10: 00000000 r9 : 00000000 r8 : 00000000
r7 :
c03e5388 r6 : 00000000 r5 : c39b0640 r4 : c3863800
r3 :
00000001 r2 : c3863988 r1 : c4c00000 r0 : 00000002
Flags:
nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control:
c000717f Table: 30004000 DAC: 00000017
Process swapper (pid: 1,
stack limit = 0xc3822270)
Stack: (0xc3823f08 to 0xc3824000)
3f00:
00000000 c00d398c c385a2d0 00000000 00000000 c03e5390
3f20: c03e5390
c03fbb40 c39ad960 c03fa5f8 00000000 00000000 00000000 c01c51d8
3f40:
c03e5390 c01c43c4 c03e5390 c03e53c4 c03fbb40 c39ad960 c03fa5f8 c01c44d4
3f60:
00000000 c01c4478 c03fbb40 c01c3ca4 c3804938 c38474b0 c00220dc c03fbb40
3f80:
c03fbb40 c01c3604 c039066f c039066f 00000006 c00220dc 00000000 c03fbb40
3fa0:
c001a8b4 00000000 00000000 c01c47a0 c00220dc 00000000 00000000 c001a8b4
3fc0:
00000000 c002937c c001a8b4 c03ffa34 c0407540 c0022244 c00220dc 00000000
3fe0:
00000000 00000000 00000000 c00083f8 00000000 c002a854 33cc33cc 33cc33cc
[]
(s3c24xx_nand_probe+0x2d8/0x514) from []
(platform_drv_probe+0x18/0x1c)
[]
(platform_drv_probe+0x18/0x1c) from []
(driver_probe_device+0xa8/0x15c)
[]
(driver_probe_device+0xa8/0x15c) from []
(__driver_attach+0x5c/0x7c)
[]
(__driver_attach+0x5c/0x7c) from []
(bus_for_each_dev+0x48/0x78)
[]
(bus_for_each_dev+0x48/0x78) from []
(bus_add_driver+0x98/0x21c)
[]
(bus_add_driver+0x98/0x21c) from []
(driver_register+0xa4/0x130)
[]
(driver_register+0xa4/0x130) from []
(do_one_initcall+0x5c/0x1b4)
[]
(do_one_initcall+0x5c/0x1b4) from []
(kernel_init+0x94/0x10c)
[] (kernel_init+0x94/0x10c)
from [] (kernel_thread_exit+0x0/0x8)
Code: e584321c
e58420c4 e58452ac e58482a8 (e5983018)
---[ end trace
fef4b2b65d07ac6c ]---
Kernel panic - not syncing: Attempted to kill
init!
[] (unwind_backtrace+0x0/0xdc) from
[] (panic+0x40/0x120)
[]
(panic+0x40/0x120) from [] (do_exit+0x64/0x58c)
[]
(do_exit+0x64/0x58c) from [] (die+0x15c/0x180)
[]
(die+0x15c/0x180) from [] (__do_kernel_fault+0x64/0x74)
[]
(__do_kernel_fault+0x64/0x74) from []
(do_page_fault+0x1b8/0x1cc)
[]
(do_page_fault+0x1b8/0x1cc) from []
(do_DataAbort+0x34/0x94)
[] (do_DataAbort+0x34/0x94)
from [] (__dabt_svc+0x40/0x60)
Exception
stack(0xc3823ec0 to 0xc3823f08)
3ec0: 00000002 c4c00000 c3863988
00000001 c3863800 c39b0640 00000000 c03e5388
3ee0: 00000000 00000000
00000000 00000001 00000000 c3823f08 c01e9eb0 c01e9fe4
3f00: 60000013
ffffffff
[] (__dabt_svc+0x40/0x60) from
[] (s3c24xx_nand_probe+0x2d8/0x514)
[]
(s3c24xx_nand_probe+0x2d8/0x514) from []
(platform_drv_probe+0x18/0x1c)
[]
(platform_drv_probe+0x18/0x1c) from []
(driver_probe_device+0xa8/0x15c)
[]
(driver_probe_device+0xa8/0x15c) from []
(__driver_attach+0x5c/0x7c)
[]
(__driver_attach+0x5c/0x7c) from []
(bus_for_each_dev+0x48/0x78)
[]
(bus_for_each_dev+0x48/0x78) from []
(bus_add_driver+0x98/0x21c)
[]
(bus_add_driver+0x98/0x21c) from []
(driver_register+0xa4/0x130)
[]
(driver_register+0xa4/0x130) from []
(do_one_initcall+0x5c/0x1b4)
[]
(do_one_initcall+0x5c/0x1b4) from []
(kernel_init+0x94/0x10c)
[] (kernel_init+0x94/0x10c)
from [] (kernel_thread_exit+0x0/0x8)
后来网上又是猛查,说是上面红色的地方的问题。
因为 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;
(注: 原来论坛上 讲的方法 增加 s3c_nand_set_platdata(&mini2440_nand_info);是不行的,因为 这个函数在 2.6.32中没有,我在2.6.34中找到了。)
语
句来设置当前平台所使用的存储nand flash配置的相应结构体mini2440_nand_info。
解决方法:
只需在
mach-mini2440.c的初始化函数mini2440_machine_init(void)里加入s3c_device_nand.dev.platform_data =
&mini240_nand_info;即
可。
严重参考:
阅读(2267) | 评论(2) | 转发(0) |