如何在AT91RM9200上移植jffs2文件系統

我的平臺CPU:AT91RM9200;SDRAM:32M;Nor Flash:16M;

 1.製作mtd-util工具

 

(1)從我的資源(http://download.csdn.net/source/1141237)上下載zlib-1.2.3.tar.gz 解壓縮 $ cd zlib-1.2.3

 

$ ./configure –prefix=/usr/local/arm/3.4.1/arm-linux --shared

修改Makefile如下(如果是在PC機環境下製作文件系統就不需要修改):

CC=arm-linux-gcc LDSHARED=arm-linux-ld -shared

 

$ make all

$ make install

注意:這裏是安裝在/usr/local/arm/3.4.1/arm-linux目錄下

 

由於交叉編譯mtd工具時需要zlib.h文件,所以在編譯之前先安裝zlib庫文件。

 

(2)從我的資源(http://download.csdn.net/source/1141259)上下載 mtd-snapshot-20050519.tar.bz2 解壓縮 $ cd mtd/util

修改該目錄下的Makefile(如果是在PC機環境下製作文件系統就不需要修改):

CROSS=arm-linux-

 

$ make all

 

然後將該目錄下生成的 flash_erase,flash_eraseall, mkfs.jffs2工具放在ramdisk 文件系統中(我這裏放在/bin目錄下),另外在 ramdisk文件系統的dev目錄下要保證有mtd0~mtd9,mtdblock0~mtdblock9這些設備,如果沒有可參考 ramdisk文件系統的製作,也可從pc機相同目錄下拷貝,要加上文件屬性。

 

2.需要將/arm-linux/lib目錄下的libz.so, libz.so.1, libz.so.1.2.3文件拷貝到ramdisk文件系統的/lib目錄下,否則mkfs.jffs2工具不能使用。

 

3.將新生成的uImage和ramdisk文件下載到板子上,起動系統,使用命令 cat /proc/mtd 可以看到

dev: size erasesize name

mtd0: 00040000 00020000 "Partition 1"

mtd1: 0ffc0000 00020000 "Partition 2"

mtd2: 00420000 00000210 "spi0.0-AT45DB321x"

 

這裏mtd0,mtd1是nandflash上的分區; mtd2是dataflsh上的分區,該分區上放有u-boot,uImage.img,ramdisk.img,所以我們這裏可以使用空的nandflash上的兩個分區。使用之前要先用工具flash_erase或者flash_eraseall擦除nandflash,具體使用的步驟如下:

 

# flash_erase /dev/mtd1

 

3.製作jffs2映像

 

# cd /var/tmp

 

# mkdir jffs2 (jffs2下的目錄可以任意建)

 

# mkfs.jffs2 –d jffs2/ -o jffs2.img

 

# cp /var/tmp/jffs2/jffs2.img /dev/mtdblock1

 

4.# mount -t jffs2 /dev/mtdblock1 /mnt/mtd即可,使用結束可使用$ umount /mnt/mtd 卸載.

 

如果只是當作普通的jffs2 來使用dataflash或者nandflash,可不必製作 jffs2映像,只需要最後一步

 

# mount -t jffs2 /dev/mtdblock1 /mnt/mtd即可

 

文件系統製作好以後還需要在內核編譯的時候加入對jffs2文件系統的支持,下面即是對內核編譯的介紹:

開發板上只有Nor Flash,所以爲了實現層次文件系統,需要爲Linux2.6.20增加Nor Flash MTD驅動支持。其實工作量並不大,因爲已經有現成的程序可供參考。

 
    MTD的驅動程序都集中在drivers/mtd裏面。我們需要做的,僅僅是在drivers/mtd/maps下增加自己的分區表。因爲有參考的代碼,所以比較容易。
 
1.構建配置選項
 
    首先,根據edb7312.c構建自己的mtd分區表驅動。
 

$cd drivers/mtd/maps/
$cp edb7312.c at91rm9200.c

 
    然後,修改Kconfig,增加自己的配置選項。
 

//拷貝過EDB7312稍作修改即可
config MTD_AT91RM9200
        tristate "CFI Flash device mapped on AT91RM9200"
        depends on ARM && MTD_CFI
        help
          This enables access to the CFI Flash on the ATMEL AT91RM9200DK board.
          If you have such a board, say 'Y' here.

 
    最後,修改Makefile,增加編譯項目。
 

obj-$(CONFIG_MTD_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_AT91RM9200) += at91rm9200.o

 
    這樣,自己建立的MTD分區表驅動就可以編譯進內核了。
 
2.修改分區表信息
 
    因爲第一步的工作中,at91rm9200.c實際上還是edb7312.c的內容,所以需要根據自己的開發板nor flash的配置做一下修改。
 

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>

#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif

#define WINDOW_ADDR 0x10000000 /* physical properties of flash */
#define WINDOW_SIZE 0x00800000 /* intel 28F640J3A 8MB */
#define BUSWIDTH 2 /* data bus width 16bits */
/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */
#define PROBETYPES { "cfi_probe", NULL }

#define MSG_PREFIX "AT91RM9200-NOR:" /* prefix for our printk()'s */
#define MTDID "at91rm9200-%d" /* for mtdparts= partitioning */

static struct mtd_info *mymtd;

struct map_info at91rm9200nor_map = {
        .name = "NOR flash on AT91RM9200DK",
        .size = WINDOW_SIZE,
        .bankwidth = BUSWIDTH,
        .phys = WINDOW_ADDR,
};

#ifdef CONFIG_MTD_PARTITIONS

/*
 * MTD partitioning stuff
 */

static struct mtd_partition at91rm9200nor_partitions[5] =
{
        {
                
// U-boot 128KB
                .name = "U-boot",
                .size = 0x20000,
                .offset = 0
        },
        {
                
// uImage 2MB
                .name = "Kernel",
                .size = 0x200000,
                .offset = 0x20000
        },
        {
                
// RootFS 3MB
                .name = "RootFS",
                .size = 0x300000,
                .offset = 0x220000
        },
        {
                
// UserFS
                .name = "Jffs2",
                .size = 0x2C0000,
                .offset = 0x520000
        },
        {
                
// Parameters
                .name = "Parameters",
                .size = 0x20000,
                .offset = 0x7E0000
        },
};

static const char *probes[] = { NULL };

#endif

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

int __init init_at91rm9200nor(void)
{
        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);
        at91rm9200nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);

        if (!at91rm9200nor_map.virt) {
                printk(MSG_PREFIX "failed to ioremap/n");
                return -EIO;
        }

        simple_map_init(&at91rm9200nor_map);

        mymtd = 0;
        type = rom_probe_types;
        for(; !mymtd && *type; type++) {
                mymtd = do_map_probe(*type, &at91rm9200nor_map);
        }
        if (mymtd) {
                mymtd->owner = THIS_MODULE;

#ifdef CONFIG_MTD_PARTITIONS
                mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
                if (mtd_parts_nb > 0)
                  part_type = "detected";

                if (mtd_parts_nb == 0)
                {
                        mtd_parts = at91rm9200nor_partitions;
                        mtd_parts_nb = ARRAY_SIZE(at91rm9200nor_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 *)at91rm9200nor_map.virt);
        return -ENXIO;
}

static void __exit cleanup_at91rm9200nor(void)
{
        if (mymtd) {
                del_mtd_device(mymtd);
                map_destroy(mymtd);
        }
        if (at91rm9200nor_map.virt) {
                iounmap((void *)at91rm9200nor_map.virt);
                at91rm9200nor_map.virt = 0;
        }
}

module_init(init_at91rm9200nor);
module_exit(cleanup_at91rm9200nor);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marius Groeger <[email protected]>");
MODULE_DESCRIPTION("Generic configurable MTD map driver");

 
3.配置內核
 
    增加MTD,和相應的文件系統的支持。
 
    Devices Drivers --->
            Memory Technology Devices (MTD) --->
                 <*> Memory Technology Device(MTD) support
                 <*> MTD partitioning support
                 <*> Direct char device access to MTD devices
                 <*> Caching block device access to MTD devices
                 RAM/ROM/Flash chip drivers --->
                     <*> Detect flash chips by Common Flash Interface(CFI) probe
                     <*> Support for Intel/Sharp flash chips
                 Mapping drivers for chip access --->
                     <*> CFI Flash device mapped on AT91RM9200
    File Systems --->
           Miscellaneous filesystems --->
                這裏選擇cramfs或者Jffs2的支持。
 
4.編譯,然後加載
 
    make Image編譯,然後製作成uImage。
 

TOPDIR=$($(which pwd))
TMP=$TOPDIR/linux.bin
TARGET=$TOPDIR/uImage

arm-linux-objcopy -O binary -S vmlinux $TMP && gzip -v9 $TMP && /
mkimage -n 'RAM disk' -A arm -O linux -T kernel -C gzip /
        -a 0x20008000 -e 0x20008000 -d $TMP.gz $TARGET && /
cp $TARGET /mnt/hgfs/common && /
rm -f $TMP*

 
    這是JFFS2作爲根文件系統的信息:
 

AT91RM9200-NOR:0x00800000 at 0x10000000
NOR flash on AT91RM9200DK: Found 1 x16 devices at 0x0 in 16-bit bank
 Intel/Sharp Extended Query Table at 0x0031
Using buffer write method
cfi_cmdset_0001: Erase suspend on write enabled
AT91RM9200-NOR:using static partition definition
Creating 5 MTD partitions on "NOR flash on AT91RM9200DK":
0x00000000-0x00020000 : "U-boot"
0x00020000-0x00220000 : "Kernel"
0x00220000-0x00520000 : "RootFS"
0x00520000-0x007e0000 : "Jffs2"
0x007e0000-0x00800000 : "Parameters"

 

JFFS2 notice: (1) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
VFS: Mounted root (jffs2 filesystem).
Freeing init memory: 100K
init started: BusyBox v1.9.1 (2008-03-15 15:28:44 CST)
starting pid 710, tty '': '/etc/init.d/rcS'

 
    可以看到MTD分區信息。進入shell界面,然後查看/proc/mtd,如下:
 

[root@lqm ~]#cat /proc/mtd
dev: size erasesize name
mtd0: 00800000 00020000 "NOR flash on AT91RM9200DK"
mtd1: 00020000 00020000 "U-boot"
mtd2: 00200000 00020000 "Kernel"
mtd3: 00300000 00020000 "RootFS"
mtd4: 002c0000 00020000 "Jffs2"
mtd5: 00020000 00020000 "Parameters"

 
    可以看到加載是正確的。
5.最後把內核和文件系統下載到板子上就OK了,祝大家順利。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章