RM9200中flash文件系统的移植

来源:互联网 发布:小米平板2windows评测 编辑:程序博客网 时间:2024/05/01 21:32

flash文件系统在嵌入式linux系统中是必须的,无论是作为只读的根文件系统还是作为可写的用户文件系统。目前在linux-2.6.14内核上 移植flash文件系统。下载相应内核,打好at91rm9200的补丁后,却发现先前移植nand文件系统的方法在flash文件系统中完全不行。只好从头开始了。    星光AT91RM9200开发板的flash芯片是SST39VF3201,16 位 ,4M 。按目前计划,准备分区为三个区,分别为uboot(0x40000), kernel(0x1c0000), rootfs(0x200000), 应该可以将linux的最小系统跑起来的。    首先,添加MTD分区的底层驱动文件,在drivers/mtd/maps下添加at91rm9200.c文件,该文件是flash分区的基本驱动文件,包含分区信息、芯片识别等基本flash文件系统的底层实现。事实上,该文件并不需要从头开始创建,可以参考该目录下其它文件来修改,如edb7312.c。代码如下

#define WINDOW_ADDR 0x10000000      /* physical properties of flash */#define WINDOW_SIZE 0x400000#define BUSWIDTH    2#define MSG_PREFIX "RM9200-NOR:"   /* prefix for our printk()'s */#define MTDID      "rm9200-nor"    /* for mtdparts= partitioning */static struct mtd_info *mymtd;struct map_info rm9200nor_map = {        .name = "NOR flash on rm9200",        .size = WINDOW_SIZE,        .bankwidth = BUSWIDTH,        .phys = WINDOW_ADDR,};#ifdef CONFIG_MTD_PARTITIONS/** MTD partitioning stuff */static struct mtd_partition rm9200_partitions[3] ={        {        /* uboot 256K */                .name = "uboot",                .size = 0x40000,                .offset = 0                /*.mask_flags = MTD_WRITEABLES*/        },        {        /* kernel 1.768M */                .name = "kernel",                .size = 0x1C0000,                .offset = 0x40000                /*.mask_flags = MTD_WRITEABLES*/        },        {        /* rootfs 2M */                .name = "rootfs",                .size = 0x200000,                .offset = 0x200000        },};//static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };static const char *probes[] = { NULL };#endifstatic int                   mtd_parts_nb = 0;static struct mtd_partition *mtd_parts    = 0;int __init init_rm9200nor(void){        const char *part_type = 0;   printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x/n",                WINDOW_SIZE, WINDOW_ADDR);        rm9200nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);        if (!rm9200nor_map.virt) {                printk(MSG_PREFIX "failed to ioremap/n");                return -EIO;        }                simple_map_init(&rm9200nor_map);        mymtd = do_map_probe("jedec_probe", &rm9200nor_map);        if(!mymtd)                mymtd = do_map_probe("cfi_probe", &rm9200nor_map);                if (mymtd) {                mymtd->owner = THIS_MODULE;#ifdef CONFIG_MTD_PARTITIONS                mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);                if (mtd_parts_nb > 0)                  part_type = "detected";                if (mtd_parts_nb == 0)                {                        mtd_parts = rm9200_partitions;        /* static_partitions */                        mtd_parts_nb = ARRAY_SIZE(rm9200_partitions); /* static_partitions */                        part_type = "static";                }#endif                add_mtd_device(mymtd);                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);                }                return 0;        }        iounmap((void *)rm9200nor_map.virt);        return -ENXIO;}static void __exit cleanup_rm9200nor(void){        if (mymtd) {                del_mtd_device(mymtd);                map_destroy(mymtd);        }        if (rm9200nor_map.virt) {                iounmap((void *)rm9200nor_map.virt);                rm9200nor_map.virt = 0;        }}module_init(init_rm9200nor);module_exit(cleanup_rm9200nor);

代码比较好理解,因为大部分并不需要自己写,只是照搬过来。

 

下一步就是要写flash芯片的驱动了。flash为SST39VF3201,查芯片手册,明确其接口形式(先前写上面代码时,用的是CFI接口,只用了do_map_probe("cfi_probe", &rm9200nor_map);
结果死活找不到芯片。后来在cfi_probe.c中根本找不到芯片,当然不能通过了,查手册后才知道自己犯了一个原则性错误)。
在drivers/mtd/chips/jedec_probe.c中找到以下语句
{
               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
               .dev_id         = SST39LF160,
               .name           = "SST 39LF160",
               .uaddr          = {
                       [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
                       [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
               },
               .DevSize        = SIZE_2MiB,
               .CmdSet         = P_ID_AMD_STD,
               .NumEraseRegions= 2,
               .regions        = {
                       ERASEINFO(0x1000,256),
                       ERASEINFO(0x1000,256)
               }
        },
这是SST39LF1601的代码,依照这个代码,编写SST39VF3201的jedec_table项:
{
               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
               .dev_id         = SST39VF3201,
               .name           = "SST 39VF3201",
               .uaddr          = {
                       [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
                       [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
               },
               .DevSize        = SIZE_4MiB,
               .CmdSet         = P_ID_AMD_STD,
               .NumEraseRegions= 2,
               .regions        = {
                       ERASEINFO(0x1000,1024)    
               }
        },
在文件开头的宏定义中增加flash的芯片ID号:
#define SST39VF3201        0x235b
基本完成芯片级驱动代码编写,下面就是linux内核的配置了,要将我们的修改增加到内核中去。这一步对了解linux内核配置的来讲比较简单,在此略过。
配置内核:
    在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                │ │
  │ │ 
Flash chip driver advanced configuration options               │ │
  │ │        Flash cmd/query data swapping (NO)  --->                     │ │
  │ │ 
   Specific CFI Flash geometry selection                        │ │
  │ │  [ ]     Support  8-bit buswidth                                    │ │
  │ │ 
     Support 16-bit buswidth                                    │ │
  │ │  [ ]     Support 32-bit buswidth                                    │ │
  │ │  [ ]     Support 64-bit buswidth                                    │ │
  │ │  [ ]     Support 128-bit buswidth                                   │ │
  │ │  [ ]     Support 256-bit buswidth                                   │ │
  │ │ 
     Support 1-chip flash interleave                            │ │
  │ │  [ ]     Support 2-chip flash interleave                            │ │
  │ │  [ ]     Support 4-chip flash interleave                            │ │
  │ │  [ ]     Support 8-chip flash interleave

在Mapping drivers for chip access中选中我们编写的at92rm9200.c的配置选项。系统配置完毕。
编译内核,启动可以看到输出了:
U-Boot 1.1.4 (Jun 12 2007 - 20:30:10)

U-Boot code: 21F00000 -> 21F1D788  BSS: -> 21F3B204
RAM Configuration:
Bank #0: 20000000 32 MB
SST 39VF3201 flash
Flash:  4 MB
NAND:   0 MB
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0
uboot>
uboot> loadb
## Ready for binary (kermit) download to 0x20008000 at 115200 bps...

uboot> bootm
## Booting image at 20008000 ...
   Image Name:   Linux-2.6.14
   Created:      2007-06-19  11:37:53 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1059236 Bytes =  1 MB
   Load Address: 20008000
   Entry Point:  20008040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK

Starting kernel ...

Uncompressing Linux.............................................................Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #26 Tue J7CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: Atmel AT91RM9200-DK
Memory policy: ECC disabled, Data cache writeback
Clocks: CPU 179 MHz, master 59 MHz, main 18.432 MHz
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: mem=32M noinitrd console=ttyS0,115200 init=/linnuxrc root=2AT91: 128 gpio irqs in 4 banks
PID hash table entries: 256 (order: 8, 4096 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 32MB = 32MB total
Memory: 30116KB available (1752K code, 379K data, 96K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
softlockup thread 0 started up.
NET: Registered protocol family 16
usbcore: registered new driver usbfs
usbcore: registered new driver hub
NetWinder Floating Point Emulator V0.97 (double precision)
devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
yaffs Jun 12 2007 20:21:49 Installing.
AT91 Real Time Clock driver.
AT91 SPI driver loaded
AT91 Watchdog Timer enabled (5 seconds)
ttyS0 at MMIO 0xfefff200 (irq = 1) is a AT91_SERIAL
ttyS1 at MMIO 0xfefc4000 (irq = 7) is a AT91_SERIAL
io scheduler noop registered
io scheduler anticipatory registered
RAMDISK driver initialized: 16 RAM disks of 8192K size 1024 blocksize
eth0: AT91 ethernet at 0xfefbc000 int=24 10-HalfDuplex (08:00:3e:26:0a:5b)
eth0: Davicom 9196 PHY (Copper)
RM9200-NOR:0x00400000 at 0x10000000
Found: SST 39VF3201
NOR flash on rm9200: Found 1 x16 devices at 0x0 in 16-bit bank
number of JEDEC chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
RM9200-NOR:using static partition definition
Creating 3 MTD partitions on "NOR flash on rm9200":
0x00000000-0x00040000 : "uboot"
0x00040000-0x00200000 : "kernel"
0x00200000-0x00400000 : "rootfs"
No SmartMedia card inserted.
No NAND device found!!!
at91_cf: irqs det #64, io #0
usbmon: debugfs is not available
at91rm9200-ohci at91rm9200-ohci: AT91RM9200 OHCI
at91rm9200-ohci at91rm9200-ohci: new USB bus registered, assigned bus number 1
at91rm9200-ohci at91rm9200-ohci: irq 23, io mem 0x00300000
usb usb1: Product: AT91RM9200 OHCI
usb usb1: Manufacturer: Linux 2.6.14 ohci_hcd
usb usb1: SerialNumber: at91rm9200
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
udc: at91_udc version 8 March 2005
mice: PS/2 mouse device common for all mice
i2c /dev entries driver
Found AT91 i2c
AT91RM9200 MCI initialized
NET: Registered protocol family 2
IP route cache hash table entries: 512 (order: -1, 2048 bytes)
TCP established hash table entries: 2048 (order: 1, 8192 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17

虽然flash上的文件系统还没有做,但flash芯片及flash文件系统分区信息已经出来了。有了这,就只需要在flash做实际的文件系统了。

添加64M的nandflash后uboot自动识别出来了!
U-Boot 1.1.4 (Jun 12 2007 - 20:30:10)

U-Boot code: 21F00000 -> 21F1D788  BSS: -> 21F3B204
RAM Configuration:
Bank #0: 20000000 32 MB
SST 39VF3201 flash
Flash:  4 MB
NAND:  64 MB
In:    serial
Out:   serial
Err:   serial
原创粉丝点击