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

发布者:Haifeeng最新更新时间:2016-07-20 来源: eefocus关键字:TE2410  移植  linux-2.6.14  调试过程 手机看文章 扫描二维码
随时随地手机看文章
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分区

struct  s3c2410_nand_set  nandset={

       nr_partitions:4,//5,

       partitions:partition_info,

};

nr_partitions: 指明partition_info中定义的分区数目
partitions: 分区信息表

 

(4)建立Nand Flash芯片支持

struct s3c2410_platform_nand  superlpplatform={

       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/mtdblock3 init=/linuxrc console=ttySAC0,115200 mem=64M

或者

noinitrd root=/dev/mtdblock/3 init=/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_t   ih_magic;  /* Image Header Magic Number    */

    uint32_t   ih_hcrc;   /* Image Header CRC Checksum    */

    uint32_t   ih_time;   /* Image Creation Timestamp */

    uint32_t   ih_size;   /* Image Data Size       */

    uint32_t   ih_load;   /* Data    Load  Address    */

    uint32_t   ih_ep;     /* Entry Point Address      */

    uint32_t   ih_dcrc;   /* Image Data CRC Checksum  */

    uint8_t       ih_os;     /* Operating System      */

    uint8_t       ih_arch;   /* CPU architecture      */

    uint8_t       ih_type;   /* Image Type        */

    uint8_t       ih_comp;   /* Compression Type      */

    uint8_t       ih_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-14   8: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

000000c1        SMDK2410

Please check your kernel config and/or bootloader.

修改linux-2.6.14\arch\arm\kernel\head.S,如下,蓝色字体为添加内容

ENTRY(stext)

    msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode

                     @ and irqs disabled

    bl  __lookup_processor_type     @ r5=procinfo r9=cpuid

    movs   r10, r5              @ invalid processor (r5=0)?

    beq __error_p            @ yes, error 'p'

 

    mov r1, #0xc1     @ 参考linux-2.6.14\include\asm-arm\ mach-types.h

 

    bl  __lookup_machine_type       @ r5=machinfo

    movs   r8, 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-14   8: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=/linuxrc console= 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 80x30

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 80x25

<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: Tacls 10ns, Twrph0 10ns, Twrph1 10ns

<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=/linuxrc console= 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: core 202.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: core 200.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)

name              offset        size        flag

------------------------------------------------

vivi            : 0x00000000    0x00020000     0  128k

param           : 0x00020000    0x00010000     0   64k

kernel          : 0x00030000    0x001c0000     0    1M+768k

rootfs          : 0x00200000    0x02000000     0   32M

user            : 0x02200000    0x01e00000     0   30M

所以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);

    return driver_register(&s3c2410_nand_driver);

}

 

static struct device_driver s3c2410_nand_driver = {

    .name      = "s3c2410-nand",

    .bus       = &platform_bus_type,

    .probe     = s3c2410_nand_probe,

    .remove       = s3c2410_nand_remove,

};

static int s3c2410_nand_probe(struct device *dev)

{

    return s3c24xx_nand_probe(dev, 0);

}

 

static int s3c24xx_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_TOSHIBA     0x98

#define NAND_MFR_SAMSUNG     0xec

#define NAND_MFR_FUJITSU     0x04

#define NAND_MFR_NATIONAL   0x8f

#define NAND_MFR_RENESAS     0x07

#define NAND_MFR_STMICRO     0x20

#define NAND_MFR_HYNIX       0xad

 

这样就说明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: Tacls 10ns, Twrph0 10ns, Twrph1 10ns

s3c2410-nand: NF_CONF is 0x8000

与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,找到三张图,如下:

TE2410移植linux-2.6.14 - 东海 - 东海的博客

图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

TE2410移植linux-2.6.14 - 东海 - 东海的博客

图2 NAND Flash(K9F1208U0M) user manual,Read and Write timing

tCLS等价于图1中的TACLS;tWP等价于图1中的TWRPH0;tCLH等价于图1中的TWRPH1

TE2410移植linux-2.6.14 - 东海 - 东海的博客

   图3 NAND Flash(K9F1208U0M) user manual

TE2410移植linux-2.6.14 - 东海 - 东海的博客

 

结合前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:10ns TWRPH0:30ns TWRPH1: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:10ns TWRPH0:20ns TWRPH1:10ns,NAND Flash照样正常工作.不知道为什么.

现在要说明一下我是如何修改的, TACLS TWRPH0 TWRPH1 的值在linux-2.6.14\arch\arm\mach-s3c2410\devs.c中已经设置,代码如下:

 

struct s3c2410_platform_nand  superlpplatform={

       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:1   twrph0:4  twrph1: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 80x30

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 80x25

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'

关键字:TE2410  移植  linux-2.6.14  调试过程 引用地址:TE2410移植linux-2.6.14及调试过程总结(1)

上一篇:TE2410移植linux-2.6.14及调试过程总结(2)
下一篇:引用 ADS1.2下ARM映像文件

推荐阅读最新更新时间:2024-03-16 15:01

μC/OS-III在Cortex-M3处理器上的移植
引言 μC/OS-III是一款基于优先级调度的抢占式实时内核,Micrium公司于2011年8月公开了μC/OS-III的源码,其源码遵循ANSIC标准,因而具有良好的移植性,相信其将会被移植到越来越多的处理器体系上。本文主要完成基于Cortex-M3处理器的μC/OS-III移植,通过本次移植,加深对嵌入式操作系统原理的理解。此外,在μC/OS-III移植成功的基础上进行嵌入式应用程序开发,可以把主要精力集中到应用程序上,而硬件资源交由μC/OS-III管理,从而使得嵌入式应用程序更易开发和维护,在嵌入式软硬件结构变得越来越复杂的今天具有现实意义。 1 μC/OS-III和Cortex-M3特点 相对以前的版本,μC/O
[单片机]
μC/OS-III在Cortex-M3处理器上的<font color='red'>移植</font>
移植RT-Thread到STM32开发板的详细步骤例程
本章开始,先新建一个基于野火STM32全系列(包含M3/4/7)开发板的的RT-Thread的工程模板,让RT-Thread先跑起来。以后所有的RT- Thread相关的例程我们都在此模板上修改和添加代码,不用再反反复复地新建。 获取STM32的裸机工程模板 STM32的裸机工程模板我们直接使用野火STM32开发板配套的固件库例程即可。这里我们选取比较简单的例 程—“GPIO输出—使用固件库点亮LED”作为裸机工程模板。该裸机工程模板均可以在对应板子的A盘/程序源码 /固件库例程的目录下获取到,下面以野火F103-霸道板子的光盘目录为例,具体见图 STM32裸机工程模板在光盘资料中的位置。 2. 下载RT-Threa
[单片机]
<font color='red'>移植</font>RT-Thread到STM32开发板的详细步骤例程
基于ARM的嵌入式Linux移植真实体验(4)――设备驱动
设备驱动程序是操作系统内核和机器硬件之间的接口,它为应用程序屏蔽硬件的细节,一般来说,Linux的设备驱动程序需要完成如下功能: 设备初始化、释放; 提供各类设备服务; 负责内核和设备之间的数据交换; 检测和处理设备工作过程中出现的错误。 Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合,通过这些函数使得Linux的设备操作犹如文件一般。在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作,如open ()、close ()、read ()、write () 等。 Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发送和接收数据以字符的形式进行;而
[单片机]
基于ARM的嵌入式Linux<font color='red'>移植</font>真实体验(4)――设备驱动
Exynos4412 Uboot 移植(六)—— 相关知识补充
Uboot版本:u-boot-2013.01 一、gd结构体的定义与使用 gd_t 和 bd_t 是u-boot中两个重要的数据结构,在初始化操作很多都要靠这两个数据结构来保存或传递。 gd_t 定义在/u-boot-2013.01/arch/arm/include/asm/global_data.h bd_t 定义在 ./include/asm-arm/u-boot.h 1、gd_t : global data数据结构定义 位于文件/u-boot-2013.01/arch/arm/include/asm/global_data.h 中。其成员主要是一些全局的系统初始化参数。 当使用gd_t 时需用宏定
[单片机]
[Linux 底层]bootstrap移植裁剪及编译
bootstrap文件夹内容如下图: 在board/sama5d3_xplained目录下,有官方的默认配置文件 sama5d3_xplainednf_linux_uimage_dt_defconfig 从nandflash启动直接跳转到uimage类型内核阶段 sama5d3_xplainednf_linux_zimage_dt_defconfig 从nandflash启动直接跳转到zimage类型内核阶段 sama5d3_xplainednf_uboot_defconfig 从nandflash启动直接跳转到uboot阶段 sama5d3_xplainedsd_linux_uimage_dt_defconfig 从SD
[单片机]
[Linux 底层]bootstrap<font color='red'>移植</font>裁剪及编译
将μC/OS-II移植到AndesCore™ N1033A-S处理器
μC/OS-II是一种代码公开、可裁剪的嵌入式实时多任务操作系统。该内核通过实现抢占式任务调度算法和多任务间通信等功能,使之具有执行效率高、实时性能优良等特点。另外,其占用空间非常小(最小可裁剪至2KB)并且具有高度可移植性,因此被广泛的应用于微处理器和微控制器上。 晶心科技 (Andes)作为亚洲首家原创性32位微处理器IP与系统芯片平台设计公司,推出的AndesCore™ N10系列产品N1033A-S, 搭配应用广泛的嵌入式实时操作系统μC/OS-II以及相关的软硬件开发资源,有效的帮助客户降低现有成本、提升系统效能、减少系统功耗,并缩短产品开发上市时程。本文将介绍如何将μC/OS-II移植到AndesCore™ N
[单片机]
将μC/OS-II<font color='red'>移植</font>到AndesCore™ N1033A-S处理器
Linux2.6内核2410平台上的移植
一、准备必要的文件 1.首先去官方网站下载最新的llinux内核 http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.14.tar.bz2 2.因为linux2.6.14内核需要更新版本的编译器,所以需要下载交叉编译器 ftp://ftp.handhelds.org/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2 二、安装文件 1、把gcc解压到/usr/local/arm/3.4.1目录下 2、接下来需要解压linux内核,输入命令: # tar -jxvf linux-2.6.14.tar.bz2 将内核解压
[单片机]
恩智浦重新设计LPC2000 移植微软.NET Micro Framework
恩智浦重新设计LPC2000微控制器系列,为开发者提供便利 荷兰埃因霍芬,2007年9月19日—— 恩智浦半导体(NXP Semiconductors)(由飞利浦创建的独立半导体公司)和微软Windows 嵌入式金牌合作伙伴Adeneo公司今天共同宣布:微软 .NET Micro Framework已被移植,以支持恩智浦广受欢迎的基于ARM7 处理器的LPC2000微控制器系列和基于ARM9 处理器的LPC3180微控制器。 由此,嵌入式开发者在设计基于恩智浦LPC2000和LPC3000系列微控制器的解决方案时,将能够利用微软 .NET和Visual Studio 工具的优点,加速其针对小尺寸、低功耗设备应用的开发。同样地
[焦点新闻]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved