开发环境:丰宝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) |