JFFS2 文件系统及新特性介绍

合集下载

JFFS2——精选推荐

JFFS2——精选推荐

查论编JFFS2FFS2全名是 Journalling Flash File System Version2,是Redhat公司开发的闪存⽂件系统[1],其前⾝是JFFS, 最早只⽀持NOR Flash, ⾃2.6版以后开始⽀持NAND Flash, 极适合使⽤于嵌⼊式系统。

⽬录 [隐藏]1 特性2 缺点3 参见4 注释特性 [编辑]JFFS2 功能如下:⽀持 NAND flash 设备。

硬链接(Hard links)。

这是JFFS 碍于⽂件格式所⽆法⽀持的功能。

压缩。

有三种算法: zlib, rubin 以及 rtime.更佳的性能。

缺点 [编辑]JFFS2在挂载(mount)时会扫描整个flash 所有的数据,再将⽂件系统⽬录存储在system memory, 会线性倍数成长,消耗很多时间。

JFFS2没有write-back机制,不能将数据暂存于缓存(cache), 以致于flash I/O的动作频繁。

JFFS2设计机制过于复杂,代码不易阅读。

参见 [编辑]YAFFSUBIFSLogFSZFSBtrfsNILFS注释 [编辑]1. ^ JFFS2, mainly designed for raw flash, not for block devices like hard drives, USB sticks, CF cards etc. (block2mtd)磁盘⾼级光盘存档系统AdvFS Be⽂件系统 (BFS)Btrfs Coda CrossDOS光盘存档系统 (DFS)Episode EFS exFAT ext ext2ext3ext3cow ext4FAT FAT12FAT16FAT16B FAT32全局⽂件系统 (GFS)分层⽂件系统 (HFS)HFS Plus 光盘HSF ISO 9660ISO 13490UDF闪存/固态硬盘FAT exFAT CHFS FFS2F2FS JFFS JFFS2 LogFS NVFS YAFFS UBIFS分布式Coda DCE/DFS CXFS GFS2Google⽂件系统OCFS2QFS Xsan更多...⽹络储存设备AFS OpenAFS AFP MS-DFS GPFS Google⽂件系统Lustre NCP NFS POHMELFS Hadoop HAMMER SMB (CIFS)更多...特殊cramfs FUSE SquashFS UMSDOS UnionFS更多...伪系统和虚拟configfs devfs procfs specfs sysfs tmpfs WinFS 加密EncFS EFS ZFS。

jffs2文件系统

jffs2文件系统
#cat /etc/motd
根据要求创建:/proc /dev /tmp /sys目录 和文件 /etc/motd文件
同时为了兼容的问题作一个软链接: ln -s ./rc.d/rcS ./rc
继续修改etc/inittab文件,增加一个命令终端: ::respawn:/bin/cttyhack /bin/sh
b. 编译 make
c.把编译好的相关的命令copy到/root/rootfs: make install (/bin、/sbin、/usr/sbin、/usr/bin这些目录)
2) 制作有关的Linux启动的文件:
a. 在/root/fs目录下:创建etc目录 b. 把/armlinux/busybox-1.13.4/examples/inittab COPY到etc目录
5. 把root.img文件下载到目标机中(进入bootloader)
tftp root.img root
flash root
Hale Waihona Puke 6. 修改bootloader的命令行
root=1f02 rootfstype=jffs2 console=ttyS0,115200 mem=64M init=/in.sh
2) 库文件(包括QT库文件):
3)有关的Linux启动的文件:/etc/inittab , rc,(环境变量PATH,库文件的位置)
3、制作文件系统
1) 得到相应的命令,这个可以根据自己的要求来选择自己的命令。我们将使用busybox来得到我们的命令。我们这些命令必须是使用交叉编译器编译才行。
c. 修改inittab这个文件, (/etc/rc.d/rcS因为我们的Linux系统都是这样做的)

jffs2文件系统启动说明

jffs2文件系统启动说明
使用jffs2根文件系统启动EP9302步骤
一. 主机配置
建议Redhat 9 及以后版本
1. 配置TFTP服务器
$ /sbin/chkconfig tftp on
$ /sbin/service xinetd reload
创建TFTP主目录
三. 下载Linux
1. Tftp方式下载,将板子连上网络并通过和主机通信测试
2. 通过tftp将内核和根文件系统下载到SDRM在Redboot命令行下运行
$ load -r -v -b 0x1000000 jffs2.img
$ load -r -v -b 0x80000 zImage
2. 在linux下运行./download redboot.bin,将会出现“"Waiting for the board to wake up..."
3. 打开板电源,开始下载,结束会显示“Successfully programmed 'redboot.bin'”
4. 关闭电源。重新配置跳线(JP14为2-3),启动模式为Flash启动
$
启动时间设置,如果在该时间内用户没有按Ctrl+c则运行启动脚本,如设为3秒
$ Boot script timeout (1000ms resolution): 3
其他启动配置根据自己情况设置,最后按y保存
$ Update RedBoot non-volatile configuration - continue (y/n)?y 来自$ fconfig -i
出现Run script at boot:后输入true
启动脚本输入,在>>提示符下输入一行命令,回车再输下一行,脚本结束空行按回车。启动脚本如下

JFFS2文件系统介绍

JFFS2文件系统介绍

JFFS2文件系统及新特性介绍(reset)成逻辑1。

D)闪存的使用寿命是有限的。

具体来说,闪存的使用寿命是由擦写块的最大可擦写次数来决定的。

超过了最大可擦写次数,这个擦写块就成为坏块(bad block)了。

因此为了避免某个擦写块被过度擦写,以至于它先于其他的擦写块达到最大可擦写次数,我们应该在尽量小的影响性能的前提下,使擦写操作均匀的分布在每个擦写块上。

这个过程叫做磨损平衡(wear leveling)。

NOR flash与NAND flash的不同之处:A)NOR flash读/写操作的基本单位是字节;而NAND flash又把擦写块分成页(page),页是写操作的基本单位,一般一个页的大小是512或2K个字节。

对于一个页的重复写操作次数是有限制的,不同厂商生产的NAND flash有不同的限制,有些是一次,有些是四次,六次或十次。

B)按照现在的技术水平,一般来说NOR flash擦写块的最大可擦写次数在十万次左右,NAND flash擦写块的最大可擦写次数在百万次左右。

1.2闪存转换层将磁盘文件系统(ext2,FAT)运行在闪存上的很自然的方法就是在文件系统和闪存之间提供一个闪存转换层(Flash Translation Layer),它的功能就是将底层的闪存模拟成一个具有512字节扇区大小的标准块设备(block device)。

对于文件系统来说,就像工作在一个普通的块设备上一样,没有任何的差别。

图一一个闪存转换层的最简单的实现就是将模拟的块设备一对一的映射到闪存上。

举例来说,当上层的文件系统要写一个块设备的扇区时,闪存转换层要做下面的操作来完成这个写请求:1将这个扇区所在擦写块地数据读到内存中,放在缓存(buffer)中2将缓存中与这个扇区对应的内容用新的内容替换掉3对该擦写块执行擦写操作4将缓冲中的数据写回该擦写块这种实现方式的缺点是很明显的:1效率低,对一个扇区的更新要重写整个擦写块上的数据,造成数据带宽很大的浪费。

不同文件系统的比较

不同文件系统的比较

几种文件系统比较嵌入式系统中比较常用的文件系统为JFFS、JFFS2、CRAMFS和YAFFS。

J f f s2:日志闪存文件系统版本2(J o u r n a l l i n g F l a s h F i l e S y s t e m v2)JFFS2主要应用于NOR Flash,可读写,支持数据压缩,安全保护等特点。

存储空间已满或接近满时,JFFS2文件系统的运行速度却由于垃圾收集的原因而放慢。

不适合用于NAND Flash,NAND Flash的容量一般比较大,JFFS2文件系统为维护日志节点所占用的内存空间也迅速增大,因此JFFS2在挂载时需要很长时间来扫描整个FLASH的内容,用以找出所有的日志节点并建立文件结构,这样就会极大的降低系统的运行效率。

y a f f s:Y e t A n o t h e r F l a s h F i l e S y s t e myaffs/yaffs2是专为嵌入式系统使用NAND型闪存而设计的日志型文件系统。

不支持数据压缩,速度快,挂载时间很短,对内存的占用较小。

支持跨平台。

yaffs/yaffs2自带NAND芯片的驱动,并且为嵌入式系统提供了直接访问文件系统的API。

yaffs仅支持小页(512 Bytes) NAND闪存,yaffs2可支持大页(2KB) NAND闪存。

同时,yaffs2在内存空间占用、垃圾回收速度、读/写速度等方面均有大幅提升。

C r a m f s C o m p r e s s e d R O M F i l e S y s t e m是一种只读的压缩文件系统。

它也基于MTD驱动程序。

降低了系统成本。

以压缩方式存储,在运行时解压缩,不支持应用程序以XIP方式运行,需要将程序拷到RAM里去运行,它的效率高,速度快,其只读的特点保护文件系统免受破坏,提高了系统的可靠性。

R o m f s文件系统是一种简单的只读文件系统,不支持动态擦写,按顺序存放数据,因而支持应用程序以XIP片内运行方式运行,在系统运行时,节省RAM空间。

jffs2dump使用方法

jffs2dump使用方法

jffs2dump使用方法JFFS2是一种用于嵌入式系统的日志式闪存文件系统。

jffs2dump是一个实用工具,用于将JFFS2文件系统映像中的元数据信息转储到标准输出。

下面是jffs2dump的使用方法。

首先,确保您已经在系统中安装了jffs2dump工具。

您可以使用系统的软件包管理器进行安装。

例如,在Ubuntu系统上,您可以运行以下命令来安装jffs2dump:```sudo apt-get install mtd-utils```一旦准备就绪,您可以使用以下命令来运行jffs2dump:``````其中,`<image_file>`是您要转储的JFFS2文件系统映像的路径。

运行命令后,jffs2dump将根据元数据信息的不同,将转储的内容显示在标准输出中。

转储的内容包括文件和目录的元数据信息,如文件名、权限、所有者和时间戳等。

此外,还会显示相关的数据区块信息,如数据块的位置和大小等。

请注意,jffs2dump只能转储元数据信息,而不包括文件的实际数据内容。

如果您需要提取文件的实际数据,请使用其他工具,如`jffs2reader`等。

以下是jffs2dump的一些常用选项:-`-r`:递归显示子目录的元数据信息。

-`-u`:显示未使用的闪存块的元数据信息。

-`-c`:显示压缩的元数据信息。

-`-l`:显示长列表格式的元数据信息。

例如,如果您想递归显示所有文件和目录的元数据信息,可以运行以下命令:``````除了显示元数据信息外,jffs2dump还可以用于验证JFFS2文件系统映像的完整性。

在转储过程中,jffs2dump会检查文件系统映像中的校验和,并与转储的元数据信息进行比较。

如果校验和不匹配,则可能表示文件系统映像已损坏或被修改。

综上所述,jffs2dump是一个实用的工具,可以帮助您转储JFFS2文件系统映像的元数据信息,并验证文件系统映像的完整性。

使用jffs2dump可以更好地了解JFFS2文件系统的结构和内容,有助于系统维护和故障排查。

jffs2 原理

jffs2 原理

jffs2 原理JFFS2(Journalling Flash File System 2)是一种专为闪存设备设计的文件系统,它采用了日志记录的方式来管理数据的存储和访问。

本文将介绍JFFS2的原理和工作方式。

JFFS2的设计目标是提供一种高效可靠的文件系统,以适应闪存设备的特殊性。

相比传统的文件系统,JFFS2具有更好的写入性能和更低的擦除次数。

它通过将文件数据分成多个块进行存储,并使用日志记录来跟踪文件的变化。

JFFS2的工作原理如下:首先,文件系统将闪存设备划分为多个块,每个块的大小通常为64KB。

然后,文件系统将文件数据按块的大小进行划分,并将每个数据块与一个元数据块关联起来。

元数据块包含文件的元信息,如文件名、文件大小、权限等。

当需要写入文件时,JFFS2首先将文件数据写入一个临时缓冲区。

然后,它会创建一个新的元数据块,记录新写入的文件数据的位置和大小。

接下来,文件系统将新的元数据块写入闪存设备,并标记原有的数据块为过时。

在写入完成后,JFFS2会更新闪存设备的元数据,以反映文件的最新状态。

为了提高写入性能,JFFS2采用了日志记录的方式来管理文件的变化。

每次写入操作都会被记录在一个特殊的日志区域中。

当闪存设备空闲时,JFFS2会将日志中的操作应用到闪存上,以保持文件系统的一致性。

这样,即使系统崩溃或断电,文件系统也可以通过回放日志来恢复数据的完整性。

除了写入性能的提升,JFFS2还具有较低的擦除次数。

在传统的文件系统中,当文件被修改后,需要将整个文件所在的块擦除并重新写入。

而JFFS2只需要擦除和更新被修改的数据块,而不必擦除整个文件。

然而,JFFS2也存在一些限制。

首先,它只适用于小容量的闪存设备,因为它需要较多的元数据来管理文件系统。

其次,JFFS2对于大文件的读取性能较差,因为它需要遍历整个文件系统来查找文件数据。

总结起来,JFFS2是一种专为闪存设备设计的文件系统,采用了日志记录的方式来管理数据的存储和访问。

uClinux下Nor Flash的JFFS2文件系统构建

uClinux下Nor Flash的JFFS2文件系统构建

uClinux下Nor Flash的JFFS2文件系统构建目前的系统多用法FLASH作为主存,因此,如何有效管理FLASH上的数据十分重要文章以SST39VF160芯片为例,研究了在Nor Flash上建立的JFFS2文件系统的普通步骤,从而为FLASH上的数据管理提供了抱负的挑选方式嵌入式系统正随着Internet的进展而在各个领域得到广泛的应用,作为嵌入式应用的核心,嵌入式以其自由软件特性正日益被人们看好Linux具有内核小效率高源代码开放等优点,还内涵了完整的TCP/IP 网络协议,因此十分适于嵌入式系统的应用而作为特地运行于没有MMU的微处理器的嵌入式操作系统,uClinux更是得到广泛应用当前的嵌入式系统开发,需要便利灵便的用法Flash NOR和NAND是现在市场上两种主要的非易失闪存技术 Intel于1988年首先开发出NOR flash技术,彻底转变了原先由EPROM和EEPROM一统天下的局面 NOR 的特点是芯片内执行XIP eXe-cute In Place ,这样应用程序可以挺直在flash闪存内运行,不必再把代码读到系统RAM中 NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,因此在嵌入式系统得到广泛的应用1 JFFS2文件系统简介uClinux通常默认ROMFS作为根文件系统,它相对于普通的EXT2文件系统具有节省空间的优点但是ROMFS是一种只读的文件系统,不支持动态擦写保存虽然对于需要动态保存的数据可以采纳虚拟ram盘的办法来保存,但当系统掉电后,ram盘的内容将所有走失,而不能永远保存,因此需要实现一个可读写的文件系统 JFFS2文件系统便是一个很好的挑选JFFS文件系统是瑞典Axis通信公司开发的一种基于Flash的日志文件系统,它在设计时充分考虑了Flash的读写特性和用电池供电的嵌入式系统的特点,在这类系统中必须确保在读取文件时,假如系统骤然掉电,其文件的牢靠性不受到影响对Red Hat的David Woodhouse举第1页共7页。

JFFS2文件系统挂载过程优化的分析

JFFS2文件系统挂载过程优化的分析

JFFS2文件系统挂载过程优化的分析报告一问题描述在上电启动优化中发现Linux系统下挂载JFFS2文件系统耗时较长,以128M的NOR FLASH 为例,用时接近20秒。

后续单板的FLASH容量为256M,时间会更长。

如此长的挂载时间,会大增加系统的上电启动时间。

希望能对mount功能或JFFS2文件系统做适当优化,将256M FLASH的挂载时间降到3~5秒内,优化时需要同时保证文件系统的可靠性和读写速度,要保证兼容优化前的文件系统。

root@CMM:/$ time mount -t jffs2 /dev/mtdblock1 /FLASH0real 0m 19.83suser 0m 0.00ssys 0m 19.73s二问题分析与磁盘文件系统不同,JFFS2文件系统不在FLASH设备上存储文件系统结构信息,所有的信息都分散在各个数据实体节点之中,在挂载文件系统的时候,需扫描整个Flash设备,从中建立起文件系统在内存中的映像,系统在运行期间,就利用这些内存中的信息进行各种文件操作。

这就造成了JFFS2文件系统挂载时间过长,尤其是FLASH比较大,文件比较多的情况下。

擦除块小结(erase block summary)补丁可以提高JFFS2文件系统的挂载速度,它最基本的思想就是用空间来换时间。

具体来说,就是将擦除块每个节点的原数据信息写在这个擦除块最后的固定位置,当JFFS2挂载的时候,对每个擦除块只需要读取这个小结节点。

同时该补丁具有一定的稳定性和兼容性。

●稳定性:If the summary node is missing, maybe because of a system power-down before it could be written to flash, nothing bad happens - JFFS2 just falls back to scanning the whole block as it would have done before.●兼容性:The JFFS2 image produced by sumtool is also usable with previous kernel because the summary node is JFFS2_FEATURE_RWCOMPAT_DELETE.(当不支持擦除块小结特性的JFFS2文件系统发现了一个属性是JFFS2_FEATURE_RWCOMPAT_DELETE的节点时,在垃圾回收的时候,该节点可以被删除)三原理介绍在每个擦除块的末尾,有一个8 byte长的jffs2_sum_marker节点,该sum_marker节点记录summary node信息的存储位置,summary node可以由文件系统在写操作的过程中自动产生。

JFFS2的优缺点

JFFS2的优缺点

JFFS2 文件系统及新特性介绍简介:JFFS2 是一个开放源码的项目()。

它是在闪存上使用非常广泛的读/写文件系统,在嵌入式系统中被普遍的应用。

这篇文章首先分析了在闪存上使用 JFFS2 的必要性,然后详细的阐述了 JFFS2 实现的内部机制,包括日志结构的文件系统,关键的数据结构,挂载过程和垃圾收集机制。

同时也指出了 JFFS2 的局限性,并介绍了最新的针对 JFFS2 的不足进行改进的补丁程序。

最后对 JFFS3 的设计思想和现在的开发状况给予了简单的介绍。

1.为什么需要 JFFS2这一小节首先介绍了闪存相对于磁盘介质的特别之处,然后分析了将磁盘文件系统运行在闪存上的不足,同时也给出了我们使用 JFFS2 的理由。

1.1 闪存(Flash Memory) 的特性和限制这里所介绍的闪存的特性和限制都是从上层的文件系统的角度来看的,而不会涉及到具体的物理特性。

总的来说,有两种类型的 flash memory: NOR flash 和NAND flash. 先介绍一下这两种闪存所具有的共同特性。

A) 闪存的最小寻址单位是字节(byte),而不是磁盘上的扇区(sector)。

这意味着我们可以从一块闪存的任意偏移(offset)读数据,但并不表明对闪存写操作也是以字节为单位进行的。

我们会在下面的阐述中找到答案。

B) 当一块闪存处在干净的状态时(被擦写过,但是还没有写操作发生),在这块flash上的每一位(bit)都是逻辑1。

C) 闪存上的每一位(bit)可以被写操作置成逻辑0。

可是把逻辑 0 置成逻辑 1 却不能按位(bit)来操作,而只能按擦写块(erase block)为单位进行擦写操作。

擦写块的大小从 4K 到128K 不等。

从上层来看,擦写所完成的功能就是把擦写块内的每一位都重设置(reset)成逻辑 1。

D) 闪存的使用寿命是有限的。

具体来说,闪存的使用寿命是由擦写块的最大可擦写次数来决定的。

jffs2文件系统

jffs2文件系统
[*] Direct char device access to MTD devices
[*] Caching block device access to MTD devices
File systems --->
Miscellaneous filesystems --->
nand write.jffs2:向Nand Flash写入数据,如果NandFlash相应的区域有坏块,可以跳过坏块。
nand read:读取Nand Flash相应区域的数据,如果NandFlash相应的区域有坏块,则直接报错。
nand read.jffs2:读取Nand Flash相应区域的数据,如果NandFlash相应的区域有坏块,直接跳过坏块。
#cd zlib-1.2.3
#./configure
#make
#make install
完成此步骤后,系统中就有了mkfs.jffs2的工具。注意:这个工具不同于mkfs.ext2工具,它只能制作相应的JFFS2文件系统的镜像,而不具有进行格式化的功能,而mkfs.ext2具备这以上两种功能。然后用这个工具就可以制作JFFS2文件系统的镜像了。
具体操作及地址请参照本空间 Linux 系统的烧写
********************************************************
#nand erase 0x500000 0x3e00000
#tftp 0x30008000 rootfs.jffs2
#nand write.jffs2 0x30008000 0x500000 0x250000//(必须是rootfs.jffs2的实际大小。如果是你写的小了,那么分区的其余部分JFFS2文件系统将无法识别)。

JFFS和YAFFS两种文件系统在嵌入式Linux平台上的运行比较

JFFS和YAFFS两种文件系统在嵌入式Linux平台上的运行比较

TECHNOLOGY 技术应用一、嵌入式平台物理存储特性Nand flash内存作为flash内存的一种,因其具有容量较大,改写速度快等优点,适用于大量数据的存储,并且内部采用非线性宏单元模式,所以为固态大容量内存的实现提供了廉价有效的解决方案,在业界得到了越来越广泛的应用。

本文通过比较分析JFFS和YAFFS两种文件系统在Linux平台上的运行情况,来说明面向不同性能的文件系统选择。

二、JFFS文件系统1.稳定性优势。

JFFS文件系统采用日志结构,与Linux的标准文件系统Ext2文件系统相比,JFFS文件系统在执行扇区级别上的擦除、读、写的速度更快,并且在机器崩溃、掉电时能够提供安全保护。

这是因为Ext2文件系统对于一个扇区的更新需要重写整个擦写块,但是在重写过程中,若发生机器崩溃或突然断电,将会造成整个擦写块中的数据全部丢失。

而因嵌入式系统要求高稳定性,因宕机、断电而发生数据丢失的现象是不能接受的,所以JFFS文件系统具有免受宕机和断电危害功能的日志型文件系统,这点相较于Ext2文件系统又有了能够满足嵌入式系统稳定性要求的优势。

2.高效的垃圾回收机制。

JFFS文件系统具有高效的垃圾回收机制,即具有释放过时的日志文件节点的能力。

首先,JFFS文件系统以闪存块为单位进行空间的回收,每次擦除最应该被擦除的块,该块被擦除后成为新的空闲块;其次,JFFS文件系统通过碎片收集进程回收碎片,每次仅回收一个空闲块,只有在空闲块数过多的情况下,处于睡眠状态的进程才会被唤醒。

三、YAFFS文件系统对NAND Flash的支持YAFFS文件系统与JFFS文件系统相比,其优势在于它是首个专门针对NAND型闪存的文件系统。

因为NAND型闪存结构特殊,它是以页为单位进行读写和编程的操作,适合进行文件存储以及纯数据存储,考虑到NAND型闪存的特有结构,YAFFS文件系统将文件组织成固定大小的页。

在擦写策略方面,YAFFS文件系统采取先写入新的数据块,再删除旧的数据块的方式,防止了宕机、断电情况下,数据完整性被破坏。

可以了解的JFFS2 文件系统及新特性

可以了解的JFFS2 文件系统及新特性

可以了解的JFFS2 文件系统及新特性JFFS2 是一个开放源码的项目(infradead)。

它是在闪存上使用非常广泛的读/写文件系统,在嵌入式系统中被普遍的应用。

这篇文章首先分析了在闪存上使用JFFS2 的必要性,然后详细的阐述了JFFS2 实现的内部机制,包括日志结构的文件系统,关键的数据结构,挂载过程和垃圾收集机制。

同时也指出了JFFS2 的局限性,并介绍了最新的针对JFFS2 的不足进行改进的补丁程序。

最后对JFFS3 的设计思想和现在的开发状况给予了简单的介绍。

1.为什么需要JFFS2这一小节首先介绍了闪存相对于磁盘介质的特别之处,然后分析了将磁盘文件系统运行在闪存上的不足,同时也给出了我们使用JFFS2 的理由。

1.1 闪存(Flash Memory) 的特性和限制这里所介绍的闪存的特性和限制都是从上层的文件系统的角度来看的,而不会涉及到具体的物理特性。

总的来说,有两种类型的flash memory: NOR flash 和NAND flash. 先介绍一下这两种闪存所具有的共同特性。

A) 闪存的最小寻址单位是字节(byte),而不是磁盘上的扇区(sector)。

这意味着我们可以从一块闪存的任意偏移(offset)读数据,但并不表明对闪存写操作也是以字节为单位进行的。

我们会在下面的阐述中找到答案。

B) 当一块闪存处在干净的状态时(被擦写过,但是还没有写操作发生),在这块flash上的每一位(bit)都是逻辑1。

C) 闪存上的每一位(bit)可以被写操作置成逻辑0。

可是把逻辑0 置成逻辑1 却不能按位(bit)来操作,而只能按擦写块(erase block)为单位进行擦写操作。

擦写块的大小从4K 到128K 不等。

从上层来看,擦写所完成的功能就是把擦写块内的每一位都重设置(reset)成逻辑1。

D) 闪存的使用寿命是有限的。

具体来说,闪存的使用寿命是由擦写块的最大可擦写次数来决定的。

超过了最大可擦写次数,这个擦写块就成为坏块(bad block)了。

JFFS2文件系统在mClinux中的应用

JFFS2文件系统在mClinux中的应用

JFFS2文件系统在mClinux中的应用2003-05-15 09:30:35江苏东大集成电路系统工程技术有限公司胡晨峰2003年4上半月摘要: 本文首先简述了JFFS(Journalling Flash File System)的相关知识,然后介绍了在mClinux中实现JFFS2文件系统的具体方法。

主要内容包括在mClinux中使用JFFS2文件系统时内核的配置,相关代码的修改以及辅助工具的生成和使用。

关键词: JFFS2; MTD;mClinuxFLASH是一种可擦除的只读存储器,具有低成本,高可靠性和高存储密度的特征,因此被广泛应用在PDA等手持设备和信息家电产品之类以嵌入式系统为基础的产品中,其特点是只能以扇区为单位来擦除(扇区大小和芯片的型号有关)。

长期以来FLASH一直被用来存放可执行代码、变量和其他暂态数据,随着其应用的日趋广泛和深入,如何在其上建立一种稳定可靠、便于使用的针对FLASH特点的文件系统被提上议事日程。

JFFS文件系统就是在这种环境下而产生的,目前此文件系统只能在Linux环境下运行。

mClinux是专为无存储器管理单元(MMU)的微控制器而构造的嵌入式Linux操作系统。

在mClinux中,FLASH设备有两种作为文件系统的使用方式,其一是在FLASH上构造一个伪文件系统来模拟标准的块设备,然后在块设备上挂接普通的文件系统,另一种方式是在FLASH设备上使用JFFS文件系统,本文主要探讨后者。

JFFS2文件系统JFFS文件系统是瑞典的Axis通信公司开发的一种基于FLASH的日志文件系统,其在设计时充分考虑了FLASH的读写特性和用电池供电的嵌入式系统的特点,在这类系统中必需确保在读取文件时,如果系统突然掉电,其文件的可靠性不受到影响。

Red Hat公司在JFFS文件系统的基础上加以改进而形成JFFS2,主要改善了存取策略以提高FLASH的抗疲劳性及优化了碎片整理性能,增加了数据压缩功能。

一种基于错误植入的JFFS2文件系统可靠性分析方法

一种基于错误植入的JFFS2文件系统可靠性分析方法


} 圈
图 1 JF 2文件系统 布局 FS

从 M D模块 中读取数据后 , T 随机选 择其 中某一位取 反 , 再返 回
给上层。

( a 表示 N ND型闪存物理结构 ; b 表示 JF 2节点分布 , 图( ) A 图( ) FS
持 久性 错 洪
暂 时性错 误
研究。 D型 闪存


由很多相同大小 的块 组成 , 个块 又包 含很 多相 同大小 的页 。 每 每个 页除含有正 常 读 写的用 户 区域 外 , 还包 括 一个 “ 带外 ” 区
域, 简称为 O B O tO ad 。在 O B中主要存 放控 制和 管 O ( u fB n ) O
文件 系统具 有一定的错误检测和恢复 能力 , 以检测到所 有错误 , 可以通过 重试机 制恢复写错误和擦 除错误。但是对于大部 分测 可 并 试工作 负载 ,F S J F 2不能恢复读 错误 , 结果 导致操 作失败。最后针对增 强 J F 2文件 系统 的可靠性提 出 了改进 方案 。 FS
属于 日志文件系统 L S LgsutrdFl Ss m) 可 以很好地 F ( o —rc e i yt , t u e e
错 误 , 可能是 持久性错误 。闪存块 的擦除次 数是有 限的 , 1 也 在
万次至 10万次之 间 , 0 超过 这个 限 制后 , 闪存 单元 就 变为 不 可
写 闪存 的某些 区域时可能会发 生错误 , 这些错误 可能 是暂 时性
性具有重要 意义 。
1 J F 2文件 系统 FS
JF F S文件 系统全称是 Junln l hFl Ss m( oraigFa i yt 日志 闪 l s e e 存文件系统 ) 。由于最初 的版本局 限性较大 , 存在很 多 问题 , 于 是 R d a 在 2 0 年实现 了 J F eH t 0 1 F S第 2版 , 也就 是 JF 2 F S F S 。JF 2

Nand flash文件系统总结

Nand flash文件系统总结

NAND flash文件系统目前flash的文件系统比较多,用的比较多的就是JFFS2文件系统。

基于NOR flash上的JFFS2文件系统可以说算是比较成熟了,支持NAND flash的JFFS2也已经发布了。

源代码可以到上面下载。

但是在我的测试过程中,在nand flash上挂接的JFFS2文件系统很不稳定,经常有CRC错误产生。

特别是进行写操作的时候,每次复位都会产生CRC错误,可以说支持NAND flash的JFFS2文件系统目前还不成熟。

而YAFFS文件系统则是专门针对NAND flash的,源代码可以到/yaffs/index.html上下载。

在测试过程中稳定性能比JFFS2文件系统要稳定的多,而且mount分区的时间也比JFFS2文件系统少的多。

用JFFS2 mount一个2m的文件系统大约需要1s。

下面分别介绍在uclinux 下面使用JFFS2和YAFFS文件系统。

1、JFFS2到上面下载最新的MTD和JFFS2压缩包。

压缩包里面还有有关的内核补丁和一些MTD的相关工具。

主要的补丁就是ilookup-2.4.23.patch,因为最新的MTD驱动中要用到一个ilookup()函数。

打完补丁、更新了MTD驱动和JFFS2文件系统之后就开始写自己nand flash驱动了。

如果不想把JFFS2作为根文件系统的话,还需要修改MTD_BLOCK_MAJOR。

驱动可以参考里面的例子,最简单的就是参考spia.c。

写驱动主要工作是定义flash分区结构、定义flash读写地址、写控制flash 的**_hwcontrol()函数。

具体的操作要看所用的nand flash的芯片资料。

相对NOR flash来说驱动要简单多了。

:)改完之后再配置Memory Technology Devices(MTD)下CONFIG_MTD=YCONFIG_MTD_DEBUG=YCONFIG_MTD_DEBUG_VERBOSE=3CONFIG_MTD_PARTITIONS=YCONFIG_MTD_CHAR=YCONFIG_MTD_BLOCK=YNAND Flash Device Drivers下CONFIG_MTD_NAND=Y定义自己的驱动文件File systems下CONFIG_JFFS2_FS=YCONFIG_JFFS2_FS_DEBUG=2CONFIG_JFFS2_FS_NAND=y /*这个是新加的*/在uClinux v1.3.4 Configuration下Flash Tools下CONFIG_USER_MTDUTILS=YCONFIG_USER_MTDUTILS_ERASE=YCONFIG_USER_MTDUTILS_ERASEALL=YCONFIG_USER_MTDUTILS_MKFSJFFS2=Y最后就是辛苦了调试工作了。

Cramfs、JFFS2、YAFFS2的全面对比

Cramfs、JFFS2、YAFFS2的全面对比

Cramfs、JFFS2、YAFFS2的全面对比由于嵌入式系统自身存在一些特殊要求,使得一些传统的文件系统(如FAT、EXT2等) 并不十分适合。

专用的嵌入式文件系统应有一些自身的特性,如文件系统面对的储存介质特殊性、文件系统应具有的跨平台的安全性,以及整个系统的即时性等。

本文介绍了3种源码开放的嵌入式文件系统Cramfs、JFFS2、YAFFS2,详细分析比较了这3种文件系统的主要性能,并根据分析结果指出了各自的适用领域。

Cramfs、JFFS2、YAFFS2是3种性能优越,专用于嵌入式系统的文件系统。

本文通过对这3种文件系统的设计原理和主要性能进行分析与比较,归纳出各自的选型依据据和适用领域。

三种文件系统的介绍CramfsCramfs是Linux的创始人Linus T orvalds开发的一种只读文件系统,采用了zlib压缩,压缩比一般可以达到1:2,但仍可以做到高效的随机读取。

在Linux系统中,通常把不需要经常修改的目录压缩存放,在系统引导时再将压缩文件解开。

Cramfs并不需要一次性地把文件系统的所有内容都解压到记忆体中,而只是在系统需要访问某个位置的资料时,马上计算出该资料在Cramfs中的位置,将其解压缩到记忆体之中,然后通过对记忆体的访问来获取需要读取的资料。

JFFS2JFFS意为「Journaling Flash File System」,该文件系统是瑞典Axis通信公司开发的一种基于Flash记忆体的日志文件系统。

该公司于1999年在GNU/Linux上发行了第一版JFFS文件系统,后来经过Redhat公司的发展,现在已经发行了第二个版本的JFFS2,其全部程式码都是可供研究开发的。

它在设计时充分考虑了嵌入式系统中Flash 记忆体的读写特性,确保在系统掉电时,正在读写的文件不受影响;同时,其储存策略以及抗疲劳性等方面也在第一版的基础上进行了改进。

目前,JFFS2广泛应用于嵌入式系统中,尤其是嵌入式μClinux 作业系统中。

JFFS2文件系统分析报告

JFFS2文件系统分析报告

JFFS2文件系统分析报告本文在深入研究jffs2源代码基础上,对JFFS2文件系统的实现机制进行了分析,包括关键的数据结构及其之间的联系,文件系统的注册和挂载,以及其他主要的操作流程。

1 JFFS2层次结构在Linux系统中,JFFS2文件系统处于虚拟文件系统层VFS与存储技术设备层MTD之间,如图1所示。

VFS为内核中的各种文件系统提供一个统一的抽象层,并为上层用户提供具有统一格式的接口函数;MTD子系统整合底层芯片驱动,为上层文件系统提供了统一访问MTD设备(主要是NOR闪存和NAND闪存等设备)的接口。

JFFS2在内存中建立超级块信息jffs2_sb_info管理文件系统操作,建立索引节点信息jffs2_inode_info管理打开的文件。

VFS层的超级块super_block和索引节点inode分别包含JFFS2文件系统的超级块信息jffs2_sb_info和索引节点信息jffs2_inode_info,它们是JFFS2和VFS间通信的主要接口。

JFFS2文件系统的超级块信息jffs2_sb_info包含底层MTD设备信息mtd_info指针,文件系统通过该指针访问MTD设备,实现JFFS2和底层MTD设备驱动之间的通信。

图1 JFFS2文件系统层次2 JFFS2数据实体JFFS2在Flash上只存储两种类型的数据实体,分别为jffs2_raw_inode和jffs2_raw_ dirent。

■jffs2_raw_dirent:包括文件名、ino号、父节点ino号、版本号、校验码等信息,它用来形成整个文件系统的层次目录结构。

■jffs2_raw_inode:包括文件ino号、版本号、访问权限、修改时间、本节点所包含的数据文件中的起始位置及本节点所包含的数据大小等信息,它用来管理文件的所有数据。

一个目录文件由多个jffs2_raw_dirent组成。

而普通文件,符号链接文件,设备文件,FIFO文件等都由一个或多个jffs2_raw_inode数据实体组成。

嵌入式系统中常用的文件系统

嵌入式系统中常用的文件系统

嵌⼊式系统中常⽤的⽂件系统嵌⼊式系统中常⽤⽂件系统包括cramfs、jffs2、NFS、initrd、ext4、squashfs、ubifs等。

它们的特点如下:1、cramfs 和 jffs2 具有好的空间特性,很适合嵌⼊式产品应⽤。

2、cramfs 与 squashfs 为只读⽂件系统,⽬前只有 SPI Nor FLASH ⽀持这两种⽂件系统。

3、squashfs 压缩率最⾼。

4、jffs2 为可读写⽂件系统。

5、NFS ⽂件系统适⽤于开发初期的调试阶段。

6、initrd 采⽤ cramfs ⽂件系统,为只读。

7、ext4 ⽂件系统⽤于 eMMC 卡。

⼀、cramfscramfs 是针对 Linux 内核 2.4 之后的版本所设计的⼀种新型⽂件系统,使⽤简单,加载容易,速度快。

cramfs 的优点如下:1、将⽂件数据以压缩形式存储,在需要运⾏时进⾏解压缩,能节省 Flash 存储空间。

cramfs 的缺点如下:1、由于它存储的⽂件是压缩的格式,所以⽂件系统不能直接在 Flash 上运⾏。

2、⽂件系统运⾏时需要解压数据并拷贝到内存中,在⼀定程度上降低读取效率。

3、cramfs ⽂件系统是只读的。

⼆、jffs2jffs2 是 RedHat 的 David Woodhouse 在 jffs 基础上改进的⽂件系统,是⽤于微型嵌⼊式设备的原始闪存芯⽚的实际⽂件系统。

jffs2 ⽂件系统是⽇志结构化的可读写的⽂件系统。

jffs2 的优点如下:1、使⽤了压缩的⽂件格式。

最重要的特性是可读写操作。

jffs2 的缺点如下:1、jffs2 ⽂件系统挂载时需要扫描整个 jffs2 ⽂件系统,因此当 jffs2 ⽂件系统分区增⼤时,挂载时间也会相应的变长。

2、使⽤ jffs2 格式可能带来少量的 Flash 空间的浪费。

这主要是由于⽇志⽂件的过度开销和⽤于回收系统的⽆⽤存储单元,浪费的空间⼤⼩⼤致是若⼲个数据段。

3、jffs2 的另⼀缺点是当⽂件系统已满或接近满时,jffs2 运⾏速度会迅速降低。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JFFS2 文件系统及新特性介绍生赵复 (forrest.zhao@), 软件工程师,开源技术中心(OTC),Intel(China) Software Center简介: JFFS2 是一个开放源码的项目()。

它是在闪存上使用非常广泛的读/写文件系统,在嵌入式系统中被普遍的应用。

这篇文章首先分析了在闪存上使用 JFFS2 的必要性,然后详细的阐述了 JFFS2 实现的内部机制,包括日志结构的文件系统,关键的数据结构,挂载过程和垃圾收集机制。

同时也指出了 JFFS2 的局限性,并介绍了最新的针对 JFFS2 的不足进行改进的补丁程序。

最后对 JFFS3 的设计思想和现在的开发状况给予了简单的介绍。

标记本文!发布日期: 2005 年 12 月 22 日级别:初级访问情况 991 次浏览建议: 0 (添加评论)平均分(共 0 个评分)1.为什么需要 JFFS2这一小节首先介绍了闪存相对于磁盘介质的特别之处,然后分析了将磁盘文件系统运行在闪存上的不足,同时也给出了我们使用 JFFS2 的理由。

1.1 闪存(Flash Memory) 的特性和限制这里所介绍的闪存的特性和限制都是从上层的文件系统的角度来看的,而不会涉及到具体的物理特性。

总的来说,有两种类型的 flash memory: NOR flash 和NAND flash. 先介绍一下这两种闪存所具有的共同特性。

A) 闪存的最小寻址单位是字节(byte),而不是磁盘上的扇区(sector)。

这意味着我们可以从一块闪存的任意偏移(offset)读数据,但并不表明对闪存写操作也是以字节为单位进行的。

我们会在下面的阐述中找到答案。

B) 当一块闪存处在干净的状态时(被擦写过,但是还没有写操作发生),在这块flash上的每一位(bit)都是逻辑1。

C) 闪存上的每一位(bit)可以被写操作置成逻辑0。

可是把逻辑 0 置成逻辑 1 却不能按位(bit)来操作,而只能按擦写块(erase block)为单位进行擦写操作。

擦写块的大小从 4K 到128K 不等。

从上层来看,擦写所完成的功能就是把擦写块内的每一位都重设置(reset)成逻辑 1。

D) 闪存的使用寿命是有限的。

具体来说,闪存的使用寿命是由擦写块的最大可擦写次数来决定的。

超过了最大可擦写次数,这个擦写块就成为坏块(bad block)了。

因此为了避免某个擦写块被过度擦写,以至于它先于其他的擦写块达到最大可擦写次数,我们应该在尽量小的影响性能的前提下,使擦写操作均匀的分布在每个擦写块上。

这个过程叫做磨损平衡(wear leveling)。

NOR flash 与 NAND flash 的不同之处:A) NOR flash 读/写操作的基本单位是字节;而 NAND flash 又把擦写块分成页(page), 页是写操作的基本单位,一般一个页的大小是 512 或 2K 个字节。

对于一个页的重复写操作次数是有限制的,不同厂商生产的 NAND flash 有不同的限制,有些是一次,有些是四次,六次或十次。

B) 按照现在的技术水平,一般来说NOR flash擦写块的最大可擦写次数在十万次左右,NAND flash擦写块的最大可擦写次数在百万次左右。

1.2 闪存转换层将磁盘文件系统(ext2, FAT)运行在闪存上的很自然的方法就是在文件系统和闪存之间提供一个闪存转换层(Flash Translation Layer), 它的功能就是将底层的闪存模拟成一个具有 512字节扇区大小的标准块设备(block device)。

对于文件系统来说,就像工作在一个普通的块设备上一样,没有任何的差别。

图一一个闪存转换层的最简单的实现就是将模拟的块设备一对一的映射到闪存上。

举例来说,当上层的文件系统要写一个块设备的扇区时,闪存转换层要做下面的操作来完成这个写请求:1 将这个扇区所在擦写块地数据读到内存中,放在缓存(buffer)中2 将缓存中与这个扇区对应的内容用新的内容替换掉3 对该擦写块执行擦写操作4 将缓冲中的数据写回该擦写块这种实现方式的缺点是很明显的:1 效率低,对一个扇区的更新要重写整个擦写块上的数据,造成数据带宽很大的浪费。

2 没有提供磨损平衡,那些被频繁更新的数据所在擦写块将首先变成坏块。

3 非常不安全,很容易引起数据的丢失。

如果在上面的第三步和第四步之间发生了突然掉电(power loss),那么整个擦写块中的数据就全部丢失了。

这在突然掉电经常发生的嵌入式系统中是不能接受的。

MTD 中的内核模块 mtdblock 就是基于这种机制实现的,同时还作了一些优化。

只有当文件系统的写请求超过了一个擦写块的边界的时候,它才会执行对闪存的擦写,写回操作。

因此,为了解决上面这种实现方式的问题,闪存转换层需要做更多的事情。

闪存转换层不能只实现这种一对一的映射,而需要将模拟块设备的扇区存储在闪存的不同位置,并且维持扇区到闪存的映射关系。

更进一步,闪存转换层还必须能理解上层文件系统的语义,否则闪存转换层没办法做垃圾回收(Garbage Collection)。

这样实现最大的问题就是效率不高,具体来说,闪存转换层为了能理解上层文件系统的语义,必须对文件系统的每个写请求进行解析,这势必带来写操作性能的下降。

另外要求文件系统下面的一层去理解文件系统的语义,很显然这不是最好的解决方式。

我们还有很好的解决问题的方法,就是实现一个特别针对闪存的文件系统。

而 JFFS2 就是一个这样的文件系统。

2. JFFS2有 JFFS2 就要有 JFFS v1,没错,JFFS v1 最初是由瑞典的 Axis Communications AB 公司开发的,使用在他们的嵌入式设备中,并且在 1999 年末基于 GNU GPL 发布出来。

最初的发布版本基于 Linux 内核 2.0,后来 RedHat 将它移植到 Linux 内核 2.2,做了大量的测试和 bug fix 的工作使它稳定下来,并且对签约客户提供商业支持。

但是在使用的过程中,JFFS v1 设计中的局限被不断的暴露出来。

于是在 2001 年初的时候,RedHat 决定实现一个新的闪存文件系统,这就是现在的 JFFS2。

下面将详细介绍 JFFS2 设计中主要的思想,关键的数据结构和垃圾收集机制。

这将为我们实现一个闪存上的文件系统提供很好的启示。

首先,JFFS2 是一个日志结构(log-structured)的文件系统,包含数据和原数据(meta-data)的节点在闪存上顺序的存储。

JFFS2 之所以选择日志结构的存储方式,是因为对闪存的更新应该是 out-of-place 的更新方式,而不是对磁盘的 in-place 的更新方式。

在闪存上 in-place 更新方式的问题我们已经在闪存转换层一节描述过了。

2.1 节点头部定义和兼容性JFFS2 将文件系统的数据和原数据以节点的形式存储在闪存上,具体来说节点头部的定义如下:图二幻数屏蔽位:0x1985 用来标识 JFFS2 文件系统。

节点类型:JFFS2 自身定义了三种节点类型,但是考虑到文件系统可扩展性和兼容性,JFFS2从 ext2 借鉴了经验,节点类型的最高两位被用来定义节点的兼容属性,具体来说有下面几种兼容属性:JFFS2_FEATURE_INCOMPAT:当 JFFS2 发现了一个不能识别的节点类型,并且它的兼容属性是 JFFS2_FEATURE_INCOMPAT,那么 JFFS2 必须拒绝挂载(mount)文件系统。

JFFS2_FEATURE_ROCOMPAT:当 JFFS2 发现了一个不能识别的节点类型,并且它的兼容属性是 JFFS2_FEATURE_ROCOMPAT,那么 JFFS2 必须以只读的方式挂载文件系统。

JFFS2_FEATURE_RWCOMPAT_DELETE:当 JFFS2 发现了一个不能识别的节点类型,并且它的兼容属性是 JFFS2_FEATURE_RWCOMPAT_DELETE,那么在垃圾回收的时候,这个节点可以被删除。

JFFS2_FEATURE_RWCOMPAT_COPY:当 JFFS2 发现了一个不能识别的节点类型,并且它的兼容属性是 JFFS2_FEATURE_RWCOMPAT_COPY,那么在垃圾回收的时候,这个节点要被拷贝到新的位置。

节点总长度:包括节点头和数据的长度。

节点头部 CRC 校验:包含节点头部的校验码,为文件系统的可靠性提供了支持。

2.2 节点类型JFFS2 定义了三种节点类型:JFFS2_NODETYPE_INODE: INODE 节点包含了i-节点的原数据(i节点号,文件的组 ID, 属主 id, 访问时间,偏移,长度等),文件数据被附在 INODE 节点之后。

除此之外,每个 INODE 节点还有一个版本号,它被用来维护属于一个i-节点的所有 INODE 节点的全序关系。

下面举例来说明这个全序关系在 JFFS2 的使用:图三因此,当文件系统从闪存上读节点信息后,会生成下面的映射信息:图四根据这个映射信息表,文件系统就知道到相应的 INODE 节点去读取相应的文件内容。

最后要说明的是,JFFS2 支持文件数据的压缩存储,因此在 INODE 节点中还包含了所使用的压缩算法,在读取数据的时候选择相应的压缩算法来解压缩。

JFFS2_NODETYPE_DIRENT:DIRENT 节点就是把文件名与 i 节点对应起来。

在DIRENT节点中也有一个版本号,这个版本号的作用主要是用来删除一个dentry。

具体来说,当我们要从一个目录中删除一个 dentry 时,我们要写一个DIRENT 节点,节点中的文件名与被删除的 dentry 中的文件名相同,i 节点号置为 0,同时设置一个更高的版本号。

JFFS2_NODETYPE_CLEANMARKER:当一个擦写块被擦写完毕后,CLEANMARKER 节点会被写在 NOR flash 的开头,或 NAND flash 的 OOB(Out-Of-Band) 区域来表明这是一个干净,可写的擦写块。

在 JFFS v1 中,如果扫描到开头的 1K 都是0xFF 就认为这个擦写块是干净的。

但是在实际的测试中发现,如果在擦写的过程中突然掉电,擦写块上也可能会有大块连续 0xFF,但是这并不表明这个擦写块是干净的。

于是我们需要 CLEANMARKER 节点来确切的标识一个干净的擦写块。

2.3 JFFS2节点,擦写块在内存中的表示和操作JFFS2 维护了几个链表来管理擦写块,根据擦写块上的内容,一个擦写块会在不同的链表上。

具体来说,当一个擦写块上都是合法(valid)的节点时,它会在clean_list 上;当一个擦写块包含至少一个过时(obsolete)的节点时,它会在dirty_list 上;当一个擦写块被擦写完毕,并被写入 CLEANMARKER 节点后,它会在 free_list 上。

相关文档
最新文档