西安郵電大學操作系统课程设计报告书院系名称:计算机学院学生姓名:**专业名称:软件工程班级:**班学号:*****时间:2016年5月9日至2016年5月20日1实验目的操作系统是控制和管理计算机硬件和软件资源的虚拟机,其中的文件系统是对软件和设备进行管理的系统,文件系统是操作系统中非常重要的一个模块,它的实现占用了操作系统源码的最大编码量,其好坏也直接影响着用户对操作系统的感受程度。通过对操作系统课程设计的实践,进一步加深对文件系统的认识和理解,并在此基础上培养学生的工程应用能力。实验分别从用户态和内核态两个层次实践文件系统的部分功能。2实验任务2.1ls实现在linux下编程实现带参数的shell命令ls,ls命令必须支持如下功能。1.基本要求(1)支持-l参数;(2)输出结果按字典排序;(3)列出“.”文件,支持-a参数,在没有-a时候不显示隐藏文件;(4)显示记录总数。2.高级要求(1)支持对给定的目录进行操作,如ls/tmp;(2)输出结果分栏排序,每栏的宽度由这一栏最长的文件名决定,显示的栏数还受终端显示器的宽度影响,每一列尽可能的等宽;(3)正确显示文件特殊属性suid、sgid和sticky,参见联机帮助确保程序能处理各种情况;(4)支持标准的ls支持选项-R,它的功能是递归地列出目录中所有的文件包含子目录中的文件;(5)支持标准的ls支持选项-u,它会显示出文件的最后访问时间,如果用了-u而不用-l,会有什么结果?;(6)当关掉一个文件的读权限,就不能打开这个文件来读。如果从一个终端登录,打开一个文件,保持文件的打开状态,然后从另外的终端登录,去掉文件的读权限,这时有什么事情会发生?编写一个程序,先用open()打开一个文件,用read()读一些内容,调用sleep()等待20s以后,再读一些内容,从另外的终端,再等待的20s内去掉文件的读权限,这样会有什么结果?。2.2编写内核模块显示目录或文件的信息。(1)使用内核模块编程;(2)调试《Linux操作系统原理与应用》第8章文件系统P215的例子;(3)练习给内核模块传入参数,参考关于带参数的模块编程;(4)给内核模块传入参数path,其中path为绝对路径;1)当path为目录时,显示目录对应的dentrey结构中的相关信息(可打印的信息);2)当path为文件时,显示文件对应的indoe结构中的相关信息(可打印的信息);3)当路径错误时,有错误提示信息。3开发环境设备名称设备类型配置类型参数LenovoG480PC机硬件配置RAM4G软件配置Ubuntu32位4测试环境设备名称设备类型配置类型参数LenovoG480PC机硬件配置RAM4G软件配置Ubuntu32位5总体设计5.1功能组织图ls功能图:文件权限:内核模块:运行命令LsLs-aLs-lLs-u按字典顺序排序输出隐藏文件输出文件属性输出所有文件属性运行命令chmod修改权限读文件,ls显示权限信息Ls-R输出所有文件加载模块super_blocks:path:5.2原理linux文件系统:运行命令Path=目录Path=文件路径错误显示目录信息显示文件信息显示错误信息运行命令加锁遍历系统中的超级块打印文件设备号打印文件系统名打印索引结点号统计索引结点计数卸载模块linux下有普通文件、目录文件、链接文件、设备文件、管道文件这几种类型。但链接文件、设备文件、管道文件都可以当做普通文件看待,那实际也就只要区分普通文件和目录文件这两种了。而目录文件的内容就是它所包含所有文件和子目录的一个列表,所以只要打开目录文件并读取对应目录块里的那个列表数据,就可以得到些目录下所有文件和子目录的名称了。其实这个流程简单,就是:打开目录-读取内容-显示文件名称-关闭打开的目录。Linux系统中会有很多目录。每个目录中又会有很多文件。如果要列出一个非当前目录的内容或者是一个特定文件的信息,则需要在参数中给出目录名或文件名。如:ls/tmp//列出/tmp目录中各文件的文件名ls–docs//列出docs目录中各文件的属性ls*.c//列出当前目录下与*.c匹配的文件,即当前目录下所有以.c为后缀的经常用到的命令行选项ls-l在前面已经提到过,-l就是输出文件详细的信息ls-a列出的内容包含以“.“开头的文件,即所谓有隐藏文件Linux的文件访问权限:Linux是一个安全的操作系统,说他安全,最重要的一个原因是对用户访问权限的控制。在shell下我们可以通过命令ls-lfilename来查看一文件的属性。其中第一项文件属性总共由10位构成,第一位是文件类型,剩下9位都是表示文件的访问权限,每3个一组,第一组:文件所有者对该文件的操作权限,第二组表示与文件所有者同组的用户对该文件的操作权限,第三组表示其他用户对该文件的操作权限,权限由三种字母组成:r:可读w:可写x:可执行。编写内核模块①写内核模块,打印super_block结构中一些域的值。(课本上的例子)遍历系统中的超级块:list_head结构类型的字段名称为s_list。list_entry宏通过指向list_head节点的地址来得到外部超级块的首地址。获取系统中个超级块的地址,获得某个子进程的地址,打印文件系统所在的主设备号和次设备号和文件系统名。遍历打印每个超级块中的所有索引节点号,打印索引结点。②内核模块传入参数path,其中path为绝对路径path=路径时,显示如下信息:目录项标志、哈希表、短目录名、目录项长度、目录项名、目录项计数器的引用path=文件时,显示如下信息:文件索引节点的数量、文件类型和权限、用户ID、用户组ID、指定文件系统的读写访问标志、文件大小、索引节点的状态、硬链接数、引用记数、文件的块、版本号、以位为单位的块大小6详细设计6.1模块一ls1.功能(1)ls支持-l参数;(2)输出结果按字典排序;(3)列出“.”文件,支持-a参数,在没有-a时候不显示隐藏文件支持–u参数。支持–R参数;(4)显示记录总数。(5)支持对给定的目录进行操作,如ls/tmp;(6)输出结果分栏排序,每栏的宽度由这一栏最长的文件名决定,显示的栏数还受终端显示器的宽度影响,每一列尽可能的等宽;(7)修改文件权限2.算法/流程图ls算法描述:根据输入命令所带的参数判断并调用函数do_ls();把隐藏文件属性写入结构体数组Outputpoint[]中并统计文件数。非隐藏文件属性写入结构体数组Output[]中并统计文件数。按参数要求对文件名进行排序。根据要求输出。流程图:main()函数:开始是否是否否否是是否是判断输入的命令调用do_ls()命令名字后加.判断是否是/tmp-l判断命令是否是-t判断命令是否是ls调用qsort();按最后修改时间排序结束display_Ls(cntOutput);打开当前目录把隐藏文件记录在数组Outputpoint[],非隐藏文件记录在数组Output[]调用qsort();按最后访问时间排序display_ls_R(cntOutp);判断命令是否是-R判断命令是否是ls-l循环调用dostat(Output[i].FileName);3.运行结果4.模块使用的主要函数、数据类型和宏(1)主要函数说明1)函数一do_ls();原型:voiddo_ls(intmyJudge,charmyOrder[])功能:根据命令输出对应的文件属性参数:myJudge,myOrder[]返回值:void2)函数二recursion原型:voidrecursion(char*name)功能:递归输出文件名参数:name返回值:void3)函数三display_ls_a原型:voiddisplay_Ls_a(intcntPoint,intcnt)功能:ls–a的功能,输出非隐藏文件参数:cntPoint,cnt返回值:void4)函数四show_file_info原型:voidshow_file_info(char*filename,structstat*info_p)功能:ls–l文件属性分栏输出参数:filename,info_p返回值:void(2)数据类型1)数据类型1名称:Output[maxN]类型:structOutfile*含义:非隐藏文件的保存2)数据类型2名称:,OutputPoint[maxM];类型:structOutfile*含义:隐藏文件的保存(3)宏1名称:#defineLS0//ls含义:命令行无参数宏2名称:#defineLS_A1//ls-a含义:命令行参数只有-a宏3名称:#defineLS_L2//ls-l含义:命令行参数只有-l宏4名称:#defineLS_TMP3//ls/tmp含义:命令行参数有/tmp宏5名称:#defineLS_R7//ls-R含义:命令行参数有-R6.2模块二super_block1.功能通过加载内核的方式,打印出超级块super_blocks数据结构中文件系统所在的主设备号和次设备号以及文件系统名2.算法/流程图3.运行结果开始加锁遍历系统中的超级块打印文件设备号打印文件系统名打印索引结点号索引结点计数结束加载模块卸载模块4.模块使用的主要函数、数据类型和宏(1)主要函数说明1)函数一原型:staticint__initmy_init(void)功能:模块加载参数:无返回值:int2)函数二原型:staticvoid__exitmy_exit(void)功能:模块卸载参数:void返回值:void(2)数据类型1)数据类型1名称:sb类型:structsuper_block*含义:定义一个超级块2)数据类型2名称:pos类型:structlist_head*含义:定义一个链表3)数据类型3名称:linode类型:structlist_head*含义:定义一个链表4)数据类型4名称:pinode类型:structinode*含义:定义一个索引结点5)数据类型5名称:count类型:int含义:存储总数(3)宏一名称:#defineSUPER_BLOCKS_ADDRESS0xc1778bc0含义:超级块的变量地址宏二名称:#defineSB_LOCK_ADDRESS0xc1932aa0含义:sb_lock超级块对应的自旋锁7测试方法与测试结果7.1测试方法编号输入用例期望结果1./a.out按字典排序,输出当前目录下的所有文件名(不含隐藏文件)2./a.out-l显示当前目录下的非隐藏文件详细信息按字典排序3./a.out-a显示上级目录下目录的所有文件名,含有隐藏文件。4./a.out-t按照最后修改时间排序5./a.out-R显示上层文件夹下所有文件文件6./a.outlinux显示liunx:当前文件夹下没有文件7.2测试结果1../a.out2../a.out-a3./a.out-l4../a.outlinux5../a.out-u6../a.out-R8调试情况,设计技巧及体会通过这次课程设计,使我对liunx理解更加深了一步。通过编写程序中错误,对ls功能基本以达到掌握并熟练运用的程度。对错误的调试,对程序的掌握运行有的一定的掌控。这次课程设计,收获颇深。9参考资料[1]DANIELP.BOVET&MARCOCESATI.深入理解LINUX内核[M].陈莉君,张琼声,张宏伟,译.第三版.北京:中国电力出版社,2007:825-831.[2]Documentation/x86/boot.txt[4]RichardBlum.汇编语言程序设计[M].马朝晖译.北京:机械工业出版社,2006.[5]