现代的ARM Linux开发者往往面对的是一块开发板,一个SOC,什么都看不到,让人往往难以理解电脑究竟是如何构成的……当我们面对“计算机”的时候,一定要时刻记得,你的“计算机”是台遵守存储程序原理的冯诺依曼机器——运算器,控制器(这两样合起来是CPU),存储器,输入设备,输出设备。你所面对的一切SOC也好单板电脑也好,都是高度集成在一起的冯诺依曼机
现代的电脑虽然已经缩小了n多倍,性能强了n多倍,但它们和50年代的IBM机器在结构上是一样的。思考题:试着找出上面和下面照片里的运算器,控制器,存储器,输入设备和输出设备。
要解释什么是文件系统,要先解释什么是“文件”(File),有时“文件系统”也被翻译为“档案系统”。那么这个“文件”或“档案”是什么呢?看图说话:
一摞打孔卡片,就是一个“文件”它可以是一段程序,也可以是一段程序需要使用的数据。
上面的图是一段Fortran Monitor System(monitor可以理解为原始的“操作系统”)的“作业”(job,批处理batch系统的术语,你可以理解为一个可执行的程序),包含起始卡片,程序逻辑,程序数据,结束卡片,其实和今天的可执行文件的结构非常相似。
除了穿孔卡片之外,还有穿孔纸带,你把一张一张卡片头尾相接,就构成了一个(超宽的)纸带。在逻辑上,它就是一个一维数组。
思考题:文件读取进来为什么是byte array?
纸带在70年代还很流行,当年比尔盖茨的BASIC语言解释器,就是存在纸带上的,现在已经成文物了。
纸带时代的遗产到现在还能在C语言里看到,这段代码来自:Read a file as byte array
FILE *fileptr;
char *buffer;
long filelen;
fileptr = fopen("myfile.txt", "rb"); // Open the file in binary mode
fseek(fileptr, 0, SEEK_END); // Jump to the end of the file
filelen = ftell(fileptr); // Get the current byte offset in the file
rewind(fileptr); // Jump back to the beginning of the file
buffer = (char *)malloc((filelen+1)*sizeof(char)); // Enough memory for file + \0
fread(buffer, filelen, 1, fileptr); // Read in the entire file
fclose(fileptr); // Close the file
fseek:快进,ftell:当前纸带的位置,rewind:倒带,filelen:纸带的长度,你看到文件操作的代码,想着打孔纸带卷来卷去,就形象了。磁带的原理和纸带类似,但是用磁信号代替了物理打孔,记录密度更高也更容耐用,还可以重新磁化擦除改写。
不过纸带也好磁带也好受制于物理结构都只能线性读写,不能随机读写,如果你生活在1950年代,你会想到什么?对了!黑胶唱机!
不对,是这个
此处该有音乐!Daft Punk: Random Access Memories
IBM 350“统计控制随机存取法”(Random Access Method of Accounting and Control)使用了50张磁性“唱片”和机械手臂控制的“唱针”(磁头)
后来,人们为了纪念IBM 350对计算机工业的巨大启发,为它树立了巨大的纪念性建筑——Oracle总部
思考题:数据库图标的圆柱是什么?
上面的IBM 350有5MB,磁盘在当时属于容量很大的存储器,能够存储许多许多穿孔卡片和纸带的数据了,因此就必须对磁盘进行索引,1964年的文件 Disc File Applications: Reports Presented at the Nation's First Disc File Symposium 《磁盘文件应用:递交给第一届磁盘文件研讨会的报告》展示了1960年代主要的若干电脑系统对磁盘的使用。
http://www.bitsavers.org/pdf/informatics/Disc_File_Applications_1964.pdf
其中的插图展示了硬盘“格式化”的概念,将磁盘划分为若干较小的块,方便检索和操作。
看图说话:磁盘分区软件的“柱面”是什么?
Bryant 4000是一款容量和体积都非常巨大的硬盘,直径1米的大圆盘以1200转每分的速度运行,充满了机械美学。
http://s3data.computerhistory.org/brochures/bryant.model2.1965.102646212.pdf
文件系统解决的问题,就是如何在磁盘上定位和索引文件的问题——怎么在大转盘里找到自己想要的那卷纸带,像这样。
早期的文件系统是扁平的,没有文件层次(hierarchy)的概念,Linux的前身Unix的前身Multics——爸爸的爸爸叫爷爷,总之,Linux的“爷爷”在1965年的时候成为第一个有文件层次的系统。当年的论文我们还能看到。
A General-Purpose File System For Secondary Storage
设计文件层次系统所要解决的问题,是多程序(multiprogramming)环境下的次要(Secondary)在线存储器的可用问题(主要存储器用来加载系统,不放用户程序和数据),利用树状文件系统和权限管理,可以实现程序和用户一定程度上的隔离,提升分时系统的可用性,其中CHANGEDIRECTORY命令的简写cd命令直到今天仍然是几乎所有命令行系统中都最为常用的命令之一。
CHANGEDIRECTORY PATHNAME
1970年代,Linux的“爸爸”Unix设计的时候,人们对电脑的应用更加丰富,许多新的需求被提出来,比如
- 如何让不同的程序交流数据?
- 如何让程序方便的操作不同外设?
- 如何利用脚本实现复杂的工作流程?
这些需求带来了Unix系统最为重要的特征——统一的文件系统和管道,Unix的文件包括三类:
- 普通的文件
- 目录
- 特殊文件——输入输出设备
此外Unix还设计了三个独特的文件系统机制
- 可移动的文件系统
- 10bit权限保护系统
- 统一的输入输出调用
为什么要设计可移动(挂载)的文件系统,因为我们有移动硬盘了呀,decpack了解一下,把磁盘挂载到电脑上有几个步骤?把硬盘放进洗衣机(驱动器)里,关上洗衣机门,开动洗衣机,然后mount,就可以用了。反之停掉“洗衣机”之前,要umount(unmount,卸载),才能保证没有程序占用硬盘。
思考题:图中的妹子在干什么?
1978年发表的《The UNIX Time-Sharing System》一文,介绍的就是Unix运行在上面图中同款的PDP-11电脑上的情况,也介绍了Unix文件系统的设计需求和基本概念
https://archive.org/details/bstj57-6-1905
Unix提供了统一的设备文件,抹平了不同类型的输入输出设备的差异,你可以把一个文件输出到串口,也可以把它输出到打印机,还可以把它存储到硬盘或者磁带上,而程序可以完全不用改,只要重定向输出设备就好,简直太方便了有木有,这些特性一直沿用到今天。
Device file - Wikipedia
Linux在设计时就是为了尽可能和Unix兼容,所以保留了几乎全部的Unix特性,虽然基于NAND的闪存开始在很多领域取代硬盘,巨大的CPU也被微处理器广泛替代,但对于Linux软件来说,它们面对的API仍然是一部抽象了的PDP小型机。
RAM disk出现的比较晚,1980年出现在运行在CP/M的微机上,之后也出现在DOS上,用软件机制模拟了一张磁盘来提供高速的临时存储空间,数据确实不是持久的,它的作用一般只是用来放临时数据,减少低速磁盘的读写次数,提高软件运行速度。