在STM32上实现NTFS之1:NTFS初识与准备工作
先声明一下关于版权的问题,NTFS是Microsoft公司的知识产权产品!我本人是本着学习与研究的态度对其进行分析的,以便于更好的理解数据存储技术。所查阅的所有资料,也都是网上甚至是MSDN自己公开的东西,没有逆向成分在里面,如果Microsoft公司,或者其他我引用资料的原作者发现我照搬了研究成果,请及时私信给我,我将立即删除相关信息,谢谢!
版权交代完了,接下来我们开始研究技术:
NTFS (New Technology File System),是 WindowsNT 环境的文件系统。新技术文件系统是Windows NT家族(如,Windows 2000、Windows XP、Windows Vista、Windows 7和 windows 8.1)等的限制级专用的文件系统(操作系统所在的盘符的文件系统必须格式化为NTFS的文件系统,4096簇环境下)。NTFS取代了老式的FAT文件系统。
NTFS对FAT和HPFS作了若干改进,例如,支持元数据,并且使用了高级数据结构,以便于改善性能、可靠性和磁盘空间利用率,并提供了若干附加扩展功能……
有关于NTFS的优点很多,比如更大的单一分区,更大的文件大小,单一目录的更多文件数之类的。但如果只有这些,微软的天才们是没有必要单独研发一种文件系统的,FAT64就够了,如果64不够,也许还会出现FAT128,FAT256,NTFS的优点主要体现在可靠、安全和高效几个方面;
- NTFS是一个可恢复的文件系统。在NTFS分区上用户很少需要运行磁盘修复程序。NTFS通过使用标准的事物处理日志和恢复技术来保证分区的一致性。发生系统失败事件时,NTFS使用日志文件和检查点信息自动恢复文件系统的一致性;
- NTFS支持对分区、文件夹和文件的压缩。任何基于Windows的应用程序对NTFS分区上的压缩文件进行读写时不需要事先由其他程序进行解压缩,当对文件进行读取时,文件将自动进行解压缩;文件关闭或保存时会自动对文件进行压缩;
- NTFS采用了更小的簇,可以更有效率地管理磁盘空间。在Win 2000的FAT32文件系统的情况下,分区大小在2GB~8GB时簇的大小为4KB;分区大小在8GB~16GB时簇的大小为8KB;分区大小在16GB~32GB时,簇的大小则达到了16KB。而Win 2000的NTFS文件系统,当分区的大小在2GB以下时,簇的大小都比相应的FAT32簇小;当分区的大小在2GB以上时(2GB~2TB),簇的大小都为4KB。相比之下,NTFS可以比FAT32更有效地管理磁盘空间,最大限度地避免了磁盘空间的浪费;
- 在NTFS分区上,可以为共享资源、文件夹以及文件设置访问许可权限。许可的设置包括两方面的内容:一是允许哪些组或用户对文件夹、文件和共享资源进行访问;二是获得访问许可的组或用户可以进行什么级别的访问。访问许可权限的设置不但适用于本地计算机的用户,同样也应用于通过网络的共享文件夹对文件进行访问的网络用户。与FAT32文件系统下对文件夹或文件进行访问相比,安全性要高得多。另外,在采用NTFS格式的Win 2K以上OS中,应用审核策略可以对文件夹、文件以及活动目录对象进行审核,审核结果记录在安全日志中,通过安全日志就可以查看哪些组或用户对文件夹、文件或活动目录对象进行了什么级别的操作,从而发现系统可能面临的非法访问,通过采取相应的措施,将这种安全隐患减到最低。这些在FAT32文件系统下,是不能实现的;
- 在Win 2K以上的NTFS文件系统下可以进行磁盘配额管理。磁盘配额就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。设置磁盘配额后,可以对每一个用户的磁盘使用情况进行跟踪和控制,通过监测可以标识出超过配额报警阈值和配额限制的用户,从而采取相应的措施。磁盘配额管理功能的提供,使得管理员可以方便合理地为用户分配存储资源,避免由于磁盘空间使用的失控可能造成的系统崩溃,提高了系统的安全性。
- NTFS使用一个“变更”日志来跟踪记录文件所发生的变更。
如果对以上几点不甚了解,那么我简单说几点个人看法吧:第一个是压缩解压缩问题,对于我们的深度嵌入式系统来讲,还是不压缩的好,虽然是NTFS自带的压缩,但也要占用CPU进行压缩/解压,但这个特性,使得我们可以灵活的把NTFS部署在高CPU性能+低磁盘性能或低CPU性能+高磁盘性能的地方;第二点就是恢复问题了,在深度嵌入式系统中,很可能没有OS,或只使用RTOS(UCOS1,2,3、FreeRTOS、Vxworks、RTthread等等),这就对系统数据操作的完备性提出了考验。毫无疑问,NTFS的自恢复特性比FAT文件系统有很大优势,而且,NTFS的日志对于非预期的事故有很好的作用,比如断点、意外复位等,在事件结束前NTFS不会记录事件,这样我们的系统在重新启动过程中可以检测到上一次的故障位置,而继续上次的操作,最大程度降低了破坏性;第三点就是效率问题了,NTFS有很多属性,属性,属性,属性……在载入一个NTFS文件的时候已经直接读取了一个文件的属性,甚至包括文件是否被删除或不存在,而FAT文件系统的读取方式是文件分配表——链式检索——访问文件。
但NTFS的缺点和优点正是相对存在的,NTFS最致命的地方在于他是给高性能CPU准备的而并非只有几十到几百MPS的MCU,这导致了NTFS的读写周期将会长的不可想象,不过好在——NTFS由我们来实现,我们可以通过设置一系列的宏开关来决定我们的精简化NTFS要不要磁盘配额,要不要压缩,要不要每次读写时检查扇区是否正确(当然了这个不检查会比较危险),等等。
我们的目标是:在MCU、ARM、DSP或SoC平台上正常读写NTFS格式的移动存储介质,如SD卡。
图1 SD卡格式化成NTFS格式
NTFS的基础讲完了,下面讲一下准备工作,我们的准备工作需要两大类:硬件和软件。
我用ANSI C实现NTFS的初衷是让我的STM32F103能够读取NTFS格式的文件,所以硬件上,我们需要一张SD卡,如下图,我的是8GB的TF卡和SD卡各一张。还需要一个深度嵌入式开发平台。之前反复的提到“深度嵌入式”,那么什么是深度嵌入式呢?我在这里是将它与一般嵌入式做区分的标志,一般的嵌入式系统,比如Linux,WinCE,其中可以直接嵌入NTFS的插件,或自带NTFS,是没有必要让我们自己实现NTFS的,只有那些层次更深的嵌入式,比如RTOS中,我们写的NTFS作为一个文件系统的库插入,才能提到显著的性能、安全性的提高。
在硬件平台这,我用的是曾经做过的一个产品的板子,主MCU是STM32F103ZET6,这个板子设计的时候考虑了硬件兼容,可以直接换成F407Z系列的,当然现在还是ZET6,后面如果NTFS跑不起来,再换F407。板子上有一个34针的液晶屏口,两个LED,一个RTC,一个TF卡插槽,一个TTL电平的串口,这些外设已经足够搞很多事情了。
软件方面,磁盘工具我用的是DiskGenius V4.9.1.334 x64专业版,磁盘数据读取软件用的是WinHEX 14,STM32开发环境是Keil MDK 5.21a,因为NTFS不一定要开发多久,所以直接下载到STM32是不太可能的,费时费力还费芯片,所以需要一个PC机的C语言IDE,我用的是CodeBlocks编辑器+MinGW编译器。
工具基本都备齐了,本章的内容到此也就结束了。
下一节介绍磁盘系统的一些基础和NTFS的框架。