实验四 PROC文件系统
操作系统课程设计proc文件系统
得到有用的系统/内核信息
proc 文件系统可以被用于收集有用的关于系统和运行中 的内核的信息。下面是一些重要的文件:
• • • • • • • • /proc/cpuinfo - CPU 的信息 (型号, 家族, 缓存大小等) /proc/meminfo - 物理内存、交换空间等的信息 /proc/mounts - 已加载的文件系统的列表 /proc/devices - 可用设备的列表 /proc/filesystems - 被支持的文件系统 /proc/modules - 已加载的模块 /proc/version - 内核版本 /proc/cmdline - 系统启动时输入的内核命令行参数
操作系统 课程设计
proc 文件系统
proc
• proc 文件系统是 Linux 中的特殊文件系统,提供 给用户一个可以了解内核内部工作过程的可读窗 口,在运行时访问内核内部数据结构、改变内核 设置的机制。
保存系统当前工作的特殊数据,但并不存在于任何物
理设备中;
对其进行读写时,才根据系统中的相关信息即时生成;
• 同学们在实验课程中重新编译过 Linux 内核, 有些同学可能会发现在内核的配置过程中,有 很多设备驱动程序和其他内核元素都被编译成 了模块。如果一个驱动程序被直接编译到了内 核中,那么即使这个驱动程序没有运行,它的 代码和静态数据也会占据一部分空间。但是如 果这个驱动程序被编译成一个模块,就只有在 需要内存并将其加载到内核时才会真正占用内 存空间。有趣的是,对于 LKM 来说,我们不 会注意到有什么性能方面的差异,因此这对于 创建一个适应于自己环境的内核来说是一种功 能强大的手段,这样可以根据可用硬件和连接 的设备来加载对应的模块。
proc 中的文件远不止上面列出的这么多。想要进一步了 解,可以对 /proc 的每一个文件都'more'一下。
proc 文件系统
什么是proc文件系统?proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
它以文件系统的方式为访问系统内核数据的操作提供接口。
用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。
由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
它的目录结构如下:目录名称目录内容apm 高级电源管理信息cmdline 内核命令行Cpuinfo 关于Cpu信息Devices 可以用到的设备(块设备/字符设备)Dma 使用的DMA通道Filesystems 支持的文件系统Interrupts 中断的使用Ioports I/O端口的使用Kcore 内核核心印象Kmsg 内核消息Ksyms 内核符号表Loadavg 负载均衡Locks 内核锁Meminfo 内存信息Misc 杂项Modules 加载模块列表Mounts 加载的文件系统Partitions 系统识别的分区表Rtc 实时时钟Slabinfo Slab池信息Stat 全面统计状态表Swaps 对换空间的利用情况V ersion 内核版本Uptime 系统正常运行时间并不是所有这些目录在你的系统中都有,这取决于你的内核配置和装载的模块。
另外,在/proc下还有三个很重要的目录:net,scsi和sys。
Sys目录是可写的,可以通过它来访问或修改内核的参数(见下一部分),而net和scsi则依赖于内核配置。
例如,如果系统不支持scsi,则scsi 目录不存在。
除了以上介绍的这些,还有的是一些以数字命名的目录,它们是进程目录。
系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的PID号为目录名,它们是读取进程信息的接口。
而self目录则是读取进程本身的信息接口,是一个link。
Proc文件系统的名字就是由之而起。
进程目录的结构如下:目录名称目录内容Cmdline 命令行参数Environ 环境变量值Fd 一个包含所有文件描述符的目录Mem 进程的内存被利用情况Stat 进程状态Status 进程当前状态,以可读的方式显示出来Cwd 当前工作目录的链接Exe 指向该进程的执行命令文件Maps 内存映象Statm 进程内存状态信息Root 链接此进程的root目录用户如果要查看系统信息,可以用cat命令。
Linux教程第12章 proc文件系统
第12章/proc文件系统实验目的●学习使用/proc文件系统●使用/proc文件系统显示缺页状态●使用/proc文件系统输出超过一个页面的信息。
请注意:你在第一阶段的学习中可以先把重点放在怎样使用proc文件系统上;关于proc 文件系统的内部实现细节,由于牵涉到太多文件系统原理与相关概念,建议你在学习完本书《文件系统》这一章之后,在回过头来对照相应代码进行分析。
实验内容1. 在/proc文件系统中添加必要的节点,以统计操作系统发生的缺页中断次数。
2. 实现一个proc文件接口,每次当用户读取这个proc文件的时候,要求打印出系统中所有进程的pid,comm,start_time,utime,stime,policy,priority 实验原理12.1 /proc文件系统procfs,是process fs的缩写。
最开始的时候只是一些进程相关的信息的集合,Linux 扩展了这个概念,可以通过/proc文件系统交互几乎任何内核的信息。
/proc不是一个真正的文件系统(这么说的意思是,/proc不像普通的文件系统是用于管理磁盘上的文件,并且要占用磁盘上的空间;/proc只存在于内存中,更确切地说是只有管理模块存在于内存中,所有具体的信息都动态地从运行中的内核里面读取)。
proc文件系统的历史有点复杂,基本上,随着Unix的演化而到了今天这个样子,为我们带来方便。
/proc文件系统是一个接口,用户与内核交互的接口,用户从/proc文件系统中读取很多内核释放出来的信息(包括内核各个管理模块的动态信息,CPU信息,硬件驱动释放出来的信息等等);同时内核也可以在必要的时候从用户得到输入,进而改变内核的变量,或者运行状态。
/proc文件系统中主要包含两方面的文件(或者说主要有两个大的用途):一是只读文。
proc文件系统介绍
proc⽂件系统介绍(1)linux内核是⼀个⾮常庞⼤、⾮常复杂的⼀个单独的程序,对于这样的⼀个程序来说调试是⾮常复杂的。
(2)项kernel这样庞⼤的项⽬,给⾥⾯添加/更改⼀个功能是⾮常⿇烦的,因为你这添加的⼀个功能可能会影响其他已经有的。
(3)早期内核版本中尽管调试很⿇烦,但是⾼⼿们还可以凭借个⼈超凡脱俗的能⼒去驾驭。
但是到了2.4左右的版本的时候,这个难度已经⾮常⼤了。
(4)为了降低内核调试和学习的难度,内核开发者们在内核中添加了⼀些属性专门⽤于调试内核,proc⽂件系统就是⼀个尝试。
(5)proc⽂件系统的思路是:在内核中构建⼀个虚拟⽂件系统/proc,内核运⾏时将内核中⼀些关键的数据结构以⽂件的⽅式呈现在/proc⽬录中的⼀些特定⽂件中,这样相当于将不可见的内核中的数据结构以可视化的⽅式呈现给内核的开发者。
(6)proc⽂件系统给了开发者⼀种调试内核的⽅法:我们通过实时的观察/proc/xxx⽂件,来观看内核中特定数据结构的值。
在我们添加⼀个新功能的前后来对⽐,就可以知道这个新功能产⽣的影响对还是不对。
(7)proc⽬录下的⽂件⼤⼩都是0,因为这些⽂件本⾝并不存在于硬盘中,他也不是⼀个真实⽂件,他只是⼀个接⼝,当我们去读取这个⽂件时,其实内核并不是去硬盘上找这个⽂件,⽽是映射为内核内部⼀个数据结构被读取并且格式化成字符串返回给我们。
所以尽管我们看到的还是⼀个⽂件内容字符串,和普通⽂件⼀样的;但是实际上我们知道这个内容是实时的从内核中数据结构来的,⽽不是硬盘中来的。
1、常⽤proc中的⽂件介绍(1)/proc/cmdline(2)/proc/cpuinfo(3)/proc/devices(4)/proc/interrupts2、proc⽂件系统的使⽤cat以⼿⼯查看程序中可以⽂件IO访问在shell程序中⽤cat命令结合正则表达式来获取并处理内核信息#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>int main(int argc ,char **argv){int fd=-1;char buf[500]={0};if(argc!=2){printf("eg: %s -d|-v\n",argv[0]);return -1;}if(!strcmp(argv[1],"-v")){fd=open("/proc/version",O_RDONLY);read(fd,buf,sizeof(buf));printf("结果:\n%s\n",buf);}else if(!strcmp(argv[1],"-d")){fd=open("/proc/devices",O_RDONLY);read(fd,buf,sizeof(buf));printf("结果:\n%s\n",buf);}}3、扩展:sys⽂件系统(1)sys⽂件系统本质上和proc⽂件系统是⼀样的,都是虚拟⽂件系统,都在根⽬录下有个⽬录(⼀个是/proc⽬录,另⼀个是/sys⽬录),因此都不是硬盘中的⽂件,都是内核中的数据结构的可视化接⼝。
proc 文件系统
该函数将创建一个目录,父目录为parent。
proc文件系统的编程接口
删除节点(文件或者目录)remove_proc_entry()
void remove_proc_entry ( const char *name, struct proc_dir_entry *parent)
该函数将删除一个proc节点(按文件名删除)。
proc文件系统的编程接口
以上五个创建节点的函数在内核中的实现流程:
通过proc_create为结构申请空间,并进行一些初始化工 作。 proc_register则进一步填写结构中的域。并完成注册工作
删除节点的函数在内核中的实现流程:
则是先调用clear_bit和proc_kill_inodes,注销inode结构 ,如果引用数为0,则调用free_proc_entry释放结构对应 的空间;否则置一个删除标志,不释放空间
proc文件系统的编程接口
创建设备文件proc_mknod()
struct proc_dir_entry *proc_mknod( const char *name, mode_t mode, struct proc_dir_entry *paren建一个名字为name的设 备文件,文件类型和权限为mode,设备号为rdev 。
操作系统 课程设计
proc 文件系统
proc
proc 文件系统是 Linux 中的特殊文件系统,提供 中的特殊文件系统, 给用户一个可以了解内核内部工作过程的可读窗 口,在运行时访问内核内部数据结构、改变内核 在运行时访问内核内部数据结构、 设置的机制。 设置的机制。
保存系统当前工作的特殊数据,但并不存在于任何物 理设备中; 对其进行读写时,才根据系统中的相关信息即时生成 ;或映射到系统中的变量或数据结构; proc 被称为‘伪文件系统’; 其挂接目录点固定为/proc; ‘man proc’ 进行了详细说明。
第4章文件系统实验
1.用于接收数据的地址(指针)(buffer)
2.单个元素的大小(size):单位是字节而不是位,例如读取一个int型数据就是4个字节
3.元素个数(count)
4.提供数据的文件指针(stream)
返回值:读取的元素的个数
(3)
通过strstr()函数将找出cpu MHz在buffer出现的位置,为之后的提取值做准备
1.切换用户
2.建立文件,并查看文件
3.创建软连接ຫໍສະໝຸດ 4.查看创建结果5.查看结果
6.修改test
7.查看结果
分析结果
(1)创建链接后,读取test1的时候,由于链接的原因,实际上读取到的是test的内容,所以读取test.txt和test01时显示的内容是一样的。修改test之后,test01也会跟着改变,显示了同步性。
format格式控制字符串
argument选择性设定字符串
sscanf会从buffer里读进数据,依照argument的设定将数据写回。
三、实现文件的拷贝,即把一个文件内容复制到另一个文件
1.创建文件
2.编译代码
3.运行
4.创建t1,t2
5.运行copy代码
6.查看结果
7.删除t1
8.查看t2
结果分析:
strstr()
包含文件:string.h
函数原型:extern char *strstr(char *str1, char *str2);
功能:找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符)。
返回值:返回该位置的指针,如找不到,返回空指针。
(4)
通过sscanf语句提取cpu的时钟频率
操作系统课程实验报告
proc文件系统 国防科大操作系统课件
我要加可个载以叫模加he载块llo,的不pr过oc要文给件我,创到建时一候
程序p工roc作_如t流e果s读t程写这(1个)文件,你就找 hello_read和hello_write
用户要 加载你 们这个 模块了
内核
hello_ hello_
init_module read write
好吧, 我同意 创建文 件。
我要写文件
程序h工ell作o 流程 (2)
用户要写文
件了,要写
的内容是 12345。怎 么办?
内核
知道了,我已 经记下来了。
hello_write
12345
程序我 h工e要ll作o读流文件这 出 h程el个 的lo(文 内m3e件 容)ss可是ag以:e:读。读
More write: 12345
创建proc文件
• 在上面的例子中,我们看到,通过编写一段 程序,在/proc目录下创建了如下内容:
一个名叫proc_test的子目录。 一个名叫current的文件,只读,读出的内容是
读它的进程的情况。
一个名叫current_too的链接,指向current。 一个名叫hello的文件,可读可写。读出的内容是
proc文件和用户的交互
• 当用户(用户态程序)写proc文件时,内核调 用预先设定的写函数。(回调)
• 写函数的例子,请看例子程序里面的 proc_write_hello函数。
• 参数2,3对我们有用,分别表示要写什么东西 进去,要写多少字节。
• 注意要用copy_from_user函数。 • global_buffer是我们用来保存数据的缓冲区。
gcc -c -I/usr/src/linux-2.4.208/include proc_test.c
实验指导书--实验11 Linux proc文件系统
实验十一:Linux proc文件系统实验学时:4实验类型:验证实验要求:选修一、实验目的通过本实验的学习,理解和分析proc文件系统,掌握Linux proc文件的特点和使用方法,访问有关内核的状态、计算机的属性、正在运行的进程状态等信息。
二、实验内容实验内容:了解proc文件系统,编写一个c程序,获取系统相关信息,实时监测(周期性显示)CPU、主存和网络的详细使用情况以及它们的利用率。
三、实验原理、方法和手段实验原理:proc 文件系统介绍:proc 文件系统是一个虚拟文件系统,是一种内核和内核模块用来向进程(process) 发送信息的机制 (所以叫做proc)。
这个虚拟文件系统让你可以和内核内部数据结构进行交互,获取有关进程的有用信息,在运行中 (on the fly) 改变设置 (通过改变内核参数)。
与其他文件系统不同,proc 存在于内存之中而不是硬盘上。
proc文件系统包含一些目录和虚拟文件。
大部分proc中的文件和目录提供系统物理环境最新的信息。
/proc目录中有一些以数字命名的目录,它们是进程目录。
系统中当前运行的每一个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。
此外,在Linux2.6.0-test6以上的版本中/proc/pid 目录中有一个task目录,/proc/pid/task目录中也有一些以该进程所拥有的线程的线程号命名的目录/proc/pid/task/tid,它们是读取线程信息的接口。
/proc 由内核控制,没有承载 /proc 的设备。
因为 /proc 主要存放由内核控制的状态信息,所以大部分这些信息的逻辑位置位于内核控制的内存。
对/proc 进行一次 'ls -l' 可以看到大部分文件都是 0 字节大的;不过察看这些文件的时候,确实可以看到一些信息。
这是因为 /proc 文件系统和其他常规的文件系统一样把自己注册到虚拟文件系统层 (VFS) 了。
课件:实验教案-模块参数及Proc文件系统
三、实验内容:
➢ 写一个简单的字符设备驱动程序,要求:
定义一个全局结构指针,初始值为NULL,该数据结构中包 含一个大小为N的buffer;
在open中对该全局结构进行NULL判断,为NULL则为其分配 内存,并将buffer初始化为0;
在release中释放buffer; 通过读proc文件系统对该buffer进行读取; 通过写proc文件系统对该buffer进行赋值; 在加载过程中指定模块参数N,Buffer的大小。
第二次上机实验
1
பைடு நூலகம்
一、实验目的
➢ 掌握简单字符设备驱动程序中模块参数及Proc文件系 统的编写方法。
➢ 学习利用模块参数进行驱动程序参数传递,学习利用 Proc文件系统进行数据读写。
2
二、实验要求
➢ 按实验内容编写驱动程序 ➢ 编译驱动程序 ➢ 在嵌入式设备上加载驱动程序并利用Proc文件系统的
读写进行驱动程序测试
四、实验步骤:
➢ 参考《嵌入式系统设计》课程第05讲内容,根据实验 内容要求设计编写驱动程序
➢ 编译和加载驱动程序 ➢ 进行驱动程序测试 ➢ 卸载驱动程序
实验四文件系统实验
实验四文件系统实验一. 目的要求1、用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
2、要求设计一个n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令。
二. 例题:1、设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。
2、程序采用二级文件目录(即设置主目录[MFD])和用户文件目录(UED)。
另外,为打开文件设置了运行文件目录(AFD)。
3、为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。
4、算法与框图:①因系统小,文件目录的检索使用了简单的线性搜索。
②文件保护简单使用了三位保护码:允许读写执行、对应位为1,对应位为0,则表示不允许读写、执行。
③程序中使用的主要设计结构如下:主文件目录和用户文件目录(MFD、UFD)打开文件目录(AFD)(即运行文件目录)文件目录指针文件名··文件系统算法的流程图如下:三. 实验题:1、增加2~3个文件操作命令,并加以实现。
(如移动读写指针,改变文件属性,更换文件名,改变文件保护级别)。
代码如下://1、增加2~3个文件操作命令,并加以实现。
(如移动读写指针,改变文件属性,更换文件名,改变文件保护级别)。
#include<iostream>#include<string>#include<conio.h>using namespace std;struct TYPE_UFD{string File_Name;bool Read;bool Write;bool Execute;int Length_File;};struct TYPE_MFD{string User_Name;TYPE_UFD *Pointer;};struct TYPE_AFD{int File_ID;bool Read;bool Write;bool Execute;int Pointer;};class TYPE_FILE_SYSTEM{public:void Initial( void );void Start( void );private:int _Number_Users;int _Number_Files;int _MaxNumber_Open_Files;TYPE_MFD *_MFD;TYPE_UFD *_UFD;TYPE_AFD *_AFD;};void TYPE_FILE_SYSTEM::Initial( void ){_Number_Users = 10;_Number_Files = 10;_MaxNumber_Open_Files = 5;_UFD = new TYPE_UFD [_Number_Users*_Number_Files];_MFD = new TYPE_MFD [_Number_Users];int i=0;for( i=0 ; i<_Number_Users ; i++ ){_MFD[i].Pointer = &(_UFD[i*_Number_Files]);}_AFD = new TYPE_AFD [_MaxNumber_Open_Files];_MFD[0].User_Name = "zaq";_UFD[0].File_Name = "file1.txt";_UFD[0].Length_File = 10;_UFD[0].Read = true;_UFD[0].Write = false;_UFD[0].Execute = true;_UFD[1].File_Name = "file2.txt";_UFD[1].Length_File = 20;_UFD[1].Read = true;_UFD[1].Write = false;_UFD[1].Execute = false;for( i=2 ; i<_Number_Files ; i++ ){_UFD[i].File_Name = "";_UFD[i].Length_File = -1;_UFD[i].Read = false;_UFD[i].Write = false;_UFD[i].Execute = false;}}void TYPE_FILE_SYSTEM::Start( void ){int User_ID;int i,temp_int;string temp;char choice;int Number_Open_Files;string User_Name;string Command;TYPE_UFD *UFD;do{do{cout << "已创建用户名为zaq\n指令有:create delete open dir diropen write read logout shutdown \n\n";cout << "请输入用户名:";cin >> User_Name;for( User_ID=0 ; User_ID<_Number_Users ; User_ID++ ){if( _MFD[User_ID].User_Name == User_Name )break;}if( User_ID == _Number_Users )cout << "用户名错误,请再次输入." << endl;}while( User_ID == _Number_Users );cout << "欢迎登录, " << User_Name << " !" << endl;UFD = _MFD[User_ID].Pointer;for( i=0 ; i<_MaxNumber_Open_Files ; i++ ){_AFD[i].File_ID = -1;}Number_Open_Files = 0;do{cout << "C:\\" << User_Name << ">" ;cin >> Command;if( Command == "dir" ){cout << endl;cout << "打开用户" << User_Name <<"的文件" << endl;cout << "\t" << "State\t" << "Length\t" << "File name" << endl;for( i=0 ; i<_Number_Files ; i++ ){if( UFD[i].Length_File != -1 ){cout << "\t" ;if( UFD[i].Read == true )cout << "R";elsecout << "-";if( UFD[i].Write == true )cout << "W";elsecout << "-";if( UFD[i].Execute == true )cout << "E";elsecout << "-";cout << "\t";cout << UFD[i].Length_File;cout << "\t";cout << UFD[i].File_Name << endl;}}cout << endl;}else if( Command == "diropen" ){cout << endl;cout << "打开用户" << User_Name << "的文件"<<endl;cout << "\t" << "State\t" << "Open File name" << endl;for( i=0 ; i<_MaxNumber_Open_Files ; i++ ){if( _AFD[i].File_ID != -1 ){cout << "\t" ;if( _AFD[i].Read == true )cout << "R";elsecout << "-";if( _AFD[i].Write == true )cout << "W";elsecout << "-";if( _AFD[i].Execute == true )cout << "E";elsecout << "-";cout << "\t";cout << UFD[_AFD[i].File_ID].File_Name << endl;}}cout << endl;}else if( Command == "create" ){for( i=0 ; i<_Number_Files ; i++ )if( UFD[i].Length_File == -1 )break;if( i == _Number_Files )cout << "Error: 已有名为" << _Number_Files << " 的文件." << endl;else{cout << "请输入新文件信息:" << endl;cout << "文件名: ";cin >> temp;UFD[i].File_Name = temp;cout << "文件权限: ";cout << "Read (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )UFD[i].Read = true;elseUFD[i].Read = false;cout << endl;cout << "Write (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )UFD[i].Write = true;elseUFD[i].Write = false;cout << endl;cout << "Execute (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )UFD[i].Execute = true;elseUFD[i].Execute = false;cout << endl;cout << "Length :";cin >> temp_int;if( temp_int > 0 )UFD[i].Length_File = temp_int;cout << "新文件" << UFD[i].File_Name << " 已建立!" << endl;}}else if( Command == "delete" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{UFD[i].Length_File = -1;cout << "文件" << UFD[i].File_Name << " 已删除." << endl;}}else if( Command == "open" ){if( Number_Open_Files == _MaxNumber_Open_Files )cout << "Error: 你已经打开了" <<Number_Open_Files << " 文件." << endl;else{cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{Number_Open_Files++;for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == -1 )break;_AFD[temp_int].File_ID = i;_AFD[temp_int].Pointer = 0;cout << "请定义打开方式:" << endl;if( UFD[i].Read == true ){cout << "Read (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )_AFD[temp_int].Read = true;else_AFD[temp_int].Read = false;cout << endl;}else_AFD[temp_int].Read = false;if( UFD[i].Write == true ){cout << "Write (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )_AFD[temp_int].Write = true;else_AFD[temp_int].Write = false;cout << endl;}else_AFD[temp_int].Write = false;if( UFD[i].Execute == true ){cout << "Execute (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )_AFD[temp_int].Execute = true;else_AFD[temp_int].Execute = false;cout << endl;}else_AFD[temp_int].Execute;cout << "文件" << temp << " 已打开." << endl;}}}else if( Command == "logout" ){cout << "再见, " << User_Name << " !" << endl;break;}else if( Command == "close" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == i )break;if( temp_int == _MaxNumber_Open_Files )cout << "文件" << temp << " 未打开." << endl;else{_AFD[temp_int].File_ID = -1;Number_Open_Files--;cout << "文件" << temp << " 已关闭." << endl;}}}else if( Command == "read" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == i )break;if( temp_int == _MaxNumber_Open_Files )cout << "文件" << temp << " 未打开." << endl;else{if( _AFD[temp_int].Read == true )cout << "文件" << temp << " 成功读取." << endl;elsecout << "Error: 文件打开模式错误." << endl;}}}else if( Command == "write" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == i )break;if( temp_int == _MaxNumber_Open_Files )cout << "文件" << temp << " 未打开." << endl;else{if( _AFD[temp_int].Write == true )cout << "文件" << temp << " 成功写入." << endl;elsecout << "Error: 文件打开模式错误." << endl;}}}else if( Command == "shutdown" ){cout << "正在注销........" << endl;cout << "再见, " << User_Name << " !" << endl;cout << "正在关机.........." << endl;break;}else{cout << "指令错误,请再次输入." << endl;}}while( Command != "logout" && Command != "shutdown" );}while( Command != "shutdown" );}int main(){TYPE_FILE_SYSTEM FS;FS.Initial();FS.Start();return 0;}2、编一个通过屏幕选择命令的文件管理系统,每屏要为用户提供足够的选择信息,不需要打入冗长的命令。
proc文件系统
proc文件系统proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
它以文件系统的方式为访问系统内核数据的操作提供接口。
用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。
由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
它的目录结构如下:目录名称目录内容apm 高级电源管理信息cmdline 内核命令行Cpuinfo 关于Cpu信息Devices 可以用到的设备(块设备/字符设备)Dma 使用的DMA通道Filesystems 支持的文件系统Interrupts 中断的使用Ioports I/O端口的使用Kcore 内核核心印象Kmsg 内核消息Ksyms 内核符号表Loadavg 负载均衡Locks 内核锁Meminfo 内存信息Misc 杂项Modules 加载模块列表Mounts 加载的文件系统Partitions 系统识别的分区表Rtc 实时时钟Slabinfo Slab池信息Stat 全面统计状态表Swaps 对换空间的利用情况Version 内核版本Uptime 系统正常运行时间并不是所有这些目录在你的系统中都有,这取决于你的内核配置和装载的模块。
另外,在/proc 下还有三个很重要的目录:net,scsi和sys。
Sys目录是可写的,可以通过它来访问或修改内核的参数(见下一部分),而net和scsi则依赖于内核配置。
例如,如果系统不支持scsi,则scsi目录不存在。
除了以上介绍的这些,还有的是一些以数字命名的目录,它们是进程目录。
系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的PID号为目录名,它们是读取进程信息的接口。
而self目录则是读取进程本身的信息接口,是一个link。
Proc文件系统的名字就是由之而起。
进程目录的结构如下:目录名称目录内容Cmdline 命令行参数Environ 环境变量值Fd 一个包含所有文件描述符的目录Mem 进程的内存被利用情况Stat 进程状态Status 进程当前状态,以可读的方式显示出来Cwd 当前工作目录的链接Exe 指向该进程的执行命令文件Maps 内存映象Statm 进程内存状态信息Root 链接此进程的root目录用户如果要查看系统信息,可以用cat命令。
proc文件系统
10
seq_file操作procfs步骤( seq_open 1)
I. 在proc文件下创建自己的文件 static inline struct proc_dir_entry *proc_create(
const char *name, umode_t mode, struct proc_dir_entry *parent,
create_proc_read_entry 和create_proc_entry接口在新版 本的内核中已经废弃
4
seq_file
内核通过在procfs文件系统下建立文件来向用户空间提供输出信息, 用户空间可以通过任何文本阅读应用查看该文件信息,但是procfs 有 一个缺陷,如果输出内容大于1个内存页,需要多次读,因此处理起来 很难,另外,如果输出太大,速度比较慢,有时会出现一些意想不到 的情况。
6
seq_file操作procfs的方式
single_open方式 此种方式为简单方式对应的释放函数为 single_release seq_open方式 此种方式为复杂方式对应的释放函数为 seq_release
7
seq_file操作procfs步骤( single_open 1)
I. 在proc文件下创建自己的文件
procfs
2
proc文件系统概要
虚拟文件系统
驻留于内存、不占用存储空间
创建和显示内核内部的资源视窗
数据是在内核运行过程中产生的
用于配置内核参数、查看内核结构体、从设备驱 动程序中收集统计信息、获取通用的系统信息 在系统启动过程中挂载在/proc目录
3
proc文件系统操作示例1
糟 糕 的 实 现 方 式
在结束时候被调用,完成一些清理工作
proc文件系统实现原理
proc文件系统实现原理
proc文件系统是一种特殊的文件系统,主要用于内核和用户程序之间的交互。
它以文件的形式提供访问接口,用户可以通过读取或修改这些文件来获取或改变内核的一些运行时信息或行为。
当用户读取proc文件时,实际上是在读取内存中的数据。
由于proc文件系统没有实际的存储介质,因此读取的数据是动态生成的。
当用户写入proc文件时,实际上是调用了内核中与该文件关联的写函数。
这些写函数可以用来改变内核的某些行为。
由于proc文件系统存在于内存中,并且不占用实际的存储空间,因此它是一种虚拟文件系统。
proc文件系统的实现原理主要是通过内核提供的一组接口函数来完成的。
这些函数可以用于创建、删除、读取和写入proc文件。
当用户访问/proc目录下的某个文件时,内核会根据该文件的路径找到对应的函数,并调用该函数来生成或处理数据。
由于proc文件系统主要用于内核和用户程序之间的交互,因此它的设计目标是提供一种方便、高效的方式来获取和修改内核的运行时信息或行为。
Proc文件系统
/proc 文件系统是一种特殊的、由软件创建的文件系统,内核使用它向外界导出信息。
/proc 下面的每个文件都绑定与一个内核函数,用户读取其中的文件时,该函数动态地声称文件的内容。
我已经见过这类文件的一些输出情况,例如:/proc/modules列出的是当前载入模块的列表。
在Linux系统对/proc的使用很频繁。
现代Linux发行版中的很多工具都是通过/proc来获取它们所需要的信息,例如:ps、top、uptime等。
有些设备驱动程序也通过/proc导出信息。
我们自己的驱动程序当然也可以这么做。
因为/proc文件系统是动态的,所以驱动程序模块可以在任何时候添加或删除其中的入口项。
具有完整特征的/proc入口项可以相当复杂;在所有的这些特征当中,有一点要指出的是,这些/proc文件不仅可以用于读出数据,也可以用于写入数据。
不过,大多数时候,/proc 入口项是只读文件。
本节将只涉及简单的只读情形。
在/proc中实现文件所有使用/proc的模块必须包含</linux/proc_fs.h>,并通过这个头文件来定义正确的函数。
为创建一个只读的/proc文件,驱动程序必须实现一个函数,用于在读取文件时生成数据。
当某个进程读取这个文件时,读取请求会通过这个函数发送到驱动程序模块。
我们把注册接口放在本节后面,先直接讲这个函数。
在某个进程读取我们的/proc文件时,内核会分配一个内存页(即PAGE_SIZE字节的内存块),驱动程序可以将数据通过这个内存页返回到用户空间。
该缓冲区会传入我们定义的函数,而这个函数称为read_proc方法:Int(* read_proc)(char *page , char ** start , off_t offset , int count , int *eof , void *data)参数表中的page指针指向用来写入数据的缓冲区;函数应使用start返回实际的数据写到内存页的哪个位置;offset 和count这两个参数与read方法相同;eof 参数指向一个整数,当没有数据可返回时,驱动程序必须设置这个参数;data 参数是提供给驱动程序的专用数据指针,可用于内部记录。
操作系统实验四 文件系统实验
return
scanf("%s",s); strcpy(t->fileName,s); printf("\n 请输入该文件基本信息:"); scanf("%s",s); strcpy(t->file,s); t->brother=t->child=NULL; if(p->child==NULL) {
goto label; } p=p->next; } printf("文件不存在!\n"); goto label; } else if(i==8) { show(f); goto label; } else { goto label; } } void Select() { char username[20]; int i; printf("请输入用户名:\n"); scanf("%s",username); for(i=0; i<userNum; i++) { if(!strcmp(mdf[i].userName,username)) { fp= mdf[i].p; if(fp!=NULL) {
printf("该用户已创建文件:\n"); while(fp!=NULL) {
fp=fp->next; printf("%s\n",fp->fileName); } } else { printf("该用户尚未创建任何文件!\n"); } fp= mdf[i].p; Operation(fp); }
#include <stdio.h> #include <stdlib.h> #include <string.h> #define getpch(type) (type*)malloc(sizeof(type)) int userNum=0;
实验1:使用proc文件系统
实验1:使用proc文件系统:读/proc/stat文件,计算并显示系统CPU占用率和用户态CPU占用率。
(需要使用fopen(),fscanf(),printf())
实验步骤:
1)使用man命令了解/proc/stat文件的内容和格式:
man proc
2)使用man命令了解下列函数的使用方法:
fopen:
原型:FILE *fopen( const char *filename, const char *mode );
以打开一个流(文件)。
filename——文件名,mode——访问许可类型。
fscanf:
原型:int fscanf( FILE *stream, const char *format [, argument ]... );
从流中读取格式化的数据。
例子fscanf (fp ,"cpu %ld", &user)是指跳过字符串"cpu "及其前面的字符流,读取一个长整数并存入user中。
其中fp为文件流指针。
%ld对应长整数,%d 对应整数,%s对应字符串。
fclose:
原型:int fclose( FILE *stream );
关闭流(文件)。
3)用c语言编程
总CPU时间= 用户占用时间+系统占用时间+优先进程占用时间+闲置进程占用时间系统CPU占用率= 系统占用时间/ 总CPU时间
用户态CPU占用率 = 用户占用时间/ 总CPU时间
4)编译和运行。
实验4:文件系统实验指导
实验4:文件系统的设计与模拟实现一、实验目的和要求1. 学习LINUX系统下对文件进行操作的各种命令和图形化界面的使用方法,深入学习和掌握文件管理系统的基本原理。
2. 掌握LINUX等操作系统下常用的系统调用,编写一个使用系统调用的例程。
3. 运用所学的操作系统文件管理机制的相关知识设计一个简单多用户文件系统,要求具有分级文件目录、文件分权限操作、用户管理等,模拟文件管理的工作过程,加深理解文件系统的内部功能及内部实现机制。
二、实验指导(一)LINUX系统下对文件进行操作的命令和图形化界面的使用方法1、目录/proc下与系统相关的文件和目录(1) /proc/$pid/fd:这是一个目录,该进程($PID号码进程)每个打开的文件在该目录下有一个对应的文件。
例如:#ls /proc/851/fd0 1 2 255这表示,851号进程目前正在使用(已经打开的)文件有4个,它们的描述符分别是0、1、2、255。
其中,0、1、2 依次分别是进程的标准输入、标准输出和标准错误输出设备。
(2)/proc/filesystems:该文件记录了可用的文件系统类型。
(3)/proc/mounts:该记录了当前被安装的文件系统信息例如:#cat /proc/mount(4)/proc/$pid/maps:该文件记录了进程的映射内存区信息。
例如:#cat /proc/851/maps2.常用命令讲解ls 命令用来查看用户有执行权限的任意目录中的文件列表,该命令有许多有趣的选项。
例如:$ ls -liah *22684 -rw-r--r-- 1 bluher users 952 Dec 28 18:43 .profile19942 -rw-r--r-- 1 scalish users 30 Jan 3 20:00 test2.out925 -rwxr-xr-x 1 scalish users 378 Sep 2 2002 test.sh上面的列表显示8 列:第 1 列指示文件的inode,因为我们使用了-i 选项。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四 PROC文件系统
预备知识
proc文件系统功能 proc文件描述
proc进程目录结构
实验指导
proc信息获取
终端图形编程curses
图形界面编程GTK和Qt
实验目的、内容
2.1 proc信息获取—获取性能参数
读取proc文件系统,能获取系统各种性能参数
CPU使用率:/proc/stat 来源数据:用户模式(user)、低优先级用户模式(nice)、内核模式 (system)和空闲的处理器时间(idle) 计算方法:100 * (user+nice+system) / (user+nice+system+idle) 内存使用情况:/proc/meminfo 来源数据:当前内存使用量(cmem)、内存总量(amem) 计算方法:100 * (cmem / amem) 网络负载情况:/proc/net/dev 来源数据:从本机输出的数据包数(output)、流入本机的数据包数 (input) 计算方法:(output+input) / 2
2.2 终端图形编程curses—在屏幕上显 示字符
echochar(char) / addch(ch) 显示某个字符 mvaddch(y,x,ch) 在(x,y)上显示某个字符 addstr(str) 显示一串字符 mvaddstr(y,x,str) 在(x,y)上显示一串字符 printw(format,str) 以一定的格式输出至屏幕 mvprintw(y,x,format,str) 在(x,y)位置做printw的工作 getch()、getstr() 从键盘上读取字符/字符串 scanw(format,&arg1,&arg2) 同scanf()读取字符或字符串 ……
2.2 终端图形编程curses—常用的特殊 键
特殊控制字符以KEY_开头定义在curses.h头文件中 使用时必须将keypad设定为TRUE KEY_UP 0403 ↑ KEY_DOWN 0402 ↓ KEY_LEFT 0404 ← KEY_RIGHT 0405 → KEY_HOME 0406 Home key (upward+left arrow) KEY_BACKSPACE 0407 backspace (unreliable) KEY_F0 0410 Function keys. KEY_F(n) (KEY_F0+(n)) formula for f . KEY_NPAGE 0522 Next page KEY_PPAGE 0523 Previous page
2.1 proc信息获取—调整内核配置
修改内核参数、改变内核状态涉及到的主要文件
/proc/sys
/proc/sys/kernel
/proc/sys/net
存放所有可读写的文件的目录,的网络属性
示例:
允许ip转发:/proc/sys/net/ipv4/ip_forward 禁止ping:/proc/sys/net/ipv4/icmp_echo_ignore_all
区分标准屏幕(stdscr)和当前屏幕(curscr)
标准屏幕(stdscr)代表终端的整个屏幕区域 当前屏幕(curscr)是能够看到的屏幕
2.2 终端图形编程curses—设置函数的 描述
initscr() endwin() cbreak()
开启curses模式 关闭curses模式 该模式下除特殊控制字符外的一切输入 字符立刻被读取 nobreak() 该模式下键盘输入的字符被存在buffer中 直到输入RETURN或NEWLINE echo() / noecho() 输入字符是/否显示在终端上 refresh() 刷新屏幕,一次完成之前所做的变动, 其余信息不变。第一次调用将清除屏幕 move(y,x) 将鼠标移动至x,y位置 getyx(win,y,x) 得到当前鼠标位置 clear() / erase() 将整个屏幕清除,须与refresh()配合使用 ……
2.3 图形界面编程Qt
跨平台的C++图形用户界面应用程序框架 Qt的开源版本不允许用来开发商业软件,否则要付费 基于成熟的C++语言,用面向对象的思想组织 “一次编写、到处编译”:编译出来的程序可运行于Win32、 Linux、Solaris及Mac OS X中,甚至嵌入式系统 组成部分:Qt、基于Framebuffer的Qt Embedded、快速开发 工具Qt Designer、国际化工具Qt Linguist等
包含的内容
系统/内核信息 运行中的进程信息 通过/proc与内核交互(慎重使用)
1.2 proc文件描述
文件提供的系统信息不针对某个特定进程 文件随系统配置的不同而不同 命令procinfo显示基于其中某些文件的多种系统信息 /proc下主要的文件
/proc/cmdline: 内核启动的命令行 /proc/cpuinfo: CPU信息 /proc/devices: 字符和块设备的主设备号及设备名称 /proc/meminfo: 内存状态信息 /proc/modules:可加载内核模块的信息 /proc/mounts:当前系统所安装的文件系统信息 /proc/stat: 所有CPU活动的信息 ……
Glib:底层库,封装基本的数据结构操作、底层功能接口及平台相关
代码 GDK:封装底层访问窗口系统的函数 gdk-pixbuf:客户端的图像处理库 Pango:文本布局和渲染库,是GTK+2.0文本和字体处理的核心 Cairo:2D图形库,支持多种输出设备,支持硬件加速 ATK:一组提供访问性的接口
实验四 PROC文件系统
实验四 PROC文件系统
预备知识
proc文件系统功能 proc文件描述
proc进程目录结构
实验指导
proc信息获取
终端图形编程curses
图形界面编程GTK和Qt
实验目的、内容
1.1 proc文件系统功能
常驻虚拟内存,维持操作系统动态数据的伪文件系统 可以在Linux内核空间和用户空间之间进行通信 进程可用文件系统的方式、通过对虚拟文件的读写实 现与内核内部数据结构的交互
——直接向文件中写入“1”实现相关配置,写入“0”取消 相关配置
2.2 终端图形编程curses—函数库
几乎所有UNIX、Linux操作系统都带curses函数库 curses库提供基本的屏幕操作函数,包括输入/输出、 屏幕初始化、屏幕处理中断及窗口创建等操作 使用方法:
包含头文件curses.h 编译和链接:gcc [flag] file –lcurses
实验四 PROC文件系统
预备知识
proc文件系统功能 proc文件描述
proc进程目录结构
实验指导
proc信息获取
终端图形编程curses
图形界面编程GTK和Qt
实验目的、内容
3.1 实验目的
理解和分析proc文件系统,掌握proc文件的特点和 使用方法 掌握Linux下终端图形编程方法,能编写基于文本的 图形界面 掌握Linux下图形界面编程工具,能用GTK或QT进 行图形界面的开发
2.2 终端图形编程curses—特殊属性
通过变化让输出屏幕画面更为生动: attron(mod) 开启属性 attroff(mod) 关闭属性 A_UNDERLINE 加底线 A_REVERSE 反白 A_BLINK 闪烁 A_BOLD 高亮度 A_NORMAL 标准模式(只能配合 attrset() 使用) ……
1.3 proc进程目录结构
每个进程对应一个用它的PID命名的子目录,是 读取进程信息的接口 包含可以提供有关进程的状态和环境的重要信息 信息的文件
/proc/pid/cmdline:启动进程时调用的命令行 /proc/pid/environ:为该进程定义的所有环境变量 /proc/pid/fd:进程当前打开的所有文件描述符 /proc/pid/mem:进程在内存中的内容 /proc/pid/status:进程当前的状态信息 /proc/pid/exe:指向进程执行的可执行程序的符号链接 /proc/pid/maps:进程的内存映像 ……
3.2 实验内容
实时监测
编写一个C程序,使用Linux下基于文本的终端图形编程库 curses,分窗口实时监测(即周期性刷新显示)CPU、内存和网 络的详细使用情况和它们的利用率
从proc文件系统获取信息
通过读取proc文件系统,获取系统各种信息(如主机名、系统 启动时间、版本号、所有进程信息、CPU使用率、内存使用 率等),并以比较容易理解的方式显示出来。要求:参照 Windows的任务管理器,利用GTK或Qt实现图形界面编程
当使用attron()开启另一种属性时,必须利用attroff()先关闭原 来的属性,或直接以attrset(A_NORMAL)将所有特殊属性关 闭。否则,curses会将两种属性做重叠处理。
2.3 图形界面编程GTK
用于创建图形用户界面的工具包
遵循LGPL许可证,可用来开发开源软件、自由软件或商业 软件,而不需任何花费购买许可证或使用权 面向对象的应用程序接口,完全用C编写,但基于类和回调 函数的思想实现 组成部分