分类: LINUX
2007-08-22 16:38:25
Flash Memory有两种:NOR、NAND。
读NOR Flash就像读SRAM一样,可以从任一地址读取,可以直接从NOR Flash中执行代码,因此在小型系统中,选择NOR Flash是一种好的选择。NOR Flash大小主要从几百KB到64MB。
NAND Flash一般一次读一个block,就象一个硬盘一样。NAND Flash不能直接执行代码。NAND Flash比NOR Flash便宜,同时容量也更大,一般是8MB以上,甚至到GB。
写Flash需要固定的步骤,不象写RAM。写之前一般都要先擦除。
所有的Flash都有分段(Segment)或是分块(Block)的概念,一个段或是块是擦除的最小单元。不能擦除一个或是几个字节。段(块)的大小与具体的产品相关,一般是8KB~128KB。
接下我们重点关注NOR Flash,因为在大部分的uClinux系统中,使用的都是NOR Flash。
显而易见,Flash memory是保存系统代码与数据的设备,最简单的方案就是把uClinux的内核放在处理器的启动地址,并把Flash作为一个大的储存器。
但通常的用法都是将Flash进行分区,一个典型的分区方案:
这是一个很简单的分区方案,你也可以设计都很复杂。只要注意分区是段(块)的整数倍,因为擦除的最小单位是一个段(块)。
这个方案中是把kernel、root filesystem放在不同的分区中,而不象桌面系统或是服务器,通常它们是把kernel放在root文件系统中的。只所以不放在一起,是因为放在一起的话,需要一个智能的bootloader(比如LILO、GRUB),能够知道那些块是kernel而加载到RAM。
有几种方案来放置内核与根文件系统:
A、内核――固定位置,根文件系统――固定位置
B、内核,根文件系统紧随内核
C、压缩内核与根文件系统
方案A:方便bootloader查找内核、根文件系统,并方便升级。缺点是要浪费一部分空间
方案B:节约空间,通常是把内核和根文件系统组织成一个文件,这样升级时要把内核和文件系统一起更新
方案C:最节约空间,但需要bootloader解压缩
当前uClinux有三种块设备可以包含根文件系统:
Blkmem设备
MTD设备
RAM disk设备
Blkmem驱动是最老的驱动,配置复杂;
MTD驱动是linux下标准的Flash驱动
很明显,MTD驱动是最强大的Flash的驱动,其允许在Flash上建立read/write的文件系统,比如说JFFS、JFFS2。而Blkmem驱动不行。
在uClinux下有数种根文件系统可供选择。
ROMfs:
Cramfs:
MTD之上的read/write文件系统,如JFFS、JFFS2
当使用MTD驱动时,有如下工具可供使用:
Flatfsd对于嵌入式系统保存用户配置是一个理想的解决方案。Flatfsd在后台执行,当接收到SIGUSR1信号时,flatfsd将会把/etc/config的内容写入/dev/flash/config。
下面是配置Flatfsd的步骤
/bin/expand /etc/ramfs.img /dev/ram1
mount -t ext2 /dev/ram1 /etc/config
将ram1加载到/etc/config目录,这样就可以对/etc/config进行读写,这个目录将被应用程序用来保存配置。
Flatfsd可以与三种设备进行交互:
MTD device
Block Mem device
Disklike device
Flatfsd缺省情况下将/etc/config的内容写入设备/dev/flash/config,因此必须将/dev/flash/config与相应的设备关联起来。
如何关联/dev/flash/config?
两种方法:(通过主Makefile或是手工操作都行)
例如我们使用MTD设备(MTD设备的主设备号为90,次设备号为偶数的为可写的设备)
方法一:在主Makefile中(vendors/xxx/目录下)
FLASH_DEVICES = \
image,c,90,0 \
config,c,90,2 \
loader,c,90,4
romfs:
[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)
for i in $(ROMFS_DIRS); do \
[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)/$$i; \
done
for i in $(DEVICES); do \
touch $(ROMFSDIR)/dev/@$$i; \
done
for i in $(FLASH_DEVICES); do \
touch $(ROMFSDIR)/dev/flash/@$$i; \
done
方法二:在主Makefile中(vendors/xxx/目录下)
FLASH_DEVICES = \
image,c,90,0 \
config,c,90,2 \
loader,c,90,4
romfs:
[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)
for i in $(ROMFS_DIRS); do \
[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)/$$i; \
done
for i in $(DEVICES); do \
touch $(ROMFSDIR)/dev/@$$i; \
done
$(ROMFSINST) -s /var/tmp /tmp
$(ROMFSINST) -s /bin /sbin
$(ROMFSINST) -s /var/etc/hosts /etc/hosts
$(ROMFSINST) -s /var/etc/resolv.conf /etc/resolv.conf
$(ROMFSINST) -s /var/etc/inetd.conf /etc/inetd.conf
$(ROMFSINST) -s /var/etc/passwd /etc/passwd
$(ROMFSINST) /etc/ssl_cert.pem
$(ROMFSINST) /etc/ssl_key.pem
$(ROMFSINST) /etc/rc
$(ROMFSINST) /etc/ramfs8192.img
$(ROMFSINST) /etc/inittab
$(ROMFSINST) /etc/services
$(ROMFSINST) /etc/motd
$(ROMFSINST) -s /dev/mtd2 /dev/flash/config
很显然,系统启动的时候需要将flash里面的配置读入到/etc/config目录。通过执行
flatfsd –r
可以实行这一点。一般将这个命令放入启动脚步/etc/rc中,以便在系统启动的时候自动执行。
flatfsd也应当自动在后台执行,可以通过/etc/inittab中添加语句:
flt:unknown:/bin/flatfsd
来启动flatfsd,也可以在/etc/rc中添加脚本:
/bin/flatfsd &
来启动。
如何保证flash的文件没被破坏?