1.文件系统介绍

一个简单的文件系统大致需要这么几个要素:

● 要有地方存放Metadata;

● 要有地方记录扇区的使用情况;

● 要有地方来记录任一文件的信息,比如占用了哪些扇区等;

● 要有地方存放文件的索引。

根据这些要素,同时参照Minix的文件系统,我们就把我们的文件系统设计成如下图所示的样子:

可以看到,总体上来看,它几乎是把前述的各要素一字排开:

● 要有地方存放Metadata——占用整整一个扇区的superblock;

● 要有地方记录扇区的使用情况——sector map;

● 要有地方来记录任一文件的信息,比如占用了哪些扇区等——inode map以及被称作inode_array的 i-node真正存放地;

● 要有地方存放文件的索引——root数据区。

superblock通常也叫超级块,关于文件系统的Metadata我们统统记在这里。sector map是一个位图,它用来映射扇区的使用情况,用 1 表示扇区已被使用,0表示未使用。i-node是UNIX世界各种文件系统的核心数据结构之一,我们把它借用过来。每个 i-node对应一个文件,用于存放文件名、文件属性等内容,inode_array就是把所有 i-node都放在这里,形成一个较大的数组。而inode map就是用来映射inode_array这个数组使用情况的一个位图,用法跟sector map类似。root数据区类似于FAT12的根目录区,但本质上它也是个普通文件,由于它是所有文件的索引,所以我们把它单独看待。为简单起见,暂不支持文件夹。

下面就该将文件系统放到硬盘的一个分区上。

2.硬盘分区表介绍

为了不用掉整块硬盘造成浪费,所以这里就来研究一下怎么来针对分区进行操作。

1、硬盘的读写是以扇区为最小单位的,在VHD规范里,每个扇区是512字节。扇区的编号是从1开始的。分区表一般位于硬盘某柱面的0磁头1扇区。而第1个分区表(也即主分区表)总是位于(0柱面,0磁头,1扇区),剩余的分区表位置可以由主分区表依次推导出来。分区表有64个字节,占据其所在扇区的[447-510]字节。要判定是不是分区表,就看其后紧邻的两个字节(也即[511-512])是不是 "55AA"(55和AA两个字节,其实是两个16进制:55H和AAH,用四位二进制表示一位16进制),若是,则为分区表。

2、分区表上有四项,每一项表示一个分区,所以一个分区表最多只能表示4个分区。主分区表上的4项用来表示主分区和扩展分区的信息。因为扩展分区最多只能有一个,所以硬盘最多可以有四个主分区或者三个主分区,一个扩展分区。余下的分区表是表示逻辑分区的。这里有必要阐述一点:逻辑区都是位于扩展分区里面的,并且逻辑分区的个数没有限制。
3、分区表所在扇区通常在(0磁头,1扇区),而该分区的开始扇区通常位于(1磁头,1扇区),中间隔了63 个隐藏扇区。

硬盘分区表其实是一个结构体数组,数组的每个成员是一个16字节的结构体,它的构成如下表:

这个数组位于引导扇区的1BEh处(也就是446字节处),共有四个成员——因为IBM当时觉得一台PC最多会装四个操作系统。现在我们的计算机中每块硬盘经常划分成不止四个分区,这是因为每个主分区可以进一步分成多个逻辑分区。

现在我们就来实际看一下分区表是什么样子的,用二进制查看器来看一下引导扇区:

可以看到,我们的新硬盘前1BEh个字节(446个字节)都是0.第1BEh到第1FDh字节便是分区表的内容了。按照表9.3的说明,可知它们的意义如下表9.4所示:

从表中可知,第一个分区始于第3Fh扇区,共有4E81h个扇区,第二个分区始于第4EC0h扇区,共有22F20h个扇区。然后显然这些信息是不够的,我们还有若干逻辑分区的信息没得到呢。我们现在就来看一下第二个分区——也就是扩展分区的第一个扇区是什么样子。扩展分区的开始字节为9D8000h(4EC0hx512),它的内容如下:

其主要项的意义如下表所示:

前一个分区的起始扇区LBA是3Fh,这是个相对于扩展分区基地址的LBA,也就是说,它真正的LBA是4EC0h+3Fh=4EFFh。后一个分区,根据其分区类型05可知,它又是个扩展分区,起始扇区LBA为4EC0h+9D80h=EC40h,字节偏移为EC40hx512=1D88000h,我们继续看看其引导扇区:

其意义如下表所示:

从分区类型值(System ID)可以看出,在这个分区中,又包含了一个“普通的”分区和一个扩展分区,现在一下子明白了,多个逻辑分区是由嵌套来实现的。一个扩展分区里包含一个普通分区的同时,又可以嵌套一个扩展分区,一层一层的。到目前为止,我们已经剥开了两层,如下图所示:

3.VFS文件系统介绍

在Linux文件系统中,为了提高文件访问的效率,都使用了Cache机制来提高速度。所谓Cache机制就是指文件系统在读写磁盘上的数据之前,都要经过Cache系统的缓冲。如果数据在Cache里有的话,就直接读取,如果没有,才实际从驱动器读写。

第一个块是引导块(Boot block),系统引导的时候使用。第二个块是超级块(Super block),记录了文件系统重要的信息,接下来的磁盘块存放inode和文件数据。

在VFS里,每一个文件系统是由其超级块来表示的,这是因为超级块存放了一个文件系统的最重要的信息,通过超级块可以了解这个文件系统的基本构成。从一个文件系统的超级块出发,就可以访问文件系统中任何一个文件。因此,在Linux中文件系统的管理以超级块为单位,从超级块可以取得这个文件系统中任何一个文件的inode,从文件的inode则可以对这个文件进行读写访问。

4.块设备

块设备(blockdevice)
--- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区。
字符设备(Character device)
---是一个顺序的数据流设备,对这种设备的读写是按字符进行的,而且这些字符是连续地形成一个数据流。他不具备缓冲区,所以对这种设备的读写是实时的。

扇区(Sectors):任何块设备硬件对数据处理的基本单位。通常,1个扇区的大小为512byte。(对设备而言)
块 (Blocks):由Linux制定对内核或文件系统等数据处理的基本单位。通常,1个块由1个或多个扇区组成。(对Linux操作系统而言)
段(Segments):由若干个相邻的块组成。是Linux内存管理机制中一个内存页或者内存页的一部分。
页、段、块、扇区之间的关系图如下:

Linux0.11内核--文件系统理论知识的更多相关文章

  1. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  2. linux0.11内核源码剖析:第一篇 内存管理、memory.c【转】

    转自:http://www.cnblogs.com/v-July-v/archive/2011/01/06/1983695.html linux0.11内核源码剖析第一篇:memory.c July  ...

  3. Linux0.11内核剖析--内核体系结构

    一个完整可用的操作系统主要由 4 部分组成:硬件.操作系统内核.操作系统服务和用户应用程序,如下图所示: 用户应用程序是指那些字处理程序. Internet 浏览器程序或用户自行编制的各种应用程序: ...

  4. linux0.11内核源码——进程各状态切换的跟踪

    准备工作 1.进程的状态有五种:新建(N),就绪或等待(J),睡眠或阻塞(W),运行(R),退出(E),其实还有个僵尸进程,这里先忽略 2.编写一个样本程序process.c,里面实现了一个函数 /* ...

  5. Linux0.11内核--内存管理之1.初始化

    [版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5597705.html ] Linux内核因为使用了内存分页机制,所以相对来说好理解些.因为内存 ...

  6. Linux0.11内核源码——内核态线程(进程)切换的实现

    以fork()函数为例,分析内核态进程切换的实现 首先在用户态的某个进程中执行了fork()函数 fork引发中断,切入内核,内核栈绑定用户栈 首先分析五段论中的第一段: 中断入口:先把相关寄存器压栈 ...

  7. linux0.11内核源码——boot和setup部分

    https://blog.csdn.net/KLKFL/article/details/80730131 https://www.cnblogs.com/joey-hua/p/5528228.html ...

  8. Linux0.11内核剖析--内核代码(kernel)--sched.c

    1.概述 linux/kernel/目录下共包括 10 个 C 语言文件和 2 个汇编语言文件以及一个 kernel 下编译文件的管理配置文件 Makefile.其中三个子目录中代码注释的将放在后面的 ...

  9. Linux0.11内核--缓冲区机制大致分析

    文件系统的文件太多,而且是照搬的MINIX的文件系统,不想继续分析下去了.缓冲区机制和文件系统密切相关,所以这里就简单分析一下缓冲区机制. buffer.c 程序用于对高速缓冲区(池)进行操作和管理. ...

随机推荐

  1. 虚拟文件系统(VFS)

    原文链接:http://www.orlion.ga/1008/ linux在不同的文件系统之上做了一个抽象层,使得文件.目录.读写访问等概念都成为抽象层概念,这个抽象层被称为虚拟文件系统(VFS). ...

  2. Neutron 网络基本概念 - 每天5分钟玩转 OpenStack(66)

    上次我们讨论了 Neutron 提供的功能,今天我们学习 Neutron 模块几个重要的概念. Neutron 管理的网络资源包括 Network,subnet 和 port,下面依次介绍. netw ...

  3. Android随笔之——Activity中启动另一应用

    最近在写语音交互程序,在语音打开应用这块碰到如何用代码控制应用启动的问题.百度了一下,有两种方案:1.获取应用的包名:2.获取应用的包名.入口类名. 之前对两种方案都进行了尝试,发现方案二中存在一个弊 ...

  4. ASP.NET MVC Application_Error 无效不执行

    我们一般在开发 ASP.NET MVC 应用程序的时候,会在 Application_Error 中添加异常日志记录,一般会记录 500 的错误信息,但如果应用程序在出错的时候,Application ...

  5. geotrellis使用(二十一)自动导入数据

    目录 前言 整体介绍 前台界面 后台控制 总结 一.前言        之前Geotrellis数据导入集群采用的是命令行的方式,即通过命令行提交spark任务来ingest数据,待数据导入完毕再启动 ...

  6. 自己在总结前人经验下弄的几个opencv封装函数

    第一个是增加对比度的函数,就是变亮. IplImage* EqualizeHistColorImage(IplImage *pImage) { IplImage *pEquaImage = cvCre ...

  7. 在非SQL客户端使用命令行方式定期连接SQL Server 服务器并模拟用户查询操作,同时输出信息内容

    一个很长的标题,实现的功能就是尽量使用非人力的方式模拟人去做一件事情,为了便于记录,将他们输出成文件方便查阅. 图形界面方式,使用微软自己的ConnMaker.exe,或者Microsoft 数据连接 ...

  8. Matrix Factorization SVD 矩阵分解

    Today we have learned the Matrix Factorization, and I want to record my study notes. Some kownledge ...

  9. Struts2学习笔记--使用Response下载文件和Struts2的StreamResult文件下载

    使用Response下载文件,servlet中的文件下载是通过流来实现的   我在webRoot文件夹下新建了一个文件夹from,里边放了一张图片,这里就以下载这张图片为例:download.jsp很 ...

  10. 【LeetCode】Increasing Triplet Subsequence(334)

    1. Description Given an unsorted array return whether an increasing subsequence of length 3 exists o ...