磁盘
磁盘是一个机械机构,不同于硬盘。
现在普通人很少能见到磁盘了。
磁盘是一个机械结构+外设=访问很慢(只是相对于硬盘很慢)
磁盘的物理结构
磁盘是这种结构,像光碟一样的是盘面,主要是用于储存内容的,两面都能用,盘面是光滑的,盘面中间的是马达,控制盘面旋转。像一个指针一样的头叫做磁头,每个面都有一个磁头,是用于读写磁盘内容的,磁头和盘面没有接触,后面的是马达,用来控制磁头进行上下移动。电路板那里是电路硬件+伺服系统,用于控制磁头何时进行读写的,也就是正负电二进制控制。
其次,磁盘是有多片的,要防止抖动,不然摩擦或者是碰撞可能会导致数据丢失或者是磁盘无法使用。
还有不能拆开,拆开基本等于报废,因为磁盘不能落灰,整个磁盘在制作过程中是载真空室内,并且密封性也是非常的好。
磁盘的储存结构
每个盘面上其实是有磁道的,上面是一圈一圈的,我们看不到,磁头摆动也是为了找磁道。
磁盘寻址的时候,是512个byte访问一次,这也是一个扇区。
那么在一个扇形区域内,每个表面看扇区大小不一样,实际上储存的都是512byte。
那么磁头是如何定位一个扇区的呢?就是盘载旋转的时候就是在定位扇区,磁头摆动是在定位磁道。
这些磁头是连在一起的,一起摆动,共进退的,这就是为什么有柱面这个概念了。
柱面就是磁道每个盘面相同位置的磁道上下连在一起。
这样的话就是先定位磁道,在定位是哪一个盘面,最后在定位扇区。这种定位的方式是CHS定位法。
磁盘的逻辑结构
虽然磁盘的盘面是圆的,但是在操作系统看来他就像数组一样。
就好像录音机里面的磁带一样,虽然是卷起来的,但是也可以拉直。
那么假设一个磁盘是500GB:
对磁盘的管理==对数组的管理
那么我们如何定位扇区呢?把磁盘想象成线性结构,只要知道了数组的下标就可以,这就是等于线性空间的地址。
这个下标叫做LBA地址,逻辑块地址。
举个例子:
盘面有4个,磁道/面:10,扇区/磁道:100,扇区512字节大小。
总共大小是:4*10*100*512.
下标范围:4*10*100.
一面是:10*100
假如说下标为123:
123/100在一号磁道 C
123/1000在第0面 H
123%100在23号扇区 S
这就是CHS方法。
操作系统进行逻辑抽象是因为便于管理,还有一个原因是不想让操作系统的代码和硬件强耦合,不然明天换个配置,你要换一种代码,后面又换怎么办。
文件系统
分治
虽然对应的磁盘访问基本单位是512字节,但是依旧很小。
所以操作系统定制的进行多个扇区的读取->1KB,2KB,4KB(现在基本都是4KB)为基本单位。
哪怕是要读取或者修改1bit的内容,都必须将4KB的内容放进内存中进行读取或修改,如果必要,再写回盘。(局部性原理:如果我们访问某个部分,那么在他周围的数据是非常大概率会被访问的,这也相当于以空间换时间)
内存中被划分成4KB大小的空间——页框。
磁盘的文件尤其是可执行文件——按照4KB大小划分好的块——页帧。
文件放在内存就是页帧放进页框,这就是操作系统和文件的耦合。
假设一个磁盘有500GB:
这种思想叫做分治。
那么也就是说,我们如何去管理这个5G的区域,其他区域也可以这样管理,这种管理的方法复制过去就好了。
所以讨论文件系统,只要讨论这5G就可以了。
Boot Block:操作系统加电开机启动的时候,所有的信息都在这个区域。
Block group 0:超级块,块组0。
Super Block:超级块对象,保存的是整个文件系统的信息。
如果想清空哪个盘里面的所有数据内容,其实就相当于重写文件系统。一个磁盘,第一步是分区,第二部就是格式化,也就是写入文件系统。
文件系统的信息有分区的使用状态,分区的每个组的状态和信息。
既然这么重要,为何放在这里呢?其实在大部分文件系统中,块组前几个开头就是Super Block,这就相当于备份。
假如说某个Super Block出问题了,发现的原因其实就是Super Block对比,然后询问是否进行恢复。
inode与数据块
文件 = 内容 + 属性
Linux中,文件的属性和内容是分批存储的。
保存文件属性的叫inode块:具体大小跟文件系统的版本有关,我的是ext3,128字节。
inode是固定大小,一个文件对应一个inode(硬链接除外,下面会说),里面包含了一个文件几乎所有的属性。注意,文件名并不在里面!
inode为了区分彼此,每一个都有自己的ID。
inode Table:这个就是用来保存分组内部已使用+未使用的inode。
文件内容是存储在data block(数据块)中的:这个大小是随着应用类型的变化而发生大小的变化。
Data block:保存的是分组内部所有文件的数据块。
那么,上面的inode与数据块,他不可能随便去使用,肯定要先找到未被使用的才可以根据需求进行使用。
inode Bitmap:inode的结构位图,按照二进制,一个比特位就是一个inode,如果是0就是未被占用,1就是已被占用。
第几个比特位就代表是第几个位置,位图中比特位的位置和当前文件对应的inode的位置是一 一对应的。
也就是说,删除一个文件速度会很快,只要讲相对应的比特位置零就可以了!
Block Bitmap:这个是数据块对应的位图结构,和上面inode的位图结构同理,位图中的比特位和当前的data block对应的数据块位置是一 一对应关系!
Group Descriptor Table:块组描述表,对应分组的宏观属性信息。
在查找一个文件的时候统一用的是inode编号,它可以跨组的,不同的组里面是不同的,但是不能跨分区。
data block blocks[15]是储存数据块的,假设某个inode编号对应的数据块是这样存储的:
那么,如果inode拿到了对应的这个编号,我们要查找内容就找data block blocks[15],发现只有4个链接的,那么把数据块中的1,2,7,8,13给连接在一起就是我们要找的文件内容了。
可是,只有15个储存数据块地址内容也太小了,一个才4KB,其实后三个才是重头戏,12储存的不是某个数据块的id,而是指向了某个数据块,这个数据块里面储存的是其他数据块的id,一共可以存1024个,这个叫做一级索引。
13储存的是1024个储存1024个数据块的地址,这个叫二级索引。
14就是三级索引。
文件名在哪里?
我们平时也不会去用inode,用的都是文件名,那么文件名放在了哪里呢?
首先,任何文件都在某个目录下,那么目录是文件,也有自己对应的inode,只要有自己的inode,就有对应的数据块,那么目录的数据块放什么呢?放的就是当前目录下的文件名和inode的映射关系。
这就是为什么在一个目录下创建一个文件为什么要有写权限和读权限了,因为创建文件代表需要向这个目录中写入inode与文件名,读取目录下的文件需要去找当前目录的文件名才可以找到对应的inode。
软硬链接
什么是软硬连接
在一个目录下创建一个文件,然后创建一个硬链接与软连接。
这里,inode相同的hard_log.txt是log.txt的硬链接,soft_log.txt是log.txt的软链接。
软连接有独立的inode,可以被当成独立文件看待。
那么硬链接呢?
这次我们更加的肯定,log.txt与hard是同一个文件了。
但是2是什么呢?为什么软链接是1呢?
既然没有给硬链接单独分配inode,那么久没有自己的属性和内容,用的就是别人的inode和内容。
引用计数是硬链接数!
那么我们删除log.txt试一下。
原来log.txt对应的inode对应的文件没有被彻底删除,也就是说只有在inode中的引用计数归零的时候,这个文件才是真正被删除。
那么软链接这里却显示了文件已经消失,这说明软连接不是和inode有关系,而是和文件名有关。
这里又创建了一个同名文件,现在又显示链接成功了,但是inode已经不是原来的了。
软链接就相当于windows下的快捷方式一样。
删除链接文件用unlink 文件名也可以。
文件与引用计数
我们创建一个普通文件和目录,普通文件是一有一个硬链接的,因为文件名和它的inoded是映射关系。
那么为什么目录又两个呢?
一个点代表是当前目录的意思,这时隐藏文件,两个点是上级目录的意思,所以一个点与当前目录就是硬链接,一个点也是文件名。
但后我们在当前目录下创建一个目录。
然后回到上级目录发现硬链接数变成3个了,这是因为创建的lol目录的两个点是链接在empty目录的:
注意:操作系统不让用户给目录创建硬链接!
文件的三大时间
Access 最后访问时间(因为特殊原因,这个数值只有达到一定条件才会刷新)
Modify 文件内容最后修改时间
Change 属性最后修改时间(属性包括大小的,所以有大部分时候改内容属性也会修改)
动静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。