您的位置 首页 分销

TE2410移植linux-2.6.14及调试进程总结(1)

1.修改Makefile#cdlinux-2.6.14#viMakefile修改内容如下ARCH=armCROSS_COMPILE=arm-linux-下载交叉编译器arm-linux-gcc3.4.

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_data =&superlpplatform

}

};

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 , especially

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 only provided for

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 onto /dev

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 code will generate

debugging messages. See the file

for more

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_DATA_PTR;

ulong len = 0, checksum;

ulong initrd_start, initrd_end;

ulong data;

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 Data Size*/

uint32_tih_load;/* DataLoadAddress*/

uint32_tih_ep;/* Entry Point Address*/

uint32_tih_dcrc;/* Image Data CRC Checksum*/

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)

Data Size:1028136 Bytes = 1004 kB

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)

Data Size:1028136 Bytes = 1004 kB

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, Data cache writeback

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 code, 381K data, 92K init)

<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, Data cache writeback

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, Data cache writeback

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时把有些选项选成模块了,也没有搞清楚<*>和的不同,串口打印信息也是到这一步,可是没有No NAND device found!!!提示,由于NAND Flash的驱动没有编译进内核.后来才发现make menuconfig装备时出了问题,修正后,发现是NAND Flash驱动有问题,进入内核盯梢发现

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 code, pagesize, chipsize in MegaByte, eraseblock size,

*/

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, Data cache writeback

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 code, 381K data, 92K init)

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 data from NAND FLASH without ECC is not recommended

VFS: Mounted root (cramfs filesystem) readonly.

Freeing init memory: 92K

Warning: unable to open an initial console.

Reading data from NAND FLASH without ECC is not recommended

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

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/fenxiao/275734.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部