福州大学操作系统实验报告-文件系统的构建

合集下载

操作系统文件管理实验报告

操作系统文件管理实验报告

操作系统文件管理实验报告操作系统文件管理实验报告一、实验目的操作系统是计算机系统中的核心软件之一,负责管理计算机硬件资源和提供用户与计算机硬件之间的接口。

文件管理是操作系统的重要功能之一,它涉及到文件的创建、读取、写入、删除等操作。

本次实验旨在通过编写简单的文件管理程序,加深对操作系统文件管理机制的理解。

二、实验环境本次实验使用C语言编写,运行在Linux操作系统上。

实验过程中使用了gcc 编译器和Linux系统提供的文件管理函数。

三、实验内容1. 文件的创建在操作系统中,文件是存储在存储介质上的数据集合。

文件的创建是指在存储介质上分配一块空间,并为其分配一个唯一的文件名。

在本次实验中,我们使用了Linux系统提供的open函数来创建文件。

open函数接受两个参数,第一个参数是文件名,第二个参数是文件的打开模式。

通过调用open函数,我们可以在指定的路径下创建一个文件。

2. 文件的读取和写入文件的读取和写入是文件管理的核心操作。

在本次实验中,我们使用了Linux 系统提供的read和write函数来实现文件的读取和写入。

read函数接受三个参数,第一个参数是文件描述符,第二个参数是存储读取数据的缓冲区,第三个参数是要读取的数据的长度。

write函数也接受三个参数,第一个参数是文件描述符,第二个参数是要写入的数据的缓冲区,第三个参数是要写入的数据的长度。

通过调用read和write函数,我们可以实现对文件的读取和写入操作。

3. 文件的删除文件的删除是指在存储介质上释放文件占用的空间,并删除文件的相关信息。

在本次实验中,我们使用了Linux系统提供的unlink函数来删除文件。

unlink函数接受一个参数,即要删除的文件名。

通过调用unlink函数,我们可以删除指定的文件。

四、实验步骤1. 创建文件首先,我们使用open函数创建一个文件。

在调用open函数时,需要指定文件的路径和文件的打开模式。

文件的路径可以是绝对路径或相对路径,文件的打开模式可以是只读、只写、读写等。

操作系统-第四次实验报告-文件系统

操作系统-第四次实验报告-文件系统
操作系统实验报告 文件系统
全部代码可执行
实验介绍
本实验要求在假设的I/O 系统之上开发一个简单的文件系统, 这样做既能让实验者对文 件系统有整体了解,又避免了涉及过多细节。用户通过create, open, read 等命令与文件系统 交互。文件系统把磁盘视为顺序编号的逻辑块序列,逻辑块的编号为0 至L-1。I/O 系统利 用内存中的数组模拟磁盘。 实际物理磁盘的结构是多维的:有柱面、磁道、扇区等概念。I/O 系统的任务是隐藏磁 盘的结构细节,把磁盘以逻辑块的面目呈现给文件系统。逻辑块顺序编号,编号取值范围为 0 至L -1,其中L 表示磁盘的存储块总数。实验中,我们可以利用字符数组ldisk[L][B] 构 建磁盘模型,其中B 表示每个存储块的长度。I/O 系统从文件系统接收命令,根据命令指定 的逻辑块号把磁盘块的内容读入命令指定的内存区域, 或者把命令指定的内存区域内容写入 磁盘块。内存区域内容写入磁盘块。
整体组织
注:我定义的文件系统中,磁盘分为两大部分:数据区和保留区。其中保留区中又包含位图区和文件 描述符区,数据区的首部是文件的目录项,也就是说,文件的目录项在文件创建时会创建相应的目录 项在数据区的文件首部;而位图区用于表征数据的占用情况,例如数据区的第 N 块被分配了,那么位 图区中也要做相应的改变。
struct filesign { int file_length; int filesign_flag; int file_block;
int file_block_ary[FILE_BLOCK_LENGTH]; }; struct contents { char filename[FILE_NAME_LENGTH];
文件的读 int read(int,int,int)

文件系统设计实验报告

文件系统设计实验报告

文件系统设计实验报告文件系统设计实验报告一、引言在计算机科学领域,文件系统是操作系统中的一个重要组成部分,用于管理和组织计算机存储设备上的文件和目录。

一个高效稳定的文件系统对于计算机系统的正常运行至关重要。

本实验旨在设计一个简单但功能完善的文件系统,并通过实验验证其性能和可靠性。

二、实验背景文件系统是计算机操作系统的核心组成部分之一,它负责管理计算机存储设备上的文件和目录。

一个好的文件系统应该具备以下特点:高效的文件存取速度、可靠的数据完整性、良好的扩展性和灵活性。

三、实验目标本实验的主要目标是设计一个简单但功能完善的文件系统,并通过实验验证其性能和可靠性。

具体而言,我们将实现以下功能:1. 文件的创建、读取、写入和删除。

2. 目录的创建、删除和遍历。

3. 文件和目录的权限管理。

4. 文件系统的容量管理。

5. 文件系统的备份和恢复。

四、实验设计与实现1. 文件和目录的创建、读取、写入和删除在文件系统中,文件和目录都是通过数据块来存储的。

我们可以使用链表或树的数据结构来组织文件和目录之间的关系。

为了提高文件的读取和写入效率,可以采用缓存机制,将最近访问的文件块缓存在内存中。

2. 目录的创建、删除和遍历目录是文件系统中用于组织和管理文件的一种特殊文件。

为了实现目录的创建、删除和遍历功能,我们可以使用树的数据结构来表示目录结构,并通过递归算法来实现目录的遍历。

3. 文件和目录的权限管理为了保护文件和目录的安全,我们可以为每个文件和目录设置权限。

权限可以分为读、写和执行三种类型。

通过权限管理,可以限制用户对文件和目录的操作,提高文件系统的安全性。

4. 文件系统的容量管理文件系统的容量管理是指对文件和目录所占用的存储空间进行管理。

为了有效利用存储空间,我们可以使用位图或链表等数据结构来管理存储空间的分配和释放。

5. 文件系统的备份和恢复为了保证文件系统的可靠性,我们可以定期对文件系统进行备份。

备份可以通过复制文件和目录的数据块来实现。

《操作系统》实验报告

《操作系统》实验报告

《操作系统》实验报告一、实验目的操作系统是计算机系统中最为关键的组成部分之一,本次实验的主要目的是深入理解操作系统的基本原理和功能,通过实际操作和观察,熟悉操作系统的核心概念,包括进程管理、内存管理、文件系统和设备管理等,提高对操作系统的实际应用能力和问题解决能力。

二、实验环境本次实验在以下环境中进行:操作系统:Windows 10开发工具:Visual Studio 2019编程语言:C++三、实验内容1、进程管理实验进程是操作系统中最基本的执行单元。

在这个实验中,我们使用C++编写程序来创建和管理进程。

通过观察进程的创建、执行和结束过程,理解进程的状态转换和资源分配。

首先,我们编写了一个简单的程序,创建了多个子进程,并通过进程标识符(PID)来跟踪它们的运行状态。

然后,使用等待函数来等待子进程的结束,并获取其返回值。

在实验过程中,我们发现进程的创建和销毁需要消耗一定的系统资源,而且进程之间的同步和通信需要谨慎处理,以避免出现死锁和竞争条件等问题。

2、内存管理实验内存管理是操作系统的核心功能之一,它直接影响系统的性能和稳定性。

在这个实验中,我们研究了动态内存分配和释放的机制。

使用 C++中的 new 和 delete 操作符来分配和释放内存。

通过观察内存使用情况和内存泄漏检测工具,了解了内存分配的效率和可能出现的内存泄漏问题。

同时,我们还探讨了内存分页和分段的概念,以及虚拟内存的工作原理。

通过模拟内存访问过程,理解了页表的作用和地址转换的过程。

3、文件系统实验文件系统是操作系统用于管理文件和目录的机制。

在这个实验中,我们对文件的创建、读写和删除进行了操作。

使用 C++的文件流操作来实现对文件的读写。

通过创建不同类型的文件(文本文件和二进制文件),并对其进行读写操作,熟悉了文件的打开模式和读写方式。

此外,还研究了文件的权限设置和目录的管理,了解了如何保护文件的安全性和组织文件的结构。

4、设备管理实验设备管理是操作系统与外部设备进行交互的桥梁。

操作系统实验-文件系统设计

操作系统实验-文件系统设计

操作系统实验-文件系统设计文件系统设计1.目的和要求本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。

实验要求:①在系统中用一个文件来模拟一个磁盘;②此系统至少有:Create、delete、open、close、read、write 等和部分文件属性的功能。

③实现这个文件系统。

④能实际演示这个文件系统。

基本上是进入一个界面(此界面就是该文件系统的界面)后,可以实现设计的操作要求。

2.实验内容1)设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。

2)程序采用二级文件目录(即设置主目录MFD)和用户文件目录(UFD)。

另外,为打开文件设置了运行文件目录(AFD)。

3)为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。

4)因系统小,文件目录的检索使用了简单的线性搜索。

5)文件保护简单使用了三位保护码:允许读写执行、对应位为1,对应位为0,则表示不允许读写、执行。

6)程序中使用的主要设计结构如下:主文件目录和用户文件目录(MFD、UFD),打开文件目录(AFD)即运行文件目录。

3.实验环境VC 6.04.实验提示1) format 格式化只写打开模拟文件,初始化超级快,初始化dinode 位图 block 位图,初始化主目录,初始化etc 目录,初始化管理员admin 目录,初始化用户xiao 目录,初始化用户passwd 文件,写入模拟硬盘文件。

2 )install 安装读写打开模拟文件,读取dinode 位图 block 位图,读取主目录,读取etc 目录,读取管理员admin 目录,读取用户xiao 目录,读取用户passwd 文件。

3 )login 登陆用户输入用户名和密码,在passwd 文件中查找是否有此用户,核对密码。

正确则登陆成功,当前目录设定到当前用户文件夹下。

Login登录结束是,登录成功输入用户名查找是否有改用户名输入密码是否密码是否正确否4 )ialloc 申请inode 空间先检测inode 位图是否加锁,是则退出。

文件系统的构建实验报告

文件系统的构建实验报告

文件系统的构建实验报告 实验名称:文件系统的构建实验目的:掌握磁盘的工作原理和操作系统进行文件管理的原理实验原理:硬盘的MBR :MBR (Main Boot Record ),按其字面上的理解即为主引导记录区,位于整个硬盘的0磁道0柱面1扇区。

在总共512字节的主引导扇区中,MBR 只占用了其中的446个字节(偏移0000--偏移01BD ),另外的64个字节(偏移01BE--偏移01FD )交给了DPT(Disk Partition Table 硬盘分区表),最后两个字节"55,AA"(偏移01FE- 偏移01FF )是分区的结束标志。

这个整体构成了硬盘的主引导扇区。

硬盘依据分区表中的信息把硬盘划分为最多四个分区(对于扩展分区,可进一步划分为多个逻辑分区)。

U 盘采用类似的方法划分分区。

每个分区或软盘上可建立独立的文件系统。

下图是FAT 文件系统空间分布结构。

实验内容:在掌握磁盘的工作原理和操作系统进行文件管理原理的基础上,自行设计实现在磁盘上建立文件系统的软件,该软件应该具有与Format 类似的功能,至少支持一种文件系统格式,如FAT 、NTFS 或EXT2,至少能够对一种媒体进行格式化,如软盘,U 盘或硬盘(不得在实验室的机器上进行硬盘格式化的实验)等。

不能直接调用操作系统提供的格式化工具或类似SHFormatDrive ()的高层系统函数实现该软件。

在Windows 环境可使用biosdisk()函数完成底层盘操作,在Linux 环境上可参考format 的源代码。

比较自己设计实现的软件.与FORMAT ,分析存在什么异同。

背景知识介绍 一个分区或磁盘能作为文件系统使用前,需要初始化,并将记录数据结构写到磁盘上。

这个过程就叫建立文件系统。

大部分linux 文件系统种类具有类似的通用结构。

其中心概念是超级块superblock, i 节点inode, 数据块data block,目录块directory block, 和间接块indirection block 。

操作系统课程设计-文件管理实验报告

操作系统课程设计-文件管理实验报告

操作系统课程实验报告2013~2014年度第1学期院系:学号:姓名:任课教师:成绩评定:实验一题目:文件管理完成日期:年月日1、实验目的了解文件管理的功能和任务,理解文件系统组成和特点,熟悉文件系统的访问和操作。

实验要求用高级语言编写和调试一个简单的模拟文件管理程序。

加深理解有关盘块的分配与回收、目录管理等的具体实施策略。

2.、实验内容模拟一个资源管理器进行文件操作,包括建立和删除目录、建立和删除文件等基本文件操作。

建立相应的数据结构(如:位示图等),模拟盘块管理。

可以参照图6界面进行设计。

3、算法设计1)、定义主面板MainFrame,布局好各个控件,并初始化/** 往node节点下添加一个子节点obj;*/public void addChild(Object obj, DefaultMutableTreeNode node) {if (obj != null && node != null) {DefaultMutableTreeNode temp = new DefaultMutableTreeNode(obj);if (node.getAllowsChildren())node.add(temp);if(!((String) obj).equals("A:\\") && ((String) obj).length() <= 3)// 防止读取A软驱,会出现异常;用于初始用的;addChildren(cmd.listAll((String) obj), temp);}}/** 在node节点下添加数组children;*/public void addChildren(String[] children, DefaultMutableTreeNode node) { if (children != null && node != null) {for (int i = 0; i < children.length; i++) {addChild(children[i], node);}}}/** 对树的节点进行预提取;*/public void addPrefetchChildren(String path, DefaultMutableTreeNode node) { addChildren(cmd.listDirectory(path), node);}/** 对路径路径进行连接;(已经获得了所有的整个路径,需要量转化)*/public String toFilePath(String str) {// 先去掉头尾的[];String pa = str.substring(1, str.length() - 1);String[] temp = pa.split(", ");String path = "";for (int i = 1; i < temp.length; i++) {if (!path.endsWith("\\") && !path.equals(""))// 不为空是为去根节点;path += "\\";path += temp[i];}return path;}public String toPFilePath(String str) {// 先去掉头尾的[];String pa = str.substring(1, str.length() - 1);String[] temp = pa.split(", ");String path = "";for (int i = 1; i < temp.length - 1; i++) {if (!path.endsWith("\\") && !path.equals(""))// 不为空是为去根节点;path += "\\";path += temp[i];}return path;}public class ExpandListener implements TreeWillExpandListener {/** 树展开及收缩监听;*/private MainFrame mainFrame = null;public ExpandListener(MainFrame mainFrame) {this.mainFrame = mainFrame;}public void treeWillExpand(TreeExpansionEvent event) {// 对节点的路径进行转化String path = toFilePath(event.getPath().toString());TreePath treePath = event.getPath();DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent();// System.out.println("所展开节点的路径:" + path);// System.out.println(treePath);if (node.getDepth() < 2) {Enumeration children = node.children();String filePath = "";while (children.hasMoreElements()) {DefaultMutableTreeNode temp = (DefaultMutableTreeNode) children.nextElement();filePath = "";filePath = path;if (!filePath.endsWith("\\"))filePath += "\\";filePath += temp.toString();// System.out.println("temp=" +filePath);mainFrame.addPrefetchChildren(filePath, temp);}}}2)、添加功能“添加文件(夹)addframe()”、“修改文件(夹)mvframe()”public void addframe() {JFrame addFrame = new JFrame();JLabel jlbl = new JLabel("请输入要添加的文件(夹)名:");addrs = new JLabel("");addrs.setBounds(180, 10, 100, 25);jlbl.setBounds(10, 10, 170, 25);addfile = new JTextField();addfile.setBounds(10, 40, 260, 25);btnaddf = new JButton("添加文件");btnaddd = new JButton("添加文件夹");btnaddf.setBounds(20, 80, 100, 25);btnaddd.setBounds(160, 80, 100, 25);btnaddf.addActionListener(this);btnaddd.addActionListener(this);addFrame.add(jlbl);addFrame.add(addrs);addFrame.add(addfile);addFrame.add(btnaddf);addFrame.add(btnaddd);addFrame.setBounds(400, 350, 300, 150);addFrame.setTitle("添加文件(夹)");addFrame.setLayout(null);addFrame.setVisible(true);}public void mvframe() {JFrame mvFrame = new JFrame();JLabel jlbl = new JLabel("请输入修改后的文件名:");mvrs = new JLabel("");mvrs.setBounds(160, 10, 140, 25);jlbl.setBounds(10, 10, 170, 25);mvfile = new JTextField();mvfile.setBounds(10, 40, 260, 25);btnmvf = new JButton("修改文件名");btnmvd = new JButton(" 修改文件夹名");btnmvf.setBounds(10, 80, 120, 25);btnmvd.setBounds(150, 80, 120, 25);btnmvf.addActionListener(this);btnmvd.addActionListener(this);mvFrame.add(jlbl);mvFrame.add(mvrs);mvFrame.add(mvfile);mvFrame.add(btnmvf);mvFrame.add(btnmvd);mvFrame.setBounds(400, 350, 300, 150);mvFrame.setTitle("修改文件(夹)名");mvFrame.setLayout(null);mvFrame.setVisible(true);}}3)显示文件* 显示系统中的所有盘符;public String[] ListDisks() {File roots[] = File.listRoots();// 根盘符;String disks[] = new String[roots.length];for (int i = 0; i < roots.length; i++) {disks[i] = roots[i].toString();}return disks;}* 获得路径path下的文件;public String[] listAll(String path) {try {File f = new File(path);String[] fileName;String tmp = null;mainFrame.fileshow.setText(null);mainFrame.filestyle.setText(null);if (f.isDirectory()) {fileName = f.list();// System.out.println("共有" + fileName.length + "个文件");for (int i = 0; i < fileName.length; i++) {mainFrame.fileshow.append(fileName[i] + '\n');tmp = path + '\\' + fileName[i];// System.out.println(tmp);if (listDirectory(tmp) != null) {mainFrame.filestyle.append("文件夹\n");} else {mainFrame.filestyle.append("文件\n");}}return fileName;} else if (f.isFile()) {System.out.println("这是一个文件");return null;} else {// System.out.println(path);return null;}} catch (Exception e) {return null;}}public String[] listDirectory(String path) {File f = new File(path);String[] fileName;if (f.isDirectory()) {fileName = f.list();return fileName;} else {// System.out.println(path + "是文件");return null;}}* 进行md操作;md <目录名> 功能: 创建新目录public void md(String directory) {if (!mainFrame.currentPath.equals("")) {String temp = mainFrame.currentPath + "\\" + directory;File newFile = new File(temp);if (!newFile.exists()) {try {if (newFile.isDirectory() == false) {newFile.mkdirs();System.out.println("文件夹创建成功!");} else {System.out.println("文件夹创建出错!");}} catch (Exception e) {System.out.println("出错信息:" + e.getMessage());}} else {System.out.println("文件夹已经存在");}}}* 进行rd操作;rd <目录名> 功能: 删除目录;public void del() {String temp = mainFrame.currentPath;File file = new File(temp);if (file.exists()) {if (file.delete()) {mainFrame.fileshow.setText("文件(夹)删除成功!");} else {mainFrame.fileshow.setText("文件(夹)删除操作出错!");}} else {mainFrame.fileshow.setText("文件(夹)不存在");}}/** 进行edit操作:edit <文件名> 功能: 新建文件*/public void edit(String file) {if (!mainFrame.currentPath.equals("")) {String temp = mainFrame.currentPath + "\\" + file;File newFile = new File(temp);if (newFile.exists()) {mainFrame.addrs.setText("文件已经存在!");System.out.println("文件已经存在!");} else {try {newFile.createNewFile();mainFrame.addrs.setText("文件创建成功!");System.out.println("文件创建成功!");} catch (Exception e) {System.out.println("文件创建失败:" + e.getMessage());}}}}public void mvf(String file){if (!mainFrame.PPath.equals("")) {String temp = mainFrame.PPath + "\\" + file;File newFile = new File(mainFrame.currentPath);if (newFile.exists()) {if(newFile.renameTo(new File(temp))==true){mainFrame.mvrs.setText("修改文件名成功!");}else{mainFrame.mvrs.setText("存在同名文件!");}}}}public void mvd(String dir){if (!mainFrame.PPath.equals("")) {String temp = mainFrame.PPath + "\\" + dir;File newFile = new File(mainFrame.currentPath);if (newFile.exists()) {if(newFile.renameTo(new File(temp))==true){mainFrame.mvrs.setText("修改文件夹名成功!");}else{mainFrame.mvrs.setText("存在同名文件夹!");}}}}}4、运行与测试运行时,弹出主界面双击文件盘C在E盘路径添加文件夹操作系统,再添加文件操作系统如果文件已存在会显示可以更改文件名称删除文件,不过有个BUG,要文件一层层删,才可以删除。

操作系统文件管理实验报告

操作系统文件管理实验报告

操作系统文件管理实验报告操作系统文件管理实验报告1:引言本实验报告旨在详细描述操作系统文件管理实验的设计、实施和结果。

文件管理是操作系统的重要组成部分,负责对计算机中的文件进行组织、存储和访问。

本实验通过模拟文件管理的过程,加深对文件管理的理解和实践。

2:实验目的本实验的主要目的是:- 理解文件系统的概念和原理- 掌握文件的创建、读取、写入和删除等基本操作- 实施并测试文件的分配和回收算法- 评估不同的文件分配算法对系统性能的影响3:实验环境本实验的实施环境如下:- 操作系统:Windows 10- 开发环境:C++ 编程语言4:实验内容4.1 文件系统设计在文件系统设计中,首先确定文件的基本单位,例如块或扇区。

然后,定义文件控制块(FCB)结构,用于存储文件的元数据信息,如文件名、大小、创建时间、权限等。

接下来,设计文件分配表,记录系统中每个块的使用情况,用于实现文件的分配和回收。

4.2 文件的创建和删除在文件的创建过程中,首先为文件分配空间,并更新文件分配表。

然后,创建文件的FCB,并将其到目录项中。

在文件的删除过程中,首先释放文件的空间,并更新文件分配表。

然后,删除文件的FCB,并从目录项中移除。

4.3 文件的读写操作文件的读写操作是用户对文件进行读取和修改的过程。

在文件读取操作中,首先找到要读取的文件的FCB,获取文件的起始块地址,并从起始块中读取数据。

在文件写入操作中,首先找到要写入的文件的FCB,获取文件的起始块地址,并将数据写入起始块。

若文件大小超过起始块的容量,则按照一定的分配算法继续分配空间。

4.4 文件分配算法文件分配算法决定了操作系统如何管理文件的空间分配。

常用的文件分配算法包括顺序分配、分配和索引分配。

顺序分配将文件连续地存储在磁盘上,易于实现但可能产生外部碎片。

分配使用链表结构将文件存储在磁盘的不连续块中,不易产生外部碎片但可能引起存取时间增长。

索引分配使用索引表将文件存储在磁盘的不连续块中,不易产生外部碎片且存取时间相对较短,但索引表本身需要占用存储空间。

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

计算机操作系统实验三【实验名称】:文件系统的构建(实验3)【实验目的】:掌握磁盘的工作原理和操作系统进行文件管理的原理 【实验原理】:硬盘的MBR :MBR (Main Boot Record ),按其字面上的理解即为主引导记录区,位于整个硬盘的0磁道0柱面1扇区。

在总共512字节的主引导扇区中,MBR 只占用了其中的446个字节(偏移0000--偏移01BD ),另外的64个字节(偏移01BE--偏移01FD )交给了DPT(Disk Partition Table 硬盘分区表),最后两个字节"55,AA"(偏移01FE- 偏移01FF )是分区的结束标志。

这个整体构成了硬盘的主引导扇区。

大致的结构如图所示:硬盘依据分区表中的信息把硬盘划分为最多四个分区(对于扩展分区,可进一步划分为多个逻辑分区)。

U 盘采用类似的方法划分分区。

每个分区或软盘上可建立独立的文件系统。

下图是FAT 文件系统空间分布结构。

【实验内容】:在掌握磁盘的工作原理和操作系统进行文件管理原理的基础上,自行设计实现在磁盘上建立文件系统的软件,该软件应该具有与Format 类似的功能,至少支持一种文件系统格式,如FAT 、NTFS 或EXT2,至少能够对一种媒体进行格式化,如软盘,U 盘或硬盘(不得在实验室的机器上进行硬盘格式引导扇区FA T1FAT2根目录区文件数据区化的实验)等。

不能直接调用操作系统提供的格式化工具或类似SHFormatDrive ()的高层系统函数实现该软件。

在Windows环境可使用biosdisk()函数完成底层盘操作,在Linux环境上可参考format的源代码。

比较自己设计实现的软件与FORMAT,分析存在什么异同。

一、背景知识使用“DOC分区”体系时,磁盘的第一个——也就是0号扇区被称为主引导记录扇区,也称为主引导记录MBR(Master Boot recorder,MBR)。

1、MBR数据结构MBR由446个字节的引导代码、64字节的主分区(4个)表及两个字节的“55 AA”是分区的结束标志。

FAT文件系统的整体布局2、说明【1】保留区含有一个重要的数据结构——系统引导扇区(DBR)。

FAT12、FAT16的保留区通常只有一个扇区,而FAT32的保留扇区要多一些,除0号扇区外,还有其他一些扇区,其中包括了DBR的备份扇区。

【2】 FAT区由来年各个大小相等的FAT表组成——FAT1、FAT2,FAT2紧跟在FAT1之后。

【3】 FAT12、FAT16的根目录虽然也属于数据区,但是他们并不由簇进行管理。

也就是说FAT12、FAT16的根目录是没有簇号的,他们的2号簇从根目录之后开始。

而FAT32的根目录通常位于2号簇。

3、典型的FAT32_DBR【1】0x00~0x02:3个字节,跳转指令。

【2】0x03~0x0A:8个字节,文件系统标志和版本号,这里为MSDOC5.0。

【3】0x0B~0x0C:2个字节,每扇区字节数,512(0X02 00)。

【4】0x0D~0x0D:1个字节,每簇扇区数,8(0x08)。

【5】0x0E~0x0F:2个字节,保留扇区数,2050(0x0802)。

【6】0x10~0x10:1个字节,FAT表个数,2。

【7】0x11~0x12:2个字节,根目录最多可容纳的目录项数,FAT12/16通常为512。

FAT32不使用此处值,置0。

【8】0x13~0x14:2个字节,扇区总数,小于32MB时使用该处存放。

超过32MB时使用偏移0x20~0x23字节处的4字节存放。

笔者的SD卡容量为2GB,所以不使用该处,置0.【9】0x15~0x15:1个字节,介质描述符,0xF8表示本地硬盘。

【10】0x16~0x17:2个字节,每个FAT表的大小扇区数(FAT12/16使用,FAT32不使用此处,置0)。

【11】0x18~0x19:2个字节,每磁道扇区数,63(0x00 3F)。

【12】0x1A~0x1B:2个字节磁头数,255(0x00 FF)。

【13】0x1C~0x1F:4个字节,分区前已使用扇区数,【14】0x20~0x23:4个字节,文件系统大小扇区数。

【15】0x24~0x27:4个字节,每个FAT表的大小扇区数。

【16】0x28~0x29:2个字节,标记。

【17】0x2A~0x2B:2个字节,版本号。

【18】0x2C~0x2F:4个字节,根目录簇号,2。

(虽然在FAT32文件系统下,根目录可以存放在数据区的任何位置,但是通常情况下还是起始于2号簇)【19】0x30~0x31:2个字节,FSINFO(文件系统信息扇区)扇区号,1。

(上图的标注即用黄色条纹的标注有误,请读者注意)该扇区为操作系统提供关于空簇总数及下一可用簇的信息。

【20】0x32~0x33:2个字节,备份引导扇区的位置,6。

(上图的标注即用黄色条纹的标注有误,请读者注意)备份引导扇区总是位于文件系统的6号扇区。

【21】0x34~0x3F:12个字节,未使用。

【22】0x40~0x40:1个字节,BIOS INT 13H 设备号,0x80。

(这个我也不知道什么意思☺)【23】0x41~0x41:1个字节,未用。

【24】0x42~0x42:1个字节,扩展引导标志。

0x29。

【25】0x43~0x46:1个字节,卷序列号。

通常为一个随机值。

【26】0x47~0x51:11个字节,卷标(ASCII码),如果建立文件系统的时候指定了卷标,会保存在此。

笔者当时没有指定卷表,上图中的YCY是后来指定的。

【27】0x52~0x59:8个字节,文件系统格式的ASCII码,FAT32。

【28】 0x5A~0x1FD:410个字节,未使用。

该部分没有明确的用途。

本实验关键点:FAT1起始扇区 = DBR的扇区号 + 保留扇区号根目录起始扇区 = 保留扇区数 + 一个FAT的扇区数 × FAT表个数 + (起始始簇号-2) x 每簇的扇区数Fat32查找目录区簇号,在fat表中从根目录查起,直到其表项标记结束。

使用到的工具:winhex(自行网上下载),a.c,b.c,c.c(将下面源码复制进相应文件里即可,linux下运行没问题,windows会报错)二、实验方案(如图):获取FAT32引导记录更改记录写入引导记录清空分配表三、预计实验结果:将u盘格式化成fat32文件系统,8G容量。

四、关键代码:a.c文件读取FAT32 DBR 保存到tmp.txt#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <stdio.h>int main(){int fd;char mbr[512];FILE *fp;char tmp[20];printf("input:\n");scanf("%s",tmp);fd=open(tmp,O_RDWR);//打开驱动器read(fd,mbr,sizeof(mbr));close(fd);fp = fopen("tmp.txt","w");fwrite(mbr,sizeof(mbr),1,fp);fclose(fp);}b.c文件#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include<sys/types.h>#include<unistd.h>//DBR结构typedef struct FAT32_DBR{char BS_jmpBoot[3]; //跳转指令char BS_OEMName[8]; //操作系统的名称和版本号char BPB_BytesPerSec[2];//每扇区字节数char BPB_SecPerClus[1]; //每簇扇区数char BPB_RsvdSecCnt[2]; //保留扇区数目char BPB_NumFATs[1]; //此卷中FAT表数char BPB_RootEntCnt[2]; //FAT32为0char BPB_TotSec16[2]; //FAT32为0char BPB_Media[1]; //存储介质char BPB_FATSz16[2]; //FAT32为0char BPB_SecPerTrk[2]; //磁道扇区数char BPB_NumHeads[2]; //磁头数char BPB_HiddSec[4]; //FAT区前隐扇区数char BPB_TotSec32[4]; //该卷总扇区数char BPB_FATSz32[4]; //一个FAT表扇区数char BPB_ExtFlags[2]; //FAT32特有char BPB_FSVer[2]; //FAT32特有char BPB_RootClus[4]; //根目录簇号char FSInfo[2]; //保留扇区FSINFO扇区数char BPB_BkBootSec[2]; //通常为6char BPB_Reserved[12]; //扩展用char BS_DrvNum[1]; //char BS_Reserved1[1]; //char BS_BootSig[1]; //char BS_V olID[4]; //char BS_FilSysType[11]; //char BS_FilSysType1[8]; //"FAT32 "char left[422];//剩余空间}fat32;int main(){fat32 mymbr;int fd,i;FILE *fp;char tmp[20];char ini=0x00;char end2=0xff;printf("input:\n");scanf("%s",tmp);fp = fopen("tmp.txt","r");//从文件读取DBRfread(&mymbr,sizeof(fat32),1,fp);fd=open(tmp,O_RDWR);//打开驱动器if(fd<0){printf("error!\n");exit(1);}write(fd,&mymbr,sizeof(mymbr));//写入DBR printf("SUCCESS!\n");close(fd);fclose(fp);return 0;}c.c文件#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include<sys/types.h>#include<unistd.h>int main(){int fd,i;char tmp[20];char ini=0x00;int fat1,fat2,dir;fat1 = 1049600;fat2 = 8913408;dir = 16777216;fat1+=12;fat2+=12;printf("input:\n");scanf("%s",tmp);fd=open(tmp,O_RDWR);//打开驱动器if(fd<0){printf("error!\n");exit(1);}lseek(fd,fat1,SEEK_SET);//跳到fat1位置for(i=0;i<100000;i++)//清空分配表write(fd,&ini,1);lseek(fd,fat2,SEEK_SET);//跳到fat2位置for(i=0;i<100000;i++)//清空分配表write(fd,&ini,1);lseek(fd,dir,SEEK_SET);//跳到dir位置for(i=0;i<10000;i++)//清空目录表write(fd,&ini,1);printf("SUCCESS!\n");close(fd);return 0;}五、傻瓜式操作步骤及实验代码分析1,将上面代码存到a.c,b.c,c.c 3个文件中,放到linux同一目录下就好了2,在windows下将实验U盘格式化成fat32文件系统(右击格式化就好了)3,在linux下插入U盘运行a.c程序,输入u盘物理地址(一般是/dev/sdb或者/dev/sdb1不懂的话可以通过fdisk -l指令查看,那个个字母是小写L)会自动生成一个tmp.txt,复制到windows(这个就是标准的fat32文件系统dbr内容,可以通过winhex打开)4,windows打开winhex软件,打开tmp.txt文件后得到上图。

相关文档
最新文档