1.修正Makefile
#cd linux-2.6.14
#vi Makefile
修正内容如下
ARCH =arm
CROSS_COMPILE = arm-linux-
下载穿插编译器arm-linux-gcc3.4.1
http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2
解压后,把穿插编译东西链的途径增加到环境变量中(修正/etc/bashrc文件)
2.设置Nand Flash分区
修正linux-2.6.14\arch\arm\mach-s3c2410\devs.c
(1)增加下列头文件
#include
#include
#include
(2)增加NandFlash分区表
static struct mtd_partition partition_info[]={
{
name:”bootloader”,
size:0x00020000,
offset:0x0,
},
{
name:”param”,
size:0x00010000,
offset:0x00020000,
},
{
name:”kernel”,
size:0x001c0000,
offset:0x00030000,
},
{
name:”rootfs”,
size:0x03e00000,
offset:0x00200000,
//mask_flags:MTD_WRITEABLE,
}//,
};
其间
name:代表分区姓名
size:代表flash分区巨细(单位:字节)
offset:代表flash分区的开端地址(相对于0x0的偏移)
(3)参加Nand Flash分区
structs3c2410_nand_setnandset={
nr_partitions:4,//5,
partitions:partition_info,
};
nr_partitions:指明partition_info中界说的分区数目
partitions:分区信息表
(4)树立Nand Flash芯片支撑
struct s3c2410_platform_nandsuperlpplatform={
tacls:0,
twrph0:30,
twrph1:0,
sets:&nandset,
nr_sets:1,
};
tacls, twrph0, twrph1的意思见S3C2410手册的63,
这3个值最终会被设置到NFCONF中,见S3C2410手册66.
sets:支撑的分区集
nr_sets:分区集的个数
(5)参加Nand Flash芯片支撑到Nand Flash驱动
别的,还要修正此文件中的s3c_device_nand结构体变量,增加对dev成员的赋值
struct platform_device s3c_device_nand = {
.name= “s3c2410-nand”,
.id= -1,
.num_resources= ARRAY_SIZE(s3c_nand_resource),
.resource= s3c_nand_resource,
.dev={
.platform_da
}
};
name:设备称号
id:有用设备编号,假如只要仅有的一个设备为1,
有多个设备从0开端计数.
num_resource:有几个寄存器区
resource:寄存器区数组首地址
dev:支撑的Nand Flash设备
修正linux-2.6.14\arch\arm\mach-s3c2410\mach-smdk2410.c
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_nand,
};
(6)制止Flash ECC校验
内核都是通过UBOOT写到Nand Flash的, UBOOT通过的软件ECC算法发生ECC校验码,这与内核校验的ECC码不相同,内核中的ECC码是由S3C2410中Nand Flash控制器发生的.所以,咱们在这儿挑选制止内核ECC校验.
修正linux-2.6.14\drivers\mtd\nand\s3c2410.c
找到函数s3c2410_nand_init_chip
最终一条句子chip->eccmode= NAND_ECC_SOFT;
改为chip->eccmode= NAND_ECC_NONE;
3.装备内核选项
参阅smdk2410开发板的装备文件,将其默许的装备文件复制到内核代码的根目录下,然后开端装备内核
#cd linux-2.6.14
#cp arch/arm/configs/smdk2410_defconfig.config
#make menuconfig
留意:在每个选项前有个方括号,其间[*]/<*>表明该选项参加内核编译;[ ]/<>表明不挑选该选项;
Loadable module support ->
[*]Enable loadable module support #该选项的意图是使内核支撑可加载模块,需求运用modprobe lsmod modinfo insmod rmmod等东西,所以有必要挑选;
[*]Module unloading #卸载模块选项
[*]Force module unloading#强制性卸载模块选项,如用rmmod –f指令强制卸载;
[ ]Module versioning support
[ ]Source checksum for all modules
[*]Automatic kernel module loading#内核在使命中要运用一些被编译为模块的驱动或特性时,先运用modprobe指令来加载它,然后该选项主动调用modprobe加载需求的模块,所以该选项一定要挑选.
参加内核对S3C2410 DMA(Direct Memory Access)的支撑,装备如下:
System Type ->
[*]S3C2410 DMA support
修正指令行参数
Boot options ->
Default kernel command string
修正后内容如下:
noinitrd root=/dev/mtdblock3init=/linuxrc console=ttySAC0,115200 mem=64M
或许
noinitrd root=/dev/mtdblock/3init=/linuxrc console=ttySAC0,115200 mem=64M
mtdblock3表明运用Flash的第4个分区(便是rootfs分区),console=ttySAC0表明kernel发动期间的信息悉数输出到串口0上,115200表明波特率为115200,
mem=64M表明内存巨细为64MB
增加对浮点算法的支撑
Floating point emulation ->
[*]NWFPE math emulation#支撑NWFPE浮点数,在许多情况下要运用,所以最好选上
对MTD(Memory Technology Devices)设备(如Flash RAM等芯片)进行装备,挑选装备如下
Device Drivers->
Memory Technology Devices(MTD)->
[*]MTD partitioning support
Device Drivers->
Memory Technology Devices(MTD)->
RAM/ROM/Flash chip drivers->
<*>Detect flash chips by Common Flash Interface(CFI)probe
<*>Detect non-CFI AMD/JEDEC-compatible flash chips
<*>Support for Intel/Sharp flash chips
<*>Support for AMD/Fujitsu flash chips
<*>Support for ROM chips in bus mapping
Device Drivers->
Memory Technology Devices(MTD)->
NAND Flash Device Drivers->
<*>NAND Device Support
<*>NAND Flash support for S3C2410/S3C2440 SoC
为了要内核支撑devfs(Device Filesystem,设备文件体系),以及在发动时能主动加载/dev为devfs,需求对文件体系进行设置。
File systems ->
< >Second extended fs support#去除对ext2的支撑
Linux2.6.14 fs/Kconfig没有支撑devfs的选项(从2.6.13开端),所以make menuconfig时找不到相关菜单项
从2.6.10的fs/Kconfig中copy几项过来
config DEVFS_FS
bool “/dev file system support (OBSOLETE)”
depends on EXPERIMENTAL
help
This is support for devfs, a virtual file system (like /proc) which
provides the file system interface to device drivers, normally found
in /dev. Devfs does not depend on major and minor number
allocations. Device drivers register entries in /dev which then
appear automatically, which means that the system administrator does
not have to create character and block special device files in the
/dev directory using the mknod command (or MAKEDEV script) anymore.
This is work in progress. If you want to use this, you *must* read
the material in
the file README there.
Note that devfs no longer manages /dev/pts!If you are using UNIX98
ptys, you will also need to mount the /dev/pts filesystem (devpts).
Note that devfs has been obsoleted by udev,
It has been stripped down to a bare minimum and is on
legacy installations that use its naming scheme which is
unfortunately different from the names normal Linux installations
use.
If unsure, say N.
config DEVFS_MOUNT
bool “Automatically mount at boot”
depends on DEVFS_FS
help
This option appears if you have CONFIG_DEVFS_FS enabled. Setting
this to Y will make the kernel automatically mount devfs on
when the system is booted, before the init thread is started.
You can override this with the “devfs=nomount” boot option.
If unsure, say N.
config DEVFS_DEBUG
bool “Debug devfs”
depends on DEVFS_FS
help
If you say Y here, then the /dev file system co
debugging messages. See the file
details.
If unsure, say N.
File systems ->
Pseudo filesystems ->
[*]/proc file system support
[*]/dev file system support(OBSOLETE)
[*]Automatically mount at boot
[*]Virtual memory file system support(former shm fs)
Miscellaneous filesystems ->
<*>Compressed ROM file system support(cramfs)
Network File Systems ->
<*>NFS file system support
除此之外,还需求装备一下选项支撑S3C2410 RTC,USB,MMC/SD卡驱动,详细选项如下:
Device Drivers->
Character devices->
[*]Nonstandard serial port support
[*]S3C2410 RTC Driver
Device Drivers->
USB Support->
<*>Support for Host-side USB
Device Drivers->
MMC/SD Card Support
<*>MMC Support
<*>MMC block device driver
调试进程中呈现的问题及解决办法
1.Starting kernel …就打住了
应该是从u-boot跳转至内核的地址不正确,我下载的加了0x40字节头信息的内核镜像,下载到0x30008000,正确的跳转地址应该是0x30008040,在
u-boot-1.1.3\lib_arm\armlinux.c的do_bootm_linux函数代码如下:
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],ulong addr, ulong *len_ptr, int verify)
{
DECLARE_GLOBAL_DA
ulong len = 0, checksum;
ulong initrd_start, initrd_end;
ulong da
void (*theKernel)(int zero, int arch, uint params);
image_header_t *hdr = &header;
bd_t *bd = gd->bd;
. . .
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
. . .
/* we assume that the kernel is in place */
printf (“\nStarting kernel …\n\n”);
#ifdef CONFIG_USB_DEVICE
{
extern void udc_disconnect (void);
udc_disconnect ();
}
#endif
cleanup_before_linux ();
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
}
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
typedef struct image_header {
uint32_tih_magic;/* Image Header Magic Number*/
uint32_tih_hcrc;/* Image Header CRC Checksum*/
uint32_tih_time;/* Image Creation Timestamp*/
uint32_tih_size;/* Image Da
uint32_tih_load;/* Da
uint32_tih_ep;/* Entry Point Address*/
uint32_tih_dcrc;/* Image Da
uint8_tih_os;/* Operating System*/
uint8_tih_arch;/* CPU architecture*/
uint8_tih_type;/* Image Type*/
uint8_tih_comp;/* Compression Type*/
uint8_tih_name[IH_NMLEN];/* Image Name*/
} image_header_t;
能够看出跳转地址是由image_header结构体的ih_ep(Entry Point Address)成员来承认的,而ih_ep是由mkimage时自己填写的,如下是我填充的mkimage参数,其间的
-e 0x30008000便是来填充ih_ep成员的.
mkimage -A arm -O Linux -T kernel -C none -a 0x30008000-e 0x30008000-n Linux-2.6.14 -d zImage uImage
明显这个值应该是0x30008040
mkimage -A arm -O Linux -T kernel -C none -a 0x30008000-e 0x30008040-n Linux-2.6.14 -d zImage uImage
修正后发动信息如下
## Booting image at 30008000 …
Image Name:Linux-2.6.14
Created:2008-07-148:59:37 UTC
Image Type:ARM Linux Kernel Image (uncompressed)
Da
Load Address: 30008000
Entry Point:30008040
Verifying Checksum … OK
XIP Kernel Image … OK
commandline:noinitrd root=/dev/mtdblock3 init=/linuxrc console= ttySAC0,115200 mem=64M
Starting kernel …
Uncompressing Linux………………………………………………………….. done, booting the kernel.
2.Starting kernel …
Uncompressing Linux……………………………………………………
……… done, booting the kernel.
Error: unrecognized/unsupported machine ID (r1 = 0x000000c2).
Available machine support:
ID (hex)NAME
000000c1SMDK2410
Please check your kernel config and/or bootloader.
修正linux-2.6.14\arch\arm\kernel\head.S,如下,蓝色字体为增加内容
ENTRY(stext)
msrcpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
@ and irqs disabled
bl__lookup_processor_type@ r5=procinfo r9=cpuid
movsr10, r5@ invalid processor (r5=0)?
beq__error_p@ yes, error p
movr1, #0xc1@参阅linux-2.6.14\include\asm-arm\mach-types.h
bl__lookup_machine_type@ r5=machinfo
movsr8, r5@ invalid machine (r5=0)?
beq__error_a@ yes, error a
3.Starting kernel …
Uncompressing Linux………………………………………….
……… done, booting the kernel.
然后就中止了
检查commandline完全正确,从上面的打印信息能够看出,内核现已解压成功了,这样只能进入内核盯梢调试了
在内核中arch/arm/kernel/debug.S中存在一个debug函数叫做printascii,运用方法如下:
adr r0, str_p1
bl printascii
str_p1:.asciz”\nError: unrecognized/unsupported process type\n”
用printascii在arch/arm/kernel/head.S里盯梢调试,直到跳转到start_kernel都没有发现问题,查到printascii在进入start_kernel之后也能够运用,阐明如下:
mmu现已敞开后,体系中的物理地址都变成虚拟地址了,因而本来依据物理地址的调试计划将都会失利,但能够运用printascii持续调试,该调试功用一起支撑物理地址与虚拟地址,而且供给了一个解决计划便是将printascii参加到printk的vsprintf()之里。
修正linux-2.6.14\kernel\printk.c,蓝色字体为增加内容
extern void printascii(const char*);
asmlinkage int vprintk(const char *fmt, va_list args)
{
unsigned long flags;
int printed_len;
char *p;
static char printk_buf[1024];
static int log_level_unknown = 1;
preempt_disable();
if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
zap_locks();
spin_lock_irqsave(&logbuf_lock, flags);
printk_cpu = smp_processor_id();
/* Emit the output into the temporary buffer */
printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
printascii(printk_buf);
…
…
}
修正后内核发动成功,超级终端出来一大堆打印信息
## Booting image at 30008000 …
Image Name:Linux-2.6.14
Created:2008-07-148:59:37 UTC
Image Type:ARM Linux Kernel Image (uncompressed)
Da
Load Address: 30008000
Entry Point:30008040
Verifying Checksum … OK
XIP Kernel Image … OK
Starting kernel …
Uncompressing Linux………………………………………………………….. done, booting the kernel.
<5>Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #3 Mon Jul 14 04:59:17 EDT 2008
CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Da
CPU S3C2410A (id 0x32410002)
S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz
<6>S3C2410 Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
<7>On node 0 totalpages: 16384
<7>DMA zone: 16384 pages, LIFO batch:7
<7>Normal zone: 0 pages, LIFO batch:1
<7>HighMem zone: 0 pages, LIFO batch:1
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists
<5>Kernel command line: noinitrd root=/dev/mtdblock3 init=/linuxrcconsole= ttySAC0,115200 mem=64M
irq: clearing subpending status 00000003
PID hash table entries: 512 (order: 9, 8192 bytes)
timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4c
Console: colour dummy device 80×30
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
<6>Memory: 64MB = 64MB total
<5>Memory: 62592KB available (1708K co
<7>Calibrating delay loop… 101.17 BogoMIPS (lpj=252928)
Mount-cache hash table entries: 512
<6>CPU: Testing write buffer coherency: ok
softlockup thread 0 started up.
<6>NET: Registered protocol family 16
S3C2410: Initialising architecture
<6>usbcore: registered new driver usbfs
<6>usbcore: registered new driver hub
S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
<4>NetWinder Floating Point Emulator V0.97 (double precision)
Console: switching to colour frame buffer device 80×25
<6>fb0: Virtual frame buffer device, using 1024K of video memory
S3C2410 RTC, (c) 2004 Simtec Electronics
<6>s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410
<6>s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410
<6>s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410
<6>io scheduler noop registered
<6>io scheduler anticipatory registered
<6>io scheduler deadline registered
<6>io scheduler cfq registered
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
<6>s3c2410-nand: mapped registers at c4980000
<6>s3c2410-nand: timing: Tacls10ns, Twrph010ns, Twrph110ns
<4>No NAND device found!!!
<5>usbmon: debugfs is not available
<6>mice: PS/2 mouse device common for all mice
<6>NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
<6>TCP: Hash tables configured (established 4096 bind 4096)
<6>TCP reno registered
<6>TCP bic registered
<6>NET: Registered protocol family 1
<3>Root-NFS: No NFS server available, giving up.
<3>VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device “mtdblock3” or unknown-block(2,0)
Please append a correct “root=” boot option
<0>Kernel panic – not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
那么就阐明内核没有问题,而是commandline参数有问题,仔细看,才发现
noinitrd root=/dev/mtdblock3 init=/linuxrcconsole= ttySAC0,115200 mem=
64M
console=之后多了一个空格,可是不承认是否是这个原因,从头设置bootargs参数,去掉空格
setenv bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttyS
AC0,115200 mem=64M
从头下载,发动成功.
在网上查到有说u-boot和内核频率不共同或许导致串口没有打印信息,最好将u-boot的频率设为200M,不过我试过了,202.800 MHz也没有问题
Uncompressing Linux…………………………………………………… done, booting the kernel.
Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #3 Mon Jul 14 04:59:17 EDT 2008
CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Da
CPU S3C2410A (id 0x32410002)
S3C2410: core202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz
Starting kernel …
Uncompressing Linux…………………………………………………………. done, booting the kernel.
Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #20 Sat Jul 5 10:01:30 EDT 2008
CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Da
CPU S3C2410A (id 0x32410002)
S3C2410: core200.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
1.S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing: Tacls 10ns, Twrph0 10ns, Twrph1 10ns
No NAND device found!!!
usbmon: debugfs is not available
mice: PS/2 mouse device common for all mice
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
TCP bic registered
NET: Registered protocol family 1
Root-NFS: No NFS server available, giving up.
VFS: Unable to mount root fs via NFS, trying floppy.
VFS:Cannot open root device “mtdblock3” or unknown-block(2,0)
Please append a correct “root=” boot option
Kernel panic – not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
原因或许是一下几点:
(1)commandline中的root=/dev/mtdblock3表明rootfs在Flash的第4分区,检查承认rootfs是否是Flash的第4分区(第一个分区号为0)
(2)Flash的rootfs分区中没有下载好的根文件体系,承认是否下载好根文件体系
(3)Flash的驱动有问题,无法对Flash进行读写
我的NAND Flash分区如下:
mtdpart info. (5 partitions)
nameoffsetsizeflag
————————————————
vivi: 0x000000000x000200000128k
param: 0x000200000x00010000064k
kernel: 0x000300000x001c000001M+768k
rootfs: 0x002000000x02000000032M
user: 0x022000000x01e00000030M
所以commandline中的mtdblock3没有过错
我已下载好根文件体系至rootfs分区,再看看串口的打印信息,留意赤色的部分
No NAND device found!!!
有点古怪,其实我不太信任linux的源代码会有问题,就在根文件体系的加载这一步拖了好多天,一开端由于自己的忽略,make menuconfig时把有些选项选成模块了,也没有搞清楚<*>和
linux-2.6.14\drivers\mtd\nand\s3c2410.c中s3c2410_nand_init函数对NAND Flash初始化
static int __init s3c2410_nand_init(void)
{
printk(“S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n”);
driver_register(&s3c2440_nand_driver);
returndriver_register(&s3c2410_nand_driver);
}
static struct device_drivers3c2410_nand_driver= {
.name= “s3c2410-nand”,
.bus= &platform_bus_type,
.probe=s3c2410_nand_probe,
.remove= s3c2410_nand_remove,
};
static ints3c2410_nand_probe(struct device *dev)
{
returns3c24xx_nand_probe(dev, 0);
}
static ints3c24xx_nand_probe(struct device *dev, int is_s3c2440)
{
struct platform_device *pdev = to_platform_device(dev);
struct s3c2410_platform_nand *plat = to_nand_plat(dev);
struct s3c2410_nand_info *info;
struct s3c2410_nand_mtd *nmtd;
struct s3c2410_nand_set *sets;
struct resource *res;
. . .
for (setno = 0; setno < nr_sets; setno++, nmtd++) {
pr_debug(“initialising set %d (%p, info %p)\n”,
setno, nmtd, info);
s3c2410_nand_init_chip(info, nmtd, sets);
nmtd->scan_res =nand_scan(&nmtd->mtd,
(sets) ? sets->nr_chips : 1);
if (nmtd->scan_res == 0) {
s3c2410_nand_add_partition(info, nmtd, sets);
}
if (sets != NULL)
sets++;
}
. . .
}
通过串口打印出nmtd->scan_res的值为1,依据
if (nmtd->scan_res == 0) {
s3c2410_nand_add_partition(info, nmtd, sets);
}
来判别,应该回来0.
进入nand_scan
int nand_scan (struct mtd_info *mtd, int maxchips)
{
int i, nand_maf_id, nand_dev_id, busw, maf_id;
struct nand_chip *this = mtd->priv;
. . .
/* Select the device */
this->select_chip(mtd, 0);
/* Send the command for reading device ID */
this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
nand_maf_id= this->read_byte(mtd);
nand_dev_id= this->read_byte(mtd);
. . .
/* Print and store flash device information */
for (i = 0; nand_flash_ids[i].name != NULL; i++) {
if (nand_dev_id != nand_flash_ids[i].id)
continue;
if (!mtd->name) mtd->name = nand_flash_ids[i].name;
this->chipsize = nand_flash_ids[i].chipsize << 20;
. . .
/* Try to identify manufacturer */
for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
if (nand_manuf_ids[maf_id].id == nand_maf_id)
break;
}
. . .
printk (KERN_INFO “NAND device: Manufacturer ID:”
” 0x%02x, Chip ID: 0x%02x (%s %s)\n”, nand_maf_id, nand_dev_id,
nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
break;
}
if (!nand_flash_ids[i].name) {
printk (KERN_WARNING “No NAND device found!!!\n”);
this->select_chip(mtd, -1);
return 1;
}
. . .
}
依据上面的代码能够看出没有在nand_flash_ids数组中找到nand_dev_id匹配值,记住在u-boot中也有nand_probe函数检测NAND Flash,打印出2个ID值如下
NAND:Flash chip found:Manufacturer ID:0xEC, Chip ID:0x76
Linux中nand_flash_ids和nand_manuf_ids数组内容如下:
/*
*Chip ID list*
*Name. ID co
*/
struct nand_flash_dev nand_flash_ids[] = {
{“NAND 1MiB 5V 8-bit”,0x6e, 256, 1, 0x1000, 0},
{“NAND 2MiB 5V 8-bit”,0x64, 256, 2, 0x1000, 0},
{“NAND 4MiB 5V 8-bit”,0x6b, 512, 4, 0x2000, 0},
{“NAND 1MiB 3,3V 8-bit”,0xe8, 256, 1, 0x1000, 0},
{“NAND 1MiB 3,3V 8-bit”,0xec, 256, 1, 0x1000, 0},
{“NAND 2MiB 3,3V 8-bit”,0xea, 256, 2, 0x1000, 0},
{“NAND 4MiB 3,3V 8-bit”,0xd5, 512, 4, 0x2000, 0},
{“NAND 4MiB 3,3V 8-bit”,0xe3, 512, 4, 0x2000, 0},
{“NAND 4MiB 3,3V 8-bit”,0xe5, 512, 4, 0x2000, 0},
. . .
{“NAND 64MiB 3,3V 8-bit”,0x76, 512, 64, 0x4000, 0},
. . .
{NULL,}
};
/*
*Manufacturer ID list
*/
struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_TOSHIBA, “Toshiba”},
{NAND_MFR_SAMSUNG, “Samsung”},
{NAND_MFR_FUJITSU, “Fujitsu”},
{NAND_MFR_NATIONAL, “National”},
{NAND_MFR_RENESAS, “Renesas”},
{NAND_MFR_STMICRO, “ST Micro”},
{NAND_MFR_HYNIX, “Hynix”},
{0x0, “Unknown”}
};
/*
* NAND Flash Manufacturer ID Codes
*/
#define NAND_MFR_TOSHIBA0x98
#defineNAND_MFR_SAMSUNG0xec
#define NAND_MFR_FUJITSU0x04
#define NAND_MFR_NATIONAL0x8f
#define NAND_MFR_RENESAS0x07
#define NAND_MFR_STMICRO0x20
#define NAND_MFR_HYNIX0xad
这样就阐明nand_scan中读取NAND Flash的id值是过错的,不是0xec和0x76,从串口打印出来的id值的确不正确,首要我的NAND Flash必定正常作业,在u-boot中一直是好的,那么或许是Linux中对Flash读写的出问题了,怀疑是宣布指令后的延时有问题,向NAND Flash宣布读取id指令后的延时太短,导致读出来的值过错,nand_wait_ready这个便是延时等候指令履行完结的函数,通过测验没有问题,到这个时分,真有点溃散了.然后估量是NAND Flash的NFCONF寄存器设置有问题, NFCONF寄存器在函数s3c2410_nand_inithw中初始化,s3c2410_nand_inithw中将NFCONF寄存器的值打印出来,如下:
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing:Tacls10ns, Twrph010ns, Twrph110ns
s3c2410-nand: NF_CONF is0x8000
与u-boot中设置的NFCONF寄存器值比较发现,不同的是TACLS TWRPH0 TWRPH1以及是否初始化ECC,nFCE的值
U-boot中TACLS TWRPH0 TWRPH1值分别为0 4 2,初始化ECC, nFCE=1(inactive)
Linux中TACLS TWRPH0 TWRPH1值分别为0 0 0,未初始化ECC, nFCE=0(active)
应该是TACLS TWRPH0 TWRPH1的问题,检查S3C2410 user manual和NAND Flash用户手册Samsung K9F1208U0M user manual,找到三张图,如下:
图1 s3c2410 user manual, nand flash memory timing
明显s3c2410 user manual推荐值是TACLS=0 TWRPH0=1 TWRPH1=0
TACLS:1个HCLK TWRPH0:2个HCLK TWRPH1:1个HCLK
内核的频率为200MHZ,即FCLK=200MHZ,则HCLK=100MHZ(周期为10ns),所以
TACLS:10ns TWRPH0:20ns TWRPH1:10ns
图2 NAND Flash(K9F1208U0M) user manual,Read and Write timing
tCLS等价于图1中的TACLS;tWP等价于图1中的TWRPH0;tCLH等价于图1中的TWRPH1
图3 NAND Flash(K9F1208U0M) user manual
结合前3张图,能够看出对NAND Flash(K9F1208U0M)进行读写的次序要求为:
TACLS <----------->tCLS,最小值为0ns
TWRPH0<----------->tWP,最小值为25ns
TWRPH1<----------->tCLH,最小值为10ns
内核的频率为200MHZ,即FCLK=200MHZ,则HCLK=100MHZ(周期为10ns)
TACLS=0,TWRPH0=2,TWRPH1=0即可满意时序要求,此刻
TACLS:10nsTWRPH0:30nsTWRPH1:10ns
现在再看看从前串口输出的信息:
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing:Tacls 10ns, Twrph0 10ns, Twrph1 10ns
No NAND device found!!!
很明显Twrph0 10ns <25ns,本来如此!!!!
不过我试了一下TACLS=0,TWRPH0=1,TWRPH1=0, TACLS:10nsTWRPH0:20nsTWRPH1:10ns,NAND Flash照样正常作业.不知道为什么.
现在要阐明一下我是怎么修正的, TACLSTWRPH0TWRPH1的值在linux-2.6.14\arch\arm\mach-s3c2410\devs.c中现已设置,代码如下:
struct s3c2410_platform_nandsuperlpplatform={
tacls:0,
twrph0:3,
twrph1:0,
sets:&nandset,
nr_sets:1,
};
这儿设置的值和上面的剖析是共同的,应该没有问题,可是为什么打印出来的却是
s3c2410-nand: timing:Tacls 10ns, Twrph0 10ns, Twrph1 10ns
s3c2410_nand_inithw函数对NFCONF寄存器初始化,代码如下:
static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
struct device *dev)
{
struct s3c2410_platform_nand *plat = to_nand_plat(dev);
unsigned int tacls, twrph0, twrph1;
unsigned long clkrate = clk_get_rate(info->clk);
unsigned long cfg;
/* calculate the timing information for the controller */
if (plat != NULL) {
tacls= s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
printk(“plat->tacls:%d\n”,plat->tacls);
printk(“plat->twrph0:%d\n”,plat->twrph0);
printk(“plat->twrph1:%d\n”,plat->twrph1);
printk(“tacls:%d\n”,tacls);
printk(“twrph0:%d\n”,twrph0);
printk(“twrph1:%d\n”,twrph1);
printk(“clkrate:%d\n”,clkrate);
tacls=1;
twrph0 =2;
twrph1 =1;
} else {
/* default timings */
tacls = 4;
twrph0 = 8;
twrph1 = 8;
}
if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
printk(KERN_ERR PFX “cannot get timings suitable for board\n”);
return -EINVAL;
}
printk(KERN_INFO PFX “timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n”,
to_ns(tacls, clkrate),
to_ns(twrph0, clkrate),
to_ns(twrph1, clkrate));
if (!info->is_s3c2440) {
cfg= S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls-1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
} else {
cfg= S3C2440_NFCONF_TACLS(tacls-1);
cfg|= S3C2440_NFCONF_TWRPH0(twrph0-1);
cfg|= S3C2440_NFCONF_TWRPH1(twrph1-1);
}
pr_debug(PFX “NF_CONF is 0x%lx\n”, cfg);
writel(cfg, info->regs + S3C2410_NFCONF);
return 0;
}
我加了一点代码将相关参数打印出来:
plat->tacls:0
plat->twrph0:3
plat->twrph1:0
tacls:1
twrph0:1
twrph1:1
clkrate:100000000
真是搞不懂plat->tacls, plat->twrph0, plat->twrph1的值和前面初始化的值是相同的,可是通过s3c2410_nand_calc_rate函数处理后就出问题了,正确的输出值应该是
tacls:1twrph0:4twrph1:1
算了,对tacls,twrph0,twrph1三个变量强制性赋值
tacls=1;
twrph0 =2;
twrph1 =1;
修正后NAND Flash能够正常作业了,发动信息如下:
Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #7 Mon Jul 14 09:34:58 EDT 2008
CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Da
CPU S3C2410A (id 0x32410002)
S3C2410: core 200.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
S3C2410 Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists
Kernel command line: noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 mem=64M
irq: clearing subpending status 00000003
irq: clearing subpending status 00000002
PID hash table entries: 512 (order: 9, 8192 bytes)
timer tcon=00500000, tcnt a2c1, tcfg 00000200,00000000, usec 00001eb8
Console: colour dummy device 80×30
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 64MB = 64MB total
Memory: 62592KB available (1708K co
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
softlockup thread 0 started up.
NET: Registered protocol family 16
S3C2410: Initialising architecture
usbcore: registered new driver usbfs
usbcore: registered new driver hub
S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
NetWinder Floating Point Emulator V0.97 (double precision)
Console: switching to colour frame buffer device 80×25
fb0: Virtual frame buffer device, using 1024K of video memory
S3C2410 RTC, (c) 2004 Simtec Electronics
s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410
s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410
s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing: Tacls 10ns, Twrph0 20ns, Twrph1 10ns
s3c2410-nand: NF_CONF is 0x8010
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
NAND_ECC_NONE selected by board driver. This is not recommended !!
Scanning device for bad blocks
Creating 5 MTD partitions on “NAND 64MiB 3,3V 8-bit”:
0x00000000-0x00020000 : “bootloader”
0x00020000-0x00030000 : “param”
0x00030000-0x001f0000 : “kernel”
0x00200000-0x02200000 : “rootfs”
0x02200000-0x04000000 : “user”
usbmon: debugfs is not available
mice: PS/2 mouse device common for all mice
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
TCP bic registered
NET: Registered protocol family 1
Reading da
VFS: Mounted root (cramfs filesystem) readonly.
Freeing init memory: 92K
Warning: unable to open an initial console.
Reading da
sd_mod: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4
usb_storage: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4
usbvideo: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4
ov511: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4