Chinaunix首页 | 论坛 | 博客
  • 博客访问: 115093
  • 博文数量: 23
  • 博客积分: 2092
  • 博客等级: 大尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-10 19:40
文章分类
文章存档

2011年(3)

2010年(17)

2009年(3)

我的朋友

分类: 嵌入式

2010-04-06 10:42:46

开发环境:丰宝LPC2478板子

编译工具:arm-linux-tools-20061213.tar.gz

内核源码:uClinux-dist-20080904-lpc2468.tar.bz2 2.6.21内核)

NORFLASH  AM29LV160DB 16 CFI 接口 但是我不明白linux 驱动为什么在jedec_probe.c中定义,而没有在cfi_probe.c中定义。移植的时候要把这个配置选项选上。还有就是uClinux-dist-20080904-lpc2468.tar.bz2所带的jedec_probe.c编译的时候会有莫名的错误,我只好用linux2.6.29内核的jedec_probe.c去替换。

driver/mtd/maps目录下 kconfig加上

config MTD_ARM_LPC2468NOR

      tristate "Nor Flash device mapped on ARM NXP LPC2468"

      depends on ARM  && MTD

makefile中加上

obj-$(CONFIG_MTD_ARM_LPC2468NOR)+= lpc2468nor.o

 

 

现在的NorFlash大多支持CFI或者JEDEC这样的规范,根据这些规范可以自动检测出芯片的一些参数并进行读写,所以uClinux将这些规范的驱动实现单独放在mtd/chips目录下。也就是说这个目录下放的是芯片的通用驱动代码,这些代码本身是不会主动去检测芯片的存在的,它仅仅是注册了一个驱动供其它模块调用。

在通用规范的基础上,每个不同的厂商有不同的实现,且芯片在不同的系统中可能有不同的参数,如基地址,位宽等。uClinux将这部分独立出来放在mtd/maps下。这个目录下的代码将根据芯片实现的不同规范调用相应的chips驱动。因此chips下的模块必须先于maps下的模块初始化。我们主要做的工作是在map目录下填写map_info结构体,并作相应的初始化。


//driver/mtd/maps/lpc2468nor.c


#include <linux/module.h>

#include <linux/types.h>

#include <linux/kernel.h>

#include <asm/io.h>

#include <linux/mtd/mtd.h>

#include <linux/mtd/map.h>

#include <linux/mtd/partitions.h>


 
                         


#define WINDOW_SIZE 0X200000 //2MB

#define WINDOW_ADDR 0X80000000 // 基地址

#define BUSWIDTH 2 //16/8


#define PROBETYPES {"cfi_probe",NULL} //探测接口类型

#define MSG_PREFIX "LPC2468-NOR:" //printk前缀

#define MTDID "lpc2468-nor:" //MTD驱动



struct map_info lpc2468nor_map =
{

    .name = "lpc2468nor_flash",
    .size = WINDOW_SIZE,
    .bankwidth = BUSWIDTH,
    .phys = WINDOW_ADDR
};

#ifdef CONFIG_MTD_PARTITIONS

static struct mtd_partition static_partitions[]=
{

    {

        .name = "kernel",
        .offset = 0,
        .size = 0x100000
    },

    {

        .name = "rootfs",
        .offset = 0x100000,
        .size = 0x100000
    },


};

#endif

#define NUM_PARTITIONS ARRAY_SIZE(lpc2468nor_partitions)


static struct mtd_info *mymtd;

static int mtd_parts_nb = 0;
static struct mtd_partition *mtd_parts = 0;

 

norflash驱动模块的初始化代码为(带一些自己加上去的调试信息)

static int __init init_lpc2468nor_map(void)
{

    //int rc = 0;

       static const char *rom_probe_types[] = PROBETYPES;
        const char **type;
        const char *part_type = 0;
   printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x \n",WINDOW_SIZE,WINDOW_ADDR);
// 将物理地址映射到linux的内核空间

        lpc2468nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
         printk(" ioremap_nocache 2\n");

        if(!lpc2468nor_map.virt)

        {
            
            printk(MSG_PREFIX "Failed to ioremap_nocache\n");
            //rc = - EIO;

            //goto err2;

        }
// 填充read, write, copy_from, copy_to几个函数指针为默认值。

   printk("simple_map_init \n");
        simple_map_init(&lpc2468nor_map);
   printk("simple_map_init OK \n");

        mymtd = 0;
        type =rom_probe_types;
        for(; !mymtd && *type ; type++)

        {

        
        printk("DO do_map_probe \n");

/* do_map_probe这个函数位于drivers/mtd/chips/chipreg.c,用于查找指定名称的chip_driver,并调用它完成芯片的检测。*/

        mymtd = do_map_probe(*type, &lpc2468nor_map);
    
    
   printk("DO do_map_probe OK\n");
        }

        if(mymtd)
        {
     // printk("goto err1\n");

        //rc = - ENXIO;

        //goto err1;

       mymtd->owner = THIS_MODULE;

        // printk("parse_mtd_partitions\n");

        
            //mtd_parts_nb = parse_mtd_partitions(mymtd , NULL, &mtd_parts, MTDID);//探测分区信息 运行的时候出错 之前没有分区 因此直接注释掉


        // if(mtd_parts_nb >0 )

            // part_type = "detected";

            
        // if(mtd_parts_nb == 0) //未探测到使用数组定义的分区信息

        // {

            printk("static_partitions\n");
                mtd_parts = static_partitions;
                mtd_parts_nb = ARRAY_SIZE(static_partitions);
                part_type = "static";

        // }



      printk("add_mtd_device\n");
        add_mtd_device(mymtd);
        printk("add_mtd_device OK \n");
        
        if(mtd_parts_nb == 0)
            printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");

        else

        {
        printk(KERN_NOTICE MSG_PREFIX "using %s partition definition\n",part_type);

        add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
        printk("add_mtd_partitions OK\n");
        }

            return 0;

        }


    iounmap((void *)lpc2468nor_map.virt);


    return - ENXIO;

}

static void __exit cleanup_lpc2468nor_map(void)

{

    if(mymtd)
        {
        
        del_mtd_partitions(mymtd);
        del_mtd_device(mymtd);
        map_destroy(mymtd);

        }

    if(lpc2468nor_map.virt)
        {

        iounmap((void *)lpc2468nor_map.virt);
        lpc2468nor_map.virt = NULL ;
        }
}




module_init(init_lpc2468nor_map);

module_exit(cleanup_lpc2468nor_map);


 

/****************************************************************************/

MODULE_LICENSE("GPL");

MODULE_AUTHOR("xiaotan luo");

MODULE_DESCRIPTION("Map driver for lpc2468 nor falsh board");

/****************************************************************************/


配置选项:

 

 

#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_UCBOOTSTRAP_PARTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_AFS_PARTS=y

#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_GEOMETRY is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_OTP is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=y
# CONFIG_MTD_EPCS is not set
CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set

#
# Mapping drivers for chip access
#
CONFIG_MTD_ARM_LPC2468NOR=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_SNAPARM is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
# CONFIG_MTD_UCLINUX is not set
# CONFIG_MTD_SNAPGEARuC is not set
# CONFIG_MTD_M520x is not set
# CONFIG_MTD_PLATRAM is not set
# CONFIG_MTD_AVNET5282 is not set

#
# Self-contained MTD device drivers
#
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_MTDRAM=y
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTDRAM_ABS_POS=0
CONFIG_MTD_BLOCK2MTD=y



 

 启动信息:

 


## Booting image at a1000000 ...
   Image Name:   linux 2.6.21-piaozhiye
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    561361 Bytes = 548.2 kB
   Load Address: a0008000
   Entry Point:  a0008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

Linux version 2.6.21-uc0 () (gcc version 3.4.4) #6 Sun Apr 4 15:49:11 CST 2010
CPU: NXP-LPC2468 [24680000] revision 0 (ARMvundefined 13), cr=a0123a40
Machine: LPC22xx, PHILIPS ELECTRONICS Co., Ltd.
Built 1 zonelists.  Total pages: 8128
Kernel command line: root=/dev/ram initrd=0xA1800000,4096K console=ttyS0,38400N8
PID hash table entries: 128 (order: 7, 512 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 27148KB available (1012K code, 145K data, 72K init)
Mount-cache hash table entries: 512
checking if image is initramfs...it isn't (bad gzip magic numbers); looks like an initrd
Freeing initrd memory: 4096K
NetWinder Floating Point Emulator V0.97 (double precision)
JFFS2 version 2.2. (NAND) (C) 2001-2006 Red Hat, Inc.
io scheduler noop registered (default)
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0xe000c000 (irq = 6) is a 16550A
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: loaded (max 8 devices)
LPC2468-NOR:0x00200000 at 0x80000000
 ioremap_nocache 2
simple_map_init
simple_map_init  OK
DO do_map_probe
lpc2468nor_flash: Found 1 x16 devices at 0x0 in 16-bit bank
 Amd/Fujitsu Extended Query Table at 0x0040
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
DO do_map_probe  OK
static_partitions
add_mtd_device
mtd: Giving out device 0 to lpc2468nor_flash
add_mtd_device OK 
LPC2468-NOR:using static partition definition
Creating 2 MTD partitions on "lpc2468nor_flash":
0x00000000-0x00100000 : "kernel"
mtd: Giving out device 1 to kernel
0x00100000-0x00200000 : "rootfs"
mtd: Giving out device 2 to rootfs
add_mtd_partitions  OK
slram: not enough parameters.
mtd: Giving out device 3 to mtdram test device
block2mtd: version $Revision: 1.30 $
RAMDISK: Couldn't find valid RAM disk image starting at 0.
No filesystem could mount root, tried:  ext2 cramfs jffs2 romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

参考资料:

(1)linux设备驱动开发详解

 (2)http://blog.csdn.net/lights_joy/archive/2008/02/24/2117100.aspx

(3)


 

阅读(2805) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~