linux0.12-12-1-总体功能

[606页]

12-1 总体功能

本章所注释的程序量较大,但是通过第5章中对Linux源代码目录结构的分析(参见图5-27),
可以把它们从功能上分为4个部分进行讨论。
第一部分是有关高速缓冲区的管理程序,主要实现了对硬盘等块设备进行数据高速存取的函数。
该部分内容集中在buffer.c程序中实现;
第二部分代码描述了文件系统的低层通用函数。说明了文件索引节点的管理、磁盘数据块的分配
和释放以及文件名与i节点的转换算法;
第三部分程序是有关对文件中数据进行读写操作,包括对字符设备、管道、块读写文件中数据的访问;
第四部分的程序主要涉及文件的系统调用接口的实现,主要涉及文件打开、关闭、创建以及有关文件目录
操作等的系统调用。

下面首先介绍一下MINIX文件系统的基本结构,然后分别对着四部分加以说明。

12-1-1 MINIX文件系统

目前MINX的版本是3.1,所使用的文件系统是3.0版,它与1.5版之前的版本不同,对其容量已经作了扩展。但由于本书注释的Linux内核使用的是MINIX文件系统1.0版本,所以这里仅对其1.0版文件系统作简单介绍。
引导块+超级块+i节点位图+逻辑块位图+i节点+数据区(一个小格 = 一个盘块(两个512B) = 逻辑块)
MINIX文件系统与标准UNIX的文件系统基本相同。它由6个部分组成。对于一个360KB的软盘,其各部分的分布如图12-1所示。
在这里插入图片描述

图中,整个磁盘被划分以1KB为单位的磁盘块,因此上图中共有360个磁盘块,每个方格表示一个磁盘块。由后面的说明我们会知道,在MINIX1.0文件系统中,其磁盘块大小与逻辑块大小正好是一样的,也是1KB字节。因此360KB盘片也含有360个逻辑块。在后面的讨论中我们有时会混合使用这两个名称。

引导块是计算机加电启动时可由ROM BIOS自动读入的执行代码和数据。但并非所有盘都作为引导设备,所以对于不用引导的盘片,这一盘块中可以不含代码。但任何盘片必须含有引导块空间,以保持MINIX文件系统格式的统一。即文件系统只是在块设备上空出一个存放引导块的空间。如果你把内核映像文件放在文件系统中,那么你就可以在文件系统所在设备的第1个块(即引导块空间)存放实际的引导程序,并由它来取得和加载文件系统中的内核映像文件。

对于硬盘块设备,通常在其上会划分处几个分区,并且在每个分区中都可存放一个不同的完整文件系统,如图12-2所示。图中表示有4个分区,分别存放着FAT32文件系统、NTFS文件系统、MINIX文件系统和EXT2文件系统。
在这里插入图片描述

硬盘的第一个扇区是主引导扇区,其中存放着硬盘引导程序和分区表信息。分区表中的信息指明了硬盘上每个分区的类型、在硬盘中起始位置参数和结束位置参数以及占用的扇区总数,参见kernel/blk_drv/hd.c文件后的硬盘分区表结构。

超级块用于存放盘设备上文件系统结构的信息,并说明各部分的大小。
其结构如图12-3所示。其中,
在这里插入图片描述

s_ninodes表示设备上的i节点总数。
s_nzones表示设备上以逻辑块为单位的总逻辑块数。
s_imap_blockss_zmap_blocks分别表示i节点位图和逻辑块位图所占用的磁盘块数。
s_firstdatazone表示设备上数据区开始处占用的第一个逻辑块块号。
s_log_zone_size是使用2位底的对数表示的每个逻辑块包含的磁盘块数。
对于MINIX1.0文件系统该值为0,因此其逻辑块的大小等于磁盘块的大小,都是1KB。
s_max_size是以字节表示的最大文件长度。当然这个长度值将受到磁盘容量的限制。
s_magic是文件系统魔幻数,用以指明文件系统的类型。对于MINIX10.0文件系统,它的魔幻数是0x137f。

图12-3 MINIX的超级块结构
在这里插入图片描述
在这里插入图片描述

在Linux0.12系统中,被加载的文件系统超级块保存在超级块表(数组)super_block[]中。该表共有8项,因此Linux0.12系统中同时最多加载8个文件系统。超级块表将在super.c程序 的mount_root()函数中被初始化,在read_super()函数中会为新加载的文件系统在表中设置一个超级块项,并在put_super()函数中释放超级块表中指定的超级块项。

逻辑块位图用于描述盘上每个数据盘块的使用情况。除第1个位(位0)以外,逻辑块位图 中每个位依次代表盘上数据区中的一个逻辑块。因此逻辑块位图的位1代表盘上数据区中
第一个数据盘块,而非盘上的第一个磁盘块(引导块)。当一个数据盘块被占用时,则逻辑块位图中相应位被置位。由于当所有磁盘数据盘块都被占用时查找空闲盘块的函数会返回0值,因此逻辑块位图最低位(位0)闲置不用,并且在创建文件系统时会预先将其设置为1。

从超级块的结构中我们还可以看出,逻辑块位图最多使用8块缓冲块(s_zmpa[8]),而每块缓冲块大小是1024字节,每位表示一个盘块的占用状态,因此一个缓冲块可代表8192个盘块。8个缓冲块总共可表示65536个盘块,因此MINIX文件系统1.0所能支持的最大块设备容量(长度)是64MB。

i节点位图用于说明i节点是否被使用,同样是每个位代表一个i节点。对于1KB大小的盘块来讲,一个盘块就可表示8192个i节点的使用状况。与逻辑块位图的情况类似,由于当所有 i节点都被使用时查找空闲i节点的函数会返回0值,因此i节点位图第1个字节的最低位(位0)和对应的i节点0都闲置不用,并且在创建文件系统时会预先将i节点0对应位图中的位置位1。因此第一个i节点位图块中只能表示8191个i节点的状况。

盘上的i节点部分存放着文件系统中文件或目录名的索引节点,每个文件或目录名都有一个i节点。每个i节点结构中存放着对应文件的相关信息,如文件宿主的id(uid)、文件所属组id(gid)、文件长度、访问修改时间以及文件数据块在盘上的位置等。整个结构共使用32个字节,如图12-4所示。

图12-4 MINIX文件系统1.0版的i节点结构

i_mode字段用来保存文件的类型和访问权限属性。
其位15~12用于保存文件类型,
位11~9保存执行文件时设置的信息,
位8~0表示文件的访问权限,
如图12-5所示。具体信息参见文件include/sys/stat.h第20~50行和include/fcntl.h。
在这里插入图片描述

文件中的数据是放在磁盘块的数据区中的,而一个文件名则通过对应的i节点与这些数据磁盘块联系,这些盘块的号码就存放在 i节点的逻辑块数组i_zone[]中。其中,i_zone[]数组用与存放i节点对应文件的盘块号。i_zone[0]到i_zone[6]用于存放文件开始的7个磁盘块号,称为直接
块。若文件长度小于等于7KB,则根据其i节点可以很快就找到它所使用的盘号。若文件大一些时,就需要用到一次间接块了(i_zone[7]),这个盘块中存放着附加的盘块号。对于 MINIX文件系统它可以存放512个盘块号,因此可以寻址512个盘块。若文件还要大,则需要使用二次间接盘块(i_zone[8])。二次间接块的一级盘块的作用类似于一次间接盘块,因此使用二次间接盘块可以寻址512X512个盘块。参见图12-6。
在这里插入图片描述

另外,对于/dev/目录下的设备文件来说,它们并不占用磁盘数据区中的数据盘块,即它们文件的长度是0。设备文件名的i节点仅用于保存其所定义设备的属性和设备号。设备号被存放在设备文件i节点的zone[0]中。

当所有i节点都被使用时,查找空闲i节点的函数会返回值0,因此,i节点位图最低位和i节点0都是闲置不用。
i节点0的结构被初始化成全零,并在创建文件系统时将i节点0的位置位。

对于PC来讲,一般以一个扇区的长度(512字节)作为块设备的数据块长度。而MINIX文件系统则将连续的2个扇区数据(1024字节)作为一个数据块来处理,称之为一个磁盘块或盘块。其长度与高速缓冲区中的缓冲块长度相同。编号是从盘上第一个盘块开始算起,即引导 块时0号盘块。而上述的逻辑块或区块,则是盘块的2的幂次倍数。一个逻辑块长度可以等于1,2,4或8个盘块长度。
对于本书所讨论的Linux内核,逻辑块的长度等于盘块长度。因此在代码注释中这个两个术语含义相同。但
是术语数据逻辑块(或数据盘块)则是指盘设备上数据部分中,从第一个数据盘块开始编号的盘块。

12-1-2 文件类型、属性和目录项

1、 文件的类型和属性

UNIX类操作系统中对的文件通常可分为6类。如果在shell下执行"ls -l"命令,我们就可以
从列出的文件状态信息中知道文件的类型。如图12-7所示。

图12-7 命令"ls -l"显示的文件信息
在这里插入图片描述

图中,命令显示的第一个字节表示所列文件的类型。"-"表示该文件是一个正规(一般)文件。

**正规文件(“-”)**是一类文件系统对其不做解释的文件,包含任何长度的字节流。例如源文件、二进制执行文件、文档以及脚本文件。

**目录(“d”)**在UNIX文件系统中也是一种文件,但文件系统管理会对其内容进行解释,以使人们可以看到有哪些文件包含在一个目录中,以及它们是如何组织在一起构成一个分层次的文件系统的。

**符号链接(“s”)**用于使用一个不同文件名来引用另一个文件。符号链接可以跨越一个文件系统而链接到另一个文件系统中的一个文件上。删除一个符号链接并不影响被链接的文件。另外还有一种链接方式称为"硬链接"。它与这里所说符号链接中被链接文件的地位相同,被作为一般文件对待,但不能跨越文件系统(或设备)进行链接,并且会递增文件的链接计数值。见下面对链接计数的说明。
**命名管道(“p”)**文件是系统创建有名管道时建立的文件。可用于无关进程之间的通讯。
**字符设备(“c”)**文件用于以操作文件的方式访问字符设备,例如tty终端、内存设备以及网络设备。
**块设备(“b”)**文件用于访问向硬盘、软盘等的设备。在类UNIX操作系统中,块设备文件和字符设备
文件一般均放在系统的/dev目录中。

在Linux内核中,文件的类型信息保存在对应i节点的i_mode字段中,使用高4位来表示,并使用了一些判断文件类型宏,例如S_ISBLK、S_ISDIR等,这些宏在include/sys/stat.h中定义。

在图中文件类型字符后面是每三个字符一组构成的三组文件权限属性。用于表示文件宿主、同组用户和其他用户对文件的访问权限。“r”,“w”,"x"分别表示对文件可读、可写和可执行的许可权。对于目录文件,可执行表示可以进入目录。在对文件的权限进行操作时,一般使用八进制来表示它们。

例如"755"表示文件宿主对文件可以读/写/执行,同组用户和其他人可以读和执行文件。在Linux0.12源代码中,文件权限信息也保存咋对应i节点的i_mode字段中,使用该字段的低9位表示三组权限。并常使用变量mode来表示。有关文件权限的宏在include/fcntl.h中定义。

图中的"链接计数"位表示该文件被硬链接引用的次数。当计数减为零时,该文件即被删除。
"用户名"表示该文件宿主的名称,"组名"是该用户所属组的名称。

2、文件系统目录项结构

Linux0.12系统采用的是MINIX文件系统1.0版。它的目录结构和目录项结构与传统UNIX文件
的目录项结构相同,定义在include/linux/fs.h文件中。在文件系统的一个目录中,其中所有
文件名信息对应的目录项存储在该目录文件名文件的数据块中。

例如,目录名root/下的所有文件名的目录项就保存在root/目录名文件的数据块中。而文件系统根目录
下的所有文件名信息则保存在指定i节点(即1号i节点)的数据块中。文件名目录项结构如下所示:

//定义在include/linux/fs文件中。
#define NAME_LEN 14			//名字长度值。
#define ROOT_INO 1			//根i节点。
//文件目录项结构。
struct dir_entry {
	unsigned short inode;	//i节点号。
	char name[NAME_LEN];	//文件名。
};

每个目录项只包括一个长度为14字节的文件名字符串和该文件名对应的2字节的i节点号。因此一个逻辑磁盘块可以存放1024/16=64个目录项。有关文件的其他信息则被保存在该i节点号指定的i节点结构中,该结构中主要包括文件访问属性、宿主、长度、访问保存时间以及所在磁盘块等信息。每个i节点号的i节点都位于磁盘上的固定位置处。

在打开一个文件时,文件系统会根据给定的文件名找到其i节点号,从而通过其对应i节点信息找到文件所在的磁盘块位置,

如图12-8所示。例如对于要查找文件名/usr/bin/vi的i节点号,
在这里插入图片描述

文件系统首先会从具有固定i节点号(1)的根目录开始操作,
即从i节点号1的数据块中找到名称为usr的目录项,从而得到文件/usr的i节点号。
根据该i节点号文件系统可以顺利地取得目录/usr,并可在其中找到文件名bin的目录项。
这样也就知道了/usr/bin的i节点号,因而我们可以知道目录/usr/bin的目录所在位置,
并在该目录中查找到vi文件的目录项。最终我们获得了文件路径名/usr/bin/vi的i节点号,
从而可以从磁盘上得到该i节点号的i节点结构信息。

如果从一个文件在磁盘上的分布来看,对于某个文件数据块信息的寻找过程可用图12-9表示(其中未画出引导块、超级块、i节点和逻辑块位图)。
在这里插入图片描述

通过对用户程序指定的文件名,我们可以找到对应的目录项。根据目录项中的i节点号就可以找到i节点表中相应的i节点结构。i节点结构中包含着该文件数据的块号信息,因此最终可以得到文件名对应的数据信息。上图中有两个目录项指向了同一个i节点,因此根据这两个文件名都可以得到磁盘上相同的数据。每个i节点结构中都有一个链接计数字段i_nlinks记录着指向该i节点的目录项数,即文件的硬链接计数值。本例中该字段值为2。在执行删除操作文件时,
只有当i节点链接计数值等于0时内核才会真正删除磁盘上该文件的数据。另外,由于目录项中i节点仅能用于当前文件系统,因此不能使用一个文件系统的目录项来指向另一个文件系统中的i节点,即硬链接不能跨越文件系统。

与硬链接不同,符号链接类型的文件名目录项并不直接指向对应的i节点。符号链接目录项会在对应文件的数据块中存放某一文件的路径名字符串。当访问符号链接目录项时,内核就会读取该文件中的内容,然后根据其中的路径名字符号串来访问指定的文件。因此符号链接可以不局限在一个文件系统中,我们可以在一个文件系统中建立一个指向另一个文件系统中文件名的符号链接。

在每个目录中还包含两个特殊的文件目录项,它们的名称分贝固定为".“和”…"。
".“目录项中给出了当前目录的i节点号,而”…"目录项中给出了当前目录父目录项的i节点号。
因此在给出一个相对路径名时时文件系统就可以额利用这两个特殊目录项进行查找操作。

例如要查找…/kernel/Makefile,就可以首先根据当前目录的"…"目录项得到父目录的i节点号,然后
按照上面描述过程进行查找操作。

对于每个目录文件的目录项,其i节点中的链接计数字段值也表明连接到该目录的目录项数。因此每个目录文件的链接计数值起码为2。其中一个是包含目录文件的目录项链接,另一个是目录中"…"目录项的链接。例如我们在当前目录中建立一个名为mydir的子目录,那么在当前目录和该子目录中的链接示意图如图12-10所示。
在这里插入图片描述

图中示出了我们在i节点号为56的目录中建立了一个mydir子目录,该子目录的i节点号是123。
在my_dir子目录中的".“目录项指向自己的i节点123,而其”…"目录项则指向其父目录的i节点56。
可见,由于一个目录的目录项本本身总是会有两个链接,若其中再包含子目录,那么父目录的i
节点链接数就等于2+子目录数。

3、 目录结构例子

以Linux0.12系统为例,我们来观察它的根目录项结构。在Bochs中运行Linux0.12系统之后,我们先
列出其文件系统根目录项,包括其中隐含的".“和”…“目录项。然后使用hexdump命令查看”.“或”…"
文件的数据块内容,可以看到根目录包含的各个目录项内容。

进入到根目录
ls -la
hexdump .

执行"hexdump .“命令后列出了1号i节点数据块中包含的所有目录项。每一行对应一个
目录项,每行开始两字节是i节点号,随后的14字节是文件名或目录名字符串。若一个
目录项中i节点号是0,则表示该目录项没有被使用,或对应的文件已经被删除或移走。
其中头两个目录项(”.“和”…")的i节点号均是1.这是文件系统根目录结构的特殊之处,
与其余子目录结构不同。

现在查看etc/目录项。同样对etc/目录使用hexdump命令,可以显示出etc/子目录包含的目录项:

此时我们可以看出etc/目录名i节点对应的数据块中包含该子目录下所有文件的目录项信息。
其中目录项".“的i节点正是etc/目录项自己的i节点号4,而”…"的i节点是etc/父目录的i节点号1。

12-1-3 高速缓冲区

高速缓冲区是文件系统访问块设备中的数据的必经要道。为了访问文件系统等块设备上的数据,内核可以每次都访问块设备,进行读或写操作。但是每次I/O操作的时间与内存和CPU的处理速度相比是非常慢的。为了提高系统的性能,内核就在内存中开辟了一个高速数据缓冲区(池)(buffer cache),并 将其划分一个个与磁盘数据块大小相等的缓冲块来使用和管理,以期减少访问块设备的次数。
在Linux内核中,高速缓冲区位于内核代码和主内存之间,其中存放着最近被使用过的各个块设备中的数据块。当需要从块设备中读取数据时,缓冲区管理程序首先会在高速缓冲中寻找。如果相应数据已经在缓冲中,就无需再从块设备上读。如果数据不在高速缓冲中,就发出读块设备的
命令,将数据读到高速缓冲中。当需要把数据写到块设备中时,系统就会在高速缓冲区中申请一块空闲的
缓冲块来临时存放这些数据。至于什么时候把数据真正地写到设备中去,则是通过块设备数据同步实现的。

Linux内核实现高速缓冲区的程序是buffer.c。文件系统中其他程序通过指定需要访问的设备号和数据逻辑
块号来调用它的块读写函数。这些接口函数有:
块读取函数bread()
块提前预读函数bread()
页块读取函数bread_page()
页块读取函数一次读取一页内存所能容纳的缓冲块数(4块)。

12-1-4 文件系统底层函数

文件系统的底层处理函数包含在以下5个文件中:
bitmap.c程序包括对i节点位图和逻辑块位图进行释放和占用处理函数。操作i节点位图
的函数是free_inode()和new_inode(),操作逻辑块位图的函数是free_block()和new_block()。

truncate.c程序包括对数据文件长度截断为0的函数truncate()。
它将i节点指定的设备上文件长度截为0,并释放文件数据占用的 设备逻辑块。

inode.c程序包括分配i节点函数iget()和放回对内存i节点存取函数iput()以及根据i节
点信息取文件数据块在设备上对应的逻辑块号函数bmap()。

namei.c程序主要包括函数namei()。该函数使用iget()、iput()和bmap()将给定的文件路径
名映射到其i节点。

super.c程序专门用于处理文件系统超级块,包括函数get_super()、put_super()和
free_super()等。还包括几个文件系统加载/卸载处理函数和系统调用,如sys_mount()等。

这些文件中函数之间的层次关系如图12-11所示。
在这里插入图片描述

12-1-5 文件中数据的访问操作

关于文件中数据的访问操作代码,主要涉及5个文件(见图12-12):
block_dev.c、file_dev.c、char_dev.c、pipe.c和read_write.c。前4个文件可以认为是块设备、字符设备、管道设备和普通文件与文件读写系统调用的接口程序,
它们共同实现了read_write.c中的read()和write()系统调用。通过对被操作文件属性的判断,
这两个系统调用会分别调用这些文件中的相关处理函数进行操作。

图12-12 文件数据访问函数
在这里插入图片描述

block_dev.c中的函数block_read()和block_write()是用于读写块设备特殊文件中的数据。所使用的参数
指定了要访问的设备号、读写的起始位置和长度。

file_dev.c中的file_read()和file_write()函数是用于访问一般的正规文件。通过指定文件对应的i节点和
文件结构,可以知道文件所在的设备号和文件当前的读写指针。

pipe.c文件中实现了管道读写函数read_pipe()和write_pipe()。另外还实现了创建无名管道
的系统调用pipe()。管道主要用于在进程之间按照先进先出的方式传送数据,也可以用于使进程
同步执行。有两种类型的管道:有名管道和无名管道。
有名管道是使用文件系统的open调用建立的,而无名管道则使用系统调用pipe()来创建。
在使用管道时,则都用正规文件的read()、write()和close()函数。只有发出pipe调用的后代,
才能共享对无名管道的存取,而所有进程只要权限许可,都可以访问有名管道。

对于管道的读写,可以看出是一个进程从管道的一端写入数据,而另一个进程从管道的另一端读出数据。内核存取管道中数据的方式与存取一般正规文件中的数据方式完全一样。为管道分配存储空间和为正规文件分配空间的不同之处是,管道只是用i节点的直接块。内核将i节点的直接块作为一个循环队列来管理,通过修改读写指针来保证先进先出的顺序。

对于字符设备文件,系统调用read()和write()会调用char_dev.c中的rw_char()函数来操作。字符设备包括控制台终端(tty)、串口终端(ttyx)和内存字符设备。

另外,内核使用文件结构file、文件表file_table[]和内存中的i节点inode_table[]来管理对文件的操作访问。这些数据结构和表的定义可参见头文件include/linux/fs.h。
文件结构file被定义为如下所示:

struct file {
	unsigned short f_mode;		//文件操作模式(RW位)
	unsigned short f_flags;		//文件打开和控制的标志。
	unsigned short f_count;		//对应文件句柄引用计数。
	struct m_inode * f_inode;	//指向对应内存i节点,即现在系统中的v节点。
	off_t f_pos;				//文件当前读写指针位置。
};
struct file file_table[NR_FILE];	//文件表数组,共64项。

它用于在文件句柄和内存i节点表中i节点项之间建立关系。其中文件类型和访问属性字段
f_mode与文件i节点结构中i_mode字段的含义相同,见前面的描述;

f_flags字段是打开文件调用函数open()中参数flag给出的一些打开操作控制标志的组合,
这些标志定义在include/fcntl.h中。其中有以下标志:

//打开文件open()和文件控制函数fcntl()使用的文件访问模式。同时只能使用三者之一。
#define O_RDONLY 00//以只读方式打开文件。
#define O_WRONLY 01//以只写方式打开文件。
#define O_RDWR 02//以读写方式打开文件。

//下面是文件创建和操作标志,用于open()。可与上面访问模式用"位或"的方式一起使用。
#define O_CREAT 00100 //如果文件不存在就创建。fcntl函数不用。
#define O_EXCL 00200 //独占使用文件标志。
#define O_NOCTTY 00400 //不分配控制终端。
#define O_TRUNC 01000 //若文件已存在且是写操作,则长度截为0.
#define O_APPEND 02000 //已添加方式打开,文件指针置为文件尾。
#define O_NONBLOCK 04000 //非阻塞方式打开和操作文件。
#define O_NDELAY O_NONBLOCK //非阻塞方式打开和操作文件。

file结构中的文件引用计数字段f_count指出本文件被文件句柄引用的次数计数;
内存i节点结构字段f_inode指向本文件对应i节点表中的内存i节点结构项。
文件表是内核中由文件结构项组成的数组,在Linux0.12内核中文件表最多可有64项,
因此整个系统同时最多打开64个文件。在进程的数据结构(即进程控制块或称进程描述符)中,
专门定义了本进程打开文件结构指针数组filp[NR_OPEN]字段。其中NR_OPEN=20,因此每个进程最多可同时
打开20个文件。该指针数组项的顺序号即对应文件的描述符值,而项的指针则指向文件表中打开的文件项。

例如,filp[0]即是进程当前打开文件描述符0对应的文件结构指针。

内核中i节点表inode_table[NR_INODE]是由内存i节点结构组成的数组,其中NR_INODE=32,
因此在某一时刻内核中同时只能保存32个内存i节点信息。一个进程打开的文件和内核文件
表以及相应内存i节点的关系可用图12-13来表示。图中一个文件被作为进程的标准输入打开
(文件句柄0),另一个被作为标准输出打开(文件句柄1)。

12-1-6 文件和目录管理系统调用
有关文件系统调用的上层实现,基本上包括图12-14中5个文件。

图12-14 文件系统上层操作程序
在这里插入图片描述

open.c文件用于实现与文件操作相关的系统调用。主要有文件的创建、打开和关闭,文件
宿主和属性的修改、文件访问权限的修改、文件操作时间的修改和系统文件系统root的变动等。

exec.c程序实现对二进制可执行文件和shell脚本文件的加载与执行。其中主要的函数是函数do_execve(),
它是系统中断调用(int 0x80)功能号__NR_execve()调用的C处理函数,是exec()函数簇的主要实现函数。

fcntl.c实现了文件控制系统调用fcntl()和两个文件句柄(描述符)复制系统调用dup()和
dup2()。dup2()指定了新句柄的数值,而dup()则返回当前值最小的未用句柄。句柄复制操作
要用在文件的标准输入/输出重定向和管道操作方面。

ioclt.c文件实现了输入/输出控制系统调用ioctl()。主要调用tty_ioctl()函数,对终端的I/O进行控制。

stat.c文件用于实现取文件状态信息调用stat()和fstat()。stat()是利用文件名取信息,而
fstat()是使用文件句柄(描述符)来取信息。

12-1-7 360KB软盘中文件系统实例分析
[619页]
看懂赵老师操作就可以,但没有理解最大文件长度(显示有误)。

[617页]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值