Create Jffs2 for Linux Kernel 2.6
来源:互联网 发布:彩票源码程序 编辑:程序博客网 时间:2024/04/26 11:46
工作前准备:
1.构建交叉编译环境:请参考其它文章,建议读者直接从网上down一个已经做好的cross或者用eldk编译一个cross,在现在这个讲效率的时代,我想我们应该搞清楚重点,毕竟我们的重点工作并不是制作环境变量,而是系统构建。
2.Jffs2文件映像制作:
编译安装mtd-utils工具,用于jffs2映像制作。
如果要把ramdisk作为根文件系统,请参考另一篇文章的讲解。假设你已经
做好的你的文件系统,包括命令,库,设备文件等等。就可以使用mkfs.jffs2进行jffs2文件格式制作了。为了你的查阅方便我这里列出mkfs.jffs2常用的命令参数:
-p, --pad[=SIZE] 用16進制來表示所要輸出檔案的大小,也就是root.jffs2的size。
很重要的是, 為了不浪費flash空間, 這個值最好符合flash driver所規劃的區塊大小。
如果不足则使用0xff来填充补满。
-r, -d, --root=DIR 指定要做成image的源資料夾.(默认:当前文件夹)
-s, --pagesize=SIZE 节点页大小(默认: 4KiB)
-e, --eraseblock=SIZE 设定擦除块的大小为(默认: 64KiB)
-c, --cleanmarker=SIZE Size of cleanmarker (default 12)
-m, --compr-mode=MODE Select compression mode (default: priortiry)
-x, --disable-compressor=COMPRESSOR_NAME
Disable a compressor
-X, --enable-compressor=COMPRESSOR_NAME
Enable a compressor
-y, --compressor-priority=PRIORITY:COMPRESSOR_NAME
Set the priority of a compressor
-L, --list-compressors Show the list of the avaiable compressors
-t, --test-compression Call decompress and compare with the original (for test)
-n, --no-cleanmarkers 指明不添加清楚标记(nand flash 有自己的校检块,存放相关的信息。)
如果挂载后会出现类似:
CLEANMARKER node found at 0x0042c000 has totlen 0xc != normal 0x0
的警告,则加上-n 就会消失。
-o, --output=FILE 指定輸出image檔案的文件名.(default: stdout)
-l, --little-endian 指定使用小端格式
-b, --big-endian 指定使用大端格式
-D, --devtable=FILE Use the named FILE as a device table file
-f, --faketime Change all file times to '0' for regression testing
-q, --squash Squash permissions and owners making all files be owned by root
-U, --squash-uids 将所有文件的拥有者设为root用户
-P, --squash-perms Squash permissions on all files
--with-xattr stuff all xattr entries into image
--with-selinux stuff only SELinux Labels into jffs2 image
--with-posix-acl stuff only POSIX ACL entries into jffs2 image
-h, --help 显示这些文字
-v, --verbose Verbose operation
-V, --version 显示版本
-i, --incremental=FILE Parse FILE and generate appendage output for it
制作好的jffs2.img,我们就可以在uboot中直接cp.b到相应的“分区”中了。
Protect off all
Erase 0x10340000(jffs2文件分区起始地址) 0x103fffff(jffs2文件分区结束地址)
Tftp 0x20000000(下载jffs2.img映像到ram中) jffs2.img
Cp.b 0x20000000 0x10340000 0xdc(将刚才下载到ram中 jffs2映像写入到flash相应分区中,0xdc是jffs2的大小)
Protect on all
3. 创建相应的/dev设备文件
# mknod -m 666 mtd0 c 90 0
# mknod -m 666 mtd1 c 90 2
# mknod -m 666 mtd2 c 90 4
# mknod -m 666 mtd3 c 90 6
# mknod -m 666 mtd4 c 90 8
# mknod -m 666 mtd5 c 90 10
# mknod -m 666 mtdblock0 b 31 0
# mknod -m 666 mtdblock1 b 31 1
# mknod -m 666 mtdblock2 b 31 2
# mknod -m 666 mtdblock3 b 31 3
# mknod -m 666 mtdblock4 b 31 4
# mknod -m 666 mtdblock5 b 31 5
这里有可能只需要后面一部分,视具体内核驱动代码而定。如果我们使用mdev 或者devfs进行设备文件创建的话,就不必进行设备创建了,但是让我很恼火的是mdev创建了众多的文件,让我的ram难的承受,(更确切的讲,应该是让我很难承受),如果你也无法接受的话,你可以手动创建必要文件。
这里如果要用mdev自动创建设备文件的话,我们需要在我们的启动脚本里做出如下动作:
/sbin/init ->/etc/inittab->/etc/init.d/rcS (自定义)
在rcS中我们添加如下命令:
#!/bin/sh
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#mount -t jffs2 /dev/mtdblock5 /mnt/
当然这里执行了mount -a自然要转向/etc/fstab中执行挂载命令:
fstab中的内容如下(当然你也可以选择你需要的文件系统进行挂载):
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
4.如果系统启动停止在uncompress ramdisk处就说明init进程没有正常启动,可能是busybox编译生成的/sbin/init文件不对或者其它问题。
5.还需要要注意的是init=linuxrc和ram0的区别。
6.下面我们参考 一位网友的文章 进行实际移植操作:
(1)构建配置选项 $cd drivers/mtd/maps/
首先,由于kernel2.6的数据结构关系复杂,这里我们只需要照着例子做就行了,选择一个比较相似的驱动文件,根据edb7312.c构建自己的mtd分区表驱动。
$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
这里的at91rm9200.o来源于以下源文件at91rm9200.c,这样,自己建立的MTD分区表驱动就可以编译进内核了。
因为第一步的工作中,at91rm9200.c实际上还是edb7312.c的内容,所以需要根据自己的开发板nor flash的配置做一下修改。
/*
* $Id: physmap.c,v 0.1.0 2009/05/15 09:14:50 mag Exp $
*
* Normal mappings of chips in physical memory
*/
/**************************************************
* Add for Olp by guohui luo 2009/5/15
*
***************************************************/
#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 0x00400000
#define BUSWIDTH 2
/*
#define FLASH_BLOCKSIZE_MAIN 0x20000
#define FLASH_NUMBLOCKS_MAIN 128
*/
/* 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[6] =
{
{/*1*/
.name = "Boot for AT9200",/* boot for uboot */
.size = 0x00020000,/* 1*128KB */
.offset = 0x00000000
},
{/*2*/
.name = "U-Boot",/* U-Boot firmware */
.size = 0x00020000,/* 1*128KB */
.offset = 0x00020000
},
{/*3*/
.name = "Environment", /* default env */
.size = 0x00020000, /* 1*128kb */
.offset = 0x00040000
},
{/*4*/
.name = "Linux Kernel", /* default kernel image */
.size = 0x00100000, /*8x128k=640k*/
.offset = 0x00060000
},
{/*5*/
.name = " rootfs ramdisk", /* default root filesystem */
//.size = 0x002c0000,/*22*128KB=2816KB*/
.size = 0x001e0000,/*15*128kb=2304kb*/
.offset = 0x00160000
},
{/*6*/
.name = "Jffs2", /* writen filesystem */
//.size = 0x00040000,/* 2*128KB=256KB */
//.offset = 0x003c0000,
.size = 0x000c0000,/*6*128k=768k*/
.offset = 0x00340000
}
};
//static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
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");
增加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 --->
这里选择Jffs2的支持。
(4)编译,加载
make Image编译,然后制作成uImage。
可以修改Makefile 文件,添加cross工具和uboot工具处理命令。
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*
或者直接按照Olp嵌入式系统构建中讲到的方法进行uImage 文件生成,uImage格式要比其它其中映像格式灵活,所以我们一向选择uImage。
系统启动过程中Jffs2信息:
AT91RM9200-NOR:0x00400000 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
mtd: Giving out device 0 to NOR flash on AT91RM9200DK
AT91RM9200-NOR:using static partition definition
Creating 6 MTD partitions on "NOR flash on AT91RM9200DK":
0x00000000-0x00020000 : "Boot for AT9200"
mtd: Giving out device 1 to Boot for AT9200
0x00020000-0x00040000 : "U-Boot"
mtd: Giving out device 2 to U-Boot
0x00040000-0x00060000 : "Environment"
mtd: Giving out device 3 to Environment
0x00060000-0x00160000 : "Linux Kernel"
mtd: Giving out device 4 to Linux Kernel
0x00160000-0x00340000 : " rootfs ramdisk"
mtd: Giving out device 5 to rootfs ramdisk
0x00340000-0x00400000 : "Jffs2"
mtd: Giving out device 6 to Jffs2
查看/proc文件系统中mtd信息:
# cat /proc/mtd
dev: size erasesize name
mtd0: 00400000 00020000 "NOR flash on AT91RM9200DK"
mtd1: 00020000 00020000 "Boot for AT9200"
mtd2: 00020000 00020000 "U-Boot"
mtd3: 00020000 00020000 "Environment"
mtd4: 00100000 00020000 "Linux Kernel"
mtd5: 001e0000 00020000 " rootfs ramdisk"
mtd6: 000c0000 00020000 "Jffs2"
这里需要注意的是:
我们需要挂载mede生成 的dev设备,不然,后面的terminal 和设备都会找不到,当然如果你不选择用mdev或者devfs创建设备的话,就没有必要按下面的方式进行挂载,不过我不太喜欢medv创建的设备,实在是太多了,大大占用了我可贵的ram资源.
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mount -t jffs2 /dev/mtdblock5 /mnt/
(5)Jffs2文件系统测试
挂载Jffs2文件分区:
Mount -t jffs2 /dev/mtdblock5 /mnt
Vi /mnt/test.txt
写入一段文字,然后umount /mnt ,再挂载,看一下刚才写入的文件是否存在,再掉电重启一下系统,确认jffs2文件系统支持良好。
- Create Jffs2 for Linux Kernel 2.6
- Create Jffs2 for Linux Kernel 2.4(for arm and mips)
- 2440移植Linux Kernel笔记(三)------制作jffs2映像文件
- skyeye linux 2.6.14 jffs2
- Linux Kernel Tuning for C500k
- Linux Kernel Tuning for C500k
- make logo for linux kernel
- Compile for old-kernel Linux
- Linux Module 的HelloWorld程序(For Kernel-2.6)
- VMware for Linux Install(2.6.35 kernel)失败的问题
- linux新增system call(for kernel 2.6)
- ZZ: linux新增system call(for kernel 2.6)
- linux新增system call(for kernel 2.6)
- Linux documentation for /proc/sys/vm/* kernel version 2.6.29
- A simple kernel module for linux FC4(kernel version 2.6.11-1.1369_FC4smp)
- How to Create, Compile, Load Linux LKM Loadable Kernel Modules
- Linux jffs2 使用总结
- linux for qq (create a shortcut )
- 程序员
- Linux: 3322.org+lynx+crontab 实现ddns的自动刷新
- Linux下GCC编程四个过程(转)
- 值类型和引用类型的区别
- C#继承、覆盖和多态、抽象类
- Create Jffs2 for Linux Kernel 2.6
- C++类中的访问控制
- 客户化开发的功能主菜单丢失的问题。
- 三步学会Java Socket编程
- Linux系统信息查看命令大全
- 代码实现接口抽象类
- 什么样的域名能卖出去并卖个好价格
- OpenMP学习之--任务划分与调度(代码示例)
- Head First C# 中文版 第九章 读写文件 page424