我的平台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 <mag@sysgo.de>"); 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了,祝大家顺利。