操作系统课程设计_第1页
操作系统课程设计_第2页
操作系统课程设计_第3页
操作系统课程设计_第4页
操作系统课程设计_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

课程设计说明课程名称 操作系统课程设 业:物联网工 班级 2012级2设计人 2012010519102015116一、课程设计题目:Linux二、设计原始资料:1OperatingSystemConceptAbrahamSilberschatz 5、Linux六、命题发出日期: 设计要 总 proc伪文件系统及CMOS实时信 设计要 总 使用seq-file机制proc进程信 设计要 总 设计要 总 设计要 总 总 1、通过完成一个简单的Linux内核模块的添加和运行工作,了解并21、完成kello.c2kello.cMakefile3、完成kello.ko456kello.c代码的修改,使其能够在用户界面上输出信息,以及一定1、用gedit编辑工具完成kello.c2kello.cMakefile与普通C语言撰写的应用程序o.c相比,内核模块的编译比较复杂,这是因为在编译的过需要当前内核模块的支持。我们需要首先编写一个Makefile文件,与kello.c的编写一样,可以vi工具或者gedit代码撰写完成后,文件保存为Makefile与kello.c文件放置在同一个文件夹下。现在我们可以开始LKM的编译了。首先执行ls命令,查看并确认kello.c和Makefile存在当期工作 下,然后运行make指令。 sudoinsmodkello.ko sudormmoddmesg4、LKMkello.cMakefile文件。其内容如下:obj-:=KDIR:=/lib/modules/$(suname-r)/build:=$(spwd)$(MAKE)-C$(KDIR)SUBDIRS=$(PWD)rm-r-f.tmp_versions*.mod.c.*.cmd*.o*.symvers对该文件的解释是这样的:KERNELRELEASEMakefile中定义的一个变量,在第一次执行此Makefile时,KERNELRELEASE没有被定义,所以make将执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当没有make的目标时,make执行默认操作,即default后的指令,此时-C$(KDIR)指明跳转到内核源 下那里的=$(PWD)表明需要返回到当前 继续读入、执行当前的Makefile。当 返回时,KERNELRELEASE已被定义,kbuild也被启动去解析kbuild语法的语句,make将继续else之前的内容。else之前的内容为kbuild语法的语句,指明模块源码中各文件的依赖关系,以及要生成的目标模块名,obj-m:=kello.o表示编译连接后将生成kello.o模块,而kello.o文件默认则是由kello.c文件编译生成的。5在内核中定义了0~7总计8staticchar*log_level[]={KERN_EMERG0,表示等级最高。此时调用printkprintk(“<0>o,studentsfromSDUST!Thisisinkernelspace!\n"printk(KERN_EMERG"\no,studentsfromSDUST!Thisisinkernelspace!\n");6、intk函数还可以输出相关参数,例如如下printk(KERN_DEBUG"Wearehere:%s:%dat%s()/n",FILE ,LINE ,FUNCTION 其中FILE 表示源代码文件,以绝对路径的方式出现,LINE 表示这行printk允许在这个源代码文件中的第几行,这是一个很好的给出调测点位置的信息。这个同样可以用在用户程序。另外DATE 和TIME也是经常使用用的两个。这4个宏,在debug中会经常使用。还有一个常用的是FUNCTION 表示处在哪个函数中,也是比较好的定位方式。这些宏均可以在用户程序中使用,对debug非常有帮7kello.c代码的修改,使其能够在用户界面上输出信息,以及一定运行结果及分1、用gedit编辑工具完成kello.c2kello.c代码对应的Makefile上述代码撰写完成后,文件保存为Makefile与kello.c文件放置在同一个文件夹下。现在我们可以开始LKM的编译了。首先执行ls命令,查看并确认kello.c和Makefile存在当期工作 下,然后运行make指3、完成kello.ko4printk(“<0>o,studentsfromSDUST!Thisisinkernelspace!\n"printk(KERN_EMERG"\no,studentsfromSDUST!Thisisinkernelspace!\n");5kello.c代码的修改,使其能够在用户界面上输出信息,以及总本次设计的重点有两个的c库。MakefileMakefile文件的撰写是内核编程必要的procCMOS1LKM机制添加系统功能,并支持应用程序使用该功2Linuxmycatproc3LKM模块,并对比,更深刻地理解内核模块编1、在Linux中有一个应用非常广泛令:cat,它的作用很多,其中一个2mycat.c代码的编辑,$gccmycat.c-o文件编译成功后,按着文件中说明的方法运行$./mycat<filename>可以是mycat.cpp或其他文件的名称。请观察命令3、对照代码、结合操作系统课程内容、以及图2.1,4、运行本节命令,5、代码编辑完成后,请保存为cmos.c。然后在相同文件夹下编辑Makefile文件,内容如下:Makefile保存后,在同一 下运行make;如果报错,请根据错误提示修改;如果一切顺利,那么就生成了cmos.ko文件,可以使用ls命令查看。这表示初步的编译已经通过了。确认cmos.ko生成后,可以通过如下命令来添加该LKM模块:$sudoinsmodcmos内核源文件,Makfile6cmos.ko内核模块,cat、mycat应用程序进1$cat$cat$cat$cat$cat$cat$cat$cat2、完成如下代码的撰写,mycat.c#include<fcntl.h>//foropen()#include<stdio.h>//forperror()#include<unistd.h>//forread(),write(),close()intmain(intargc,char*argv[]){inti,fd,ch;//declarelocalvariablesfor(i=1;i<argc;i++){fd=open(argv[i],O_RDONLYif(fd<0){perror(argv[i]);continue;while(read(fd,&ch,1)==1)write(STDOUT_FILENO,&ch,1);close(fd);}}文件保存后,可以按着文件头部注释中说明的方法进行编译,$gccmycat.c-o文件编译成功后,按着文件中说明的方法运行$./mycat<filename>mycat.cpp或其他文件的名称。观察命令运行后的3、运行本节命令,查看输出结果。$catproc/cpuinfoCPU(型号,,缓存大小等)$cat/proc/modules-$cat/proc/meminfo-$cat/proc/iomemIO$cat/proc/self/maps-cat$cat/proc/devices-$cat/proc/filesystems-$cat/proc/version-4、代码编辑完成后,cmos.c。然后在相同文件夹下编辑obj-m:=cmos.oKDIR:=/lib/modules/$(suname-r)/buildPWD:=$(spwd)$(MAKE)-C$(KDIR)SUBDIRS=$(PWD)rm-r-f.tmp_versions*.mod.c.*.cmd*.o*.symversMakefile保存后,在同一下运行make;如果报错,请根据错误提示修改;如果一切顺利,cmos.ko文件,ls命令查看。这表示初步的编译已经通过了。确认cmos.ko生成后,可以通过如下命令来添加该LKM模块:$sudoinsmod 下查看是否生成了cmos伪文件,也可以使用dmesg来查看内核日志中的模块添加信息。一切顺利没有问题,我们可以运行如下命令来RTC信息了:$cat/proc/cmos你的显示器上的输出结果是什么?是不是RTC信息不断的在刷屏?按<Ctrl>+C组合键,可以停止刷屏。查看我们的cmos.c内核源文件,可以确认我们确实是只想输出一次RTC信息啊,但为什么一直在不断的输出呢?现在再尝试使用我们自己开发的mycat应用程序来查看RTC输出:$./mycat5、“新内核新特性:ubuntu14.04LTSproc特性”删除了老内核环境支持的多个版本的proc创建方法。目前3.13.0proc_create,其函数原型为staticinlinestructproc_dir_entry*proc_create(constchar*name,umode_tmode,structproc_dir_entry*parent,conststructfile_operations*proc_fops){returnproc_create_data(name,mode,parent,proc_fops,}该函数是一个内联函数(inline),proc_creat_dataproc_creat-data的原型如下externstructproc_dir_entry*proc_create_data(constchar*,umode_t,structproc_dir_entry*,conststructfile_operations*,void*);所以严格的说,在版本的Linux内核中,proc伪文件事实上只有一新版本的Linux内核删除了在ubuntu12.04LTS(Linux3.2.0内核)经常使用的proc直接读和写的函数。也就是说,在ubuntu12.04LTS中我们使用一个proc自定义的读函数就可以正确的读出相关信息了。为此,在新版Linuxprocseq_file机制绑定在一起了。也就是说,在Linux新版本的内核中proc伪文件的读写等操作都是根据seq_file机制来进行的。运行结果及分1、$cat$cat$cat$cat$cat$cat$cat$cat2、$sudoinsmod3、尝试使用自己开发的mycat应用程序来查看RTC$./mycat总/proc伪文件系统提供了一个基于文件形式的Linux内部接口。它可些状态往往都是处于内核空间的,对程序员来说是作系统隔绝开的。通过本次设计,我们可以看到为了解决应用程序与内核数据的问题,也即我们不可能让一个类似于cat的应用程序直接去读CMOS中的RTC信息,我们添加了一个cmos.ko内核模块,该模块创建了一个名为cmos的proc伪文件,通过这个伪文件我们就可以直接从硬件设备CMOS中RTC信息了。当用户程序,比如cat,要打开/proc/cmos伪文件或者/proc/cmos的信息时,cat程序中的标准库函数把相应的操作参数传递给操作系统内核对应的LKM模块,也即我们编写的cmos.ko,由cmos.ko调用相应的内核操作函数打开该设备或者相关信息,然后把操作结果返1、通过使用seq-file机制proc进程信息,了解seq_file机制,理解Linux重要的内核数据结构task_struct;2、通过利用seq_fileproc伪文件,Linux内核task_structPCB(ProcessControlBlock)的信息。1、了解seq_file2、实现procseq_file32步输出结果进行分析,查看并分析查看/proc/tasklist的信息4、重新编辑编辑代码并运试新的tasklist模块,并用mycat和cat命1、编辑tasklist.c内核代码,添加到当前内核中运行,并且通过mycat和cat命令查看/proc/tasklist的信息。实现proc伪文件与seq_file机制的绑定,通过proc伪文件tasklist当前系统中进程的pid、状态、进程名称等信 在my_proc_entryproc_create(modname0NULL&my_proc);中传递了参数&my_proc作为定义的proc伪文件tasklist的操作函数,它的具体staticconststructfile_operationsmy_proc{.owner= = = =.release=其中my_open函数是自己写的,但是只有一句就是调用seq_open函数。seq_open通常在打开文件的时候使用;seq_read,seq_lseek和seq_releaseread,llseekrelease,由头文件seq_file.h定义,在seq_file.c中实现。2、查看/proc/tasklist的信息,3、重新编辑代码并运试新的tasklist模块,并用mycat和cat命令分1是否存在差异,并分析。运行结果及分11procseq_file机制是这样绑定在一起的文件级别的操作绑定。proc在创建后,seq_file机制支持的打开、读、写(seq_open、seq_read、seq_write)等函数进行文件级别的操作;工作,那么我们就需要自己重写这些函数,这些函数都需要在file_operations结构体中,并在proc文件创建时作为参数传递进去,即proc_create中记录级别的遍历操作。如果在遍历seq_file对象时需要完成我们自己的工作,那么就需要定义我们自己的遍历操作函数,即:start、next、stop和show四个函数,并且把相关的操作函数放在seq_operations结构体中,这个结构体需要作为参数在proc伪文件打开时传递进去,即seq_open的22通过重写cmos内核代码,让其不再刷屏,mycat函数能够33./mycat/proc/tasklist1中,读一次相当于调用上面的四个函数,之前自己写的procread065,所以会一直读,会刷屏。Mycat1,而myprocread直接返回总在使用seq-file机制proc进程信息的设计中通过创建一个内核模块,利用proc伪文件系统以及seq_file机制,我学会了怎样去查看进程的信息。在这其中比较困惑的是proc怎样和seq_file机制绑定在一起的。概括来说,procseq_open、seq_read、seq_write等函数来进行操作,所以创建proc文件时要在proc_create中传入需要使file_operations作为参数,其中的操作函数可以自己重新定义。在遍历proc文件中的每个记录时需要使用seq_operations中指定的四个操作函数(必须指定,而且也只有四个):start、show、next和stop,这个结构体需要在打开proc文件时作为参数传递给seq_open函数。事实上,在本章实验中我们遍历进程Linux进程控制块结构task_struct时其实使用的是task_struct链表自带的遍历机制,比如宏定义next_task、初始位置init_task等。1、通过POSIX多线程创建,了解基于POSIX多线程编程下加锁和不加锁两种情况的区别,理解并掌握POSIX多线程环境下利用同步机制解2、通过Linux多线程创建,了解基于Linux多线程编程下加锁和不加锁两种情况的区别,理解并掌握Linux多线程环境下利用同步机制解决多1、掌握基于POSIX会IEEE开发的标准族,部分已经被ISO接受为国际标准。IEEEStd.1003.1-1990或POSIX.1为操作系统的服务例程提供了源代码级别的C2、掌握基于Linux虽然Linux支持POSIX的多线程编程,但是Linux也有自己一套用于基于POSIX多线程编1、基于POSIX在主线创建一个新的线程,完成一个从1到UPPER(指定的累加2、基于POSIX在主线创建两个新线程,合作完成一个从1到UPPER(指定的累3、基于POSIX常见的机制是同步机制在主线创建两个新线程使用基于互斥锁的同步机制合作完成一个从1到UPPER(指定的累加次数上限)的累加工作,1、基于Linux定次数的累加工作,指定累加次数为upper。也就是说最终累加结果为:2、基于Linux多线程编程:TestAndSet在主线创建四个新的进程,分别使用临界区模型完成对一个共享变量counterupper。3、基于Linux线程主动放弃CPUintnanospleep(conststructtimespec*req,structtimespec一行则是用于说明使用的tsStruct结构体timespecStructtime_ttv_sec;/*seconds秒Longinttv_nsec;/*nanoseconds纳秒}nanosleep函数功能是暂停某个线程直到规定的时间后恢复,参数seq就是要暂停的时间其中req->tv_sec是以秒为单位而tv_nsec以纳秒为单位,范围是[0, ]。由于调用nanosleep是使用线程进入TASK_RUNNING状态,这就意味着有可能会没有等到规定的时间就因为当然是在rem不为空的情况下。运行结果及分12345、TestAndSet6总本次多线程环境下的竞争条件与同步机制设计对Linux支持的线程创建机制进行了一个简单的对比分析。其中pthread函数库支持用户级的线mutexspinlocksemaphoreLinuxLinuxclone的线程由内核实现调度。根据内核数据的粒度不同、范围不同,Linux同步机制同样有的选择,包括原子操作、内存屏障、自旋锁、信号量1、通过对进程控制块task_struct中的mm_struct变量mm的操作,了栈、以及引入的动态库等。2、通过mm中的vm_struct变量mmap的操作,了解每个段的运行情1mm.cMakefile21mm.cMakefile图5.1是Operatingsystemconcepts中的一个关于内存地址映射的基本示意图。它说明了在In IA32结构中从逻辑地址到物理地址的映0MAX-1,MAXpagingpaging

图 两线程使用互斥锁同步完成一个计数工selector1613TIIA328k8kRPL。段寄存

16位16位段基地址全局段表寄全局段表寄存5.2从逻辑地址到线性地址(虚拟地址)5.2·CPUselector:offset”·在段寄存器中装入段选择符,同时把32位地址偏移量装入某个寄存器·根据选择符中的索引值、TI及RPL值,再根据相应描述符表中的段地址和段界限,进行一系列检查;如果该段无问题,就取出相应的描述·将描述符中的32位段址和放在ESI、EDI等中的32位有效地址相32page页页0图5.3 Linux线性空间在32位平台上为4GB的固定大小。linux内核将这4G字节的空间分为两部分。内核使用最高的1G字节(从虚地址0xC 0xFFFFFFFF,地址0x 因为每个进程可以通过系统调用进入内核,因此,Linux内核空间由系统内的所有进程共享。于是,从具体进程的角度看,每个进程可以拥有4G(0~3G,在系统启动时,Linux内核映像被装入到物理地址0x 地方,即1MB开始区间前面1M空间留做他用。Linux内核映像应该在虚内存的内核空间中,所以程序在内映像时在所有的符号地址加上一个偏移量0xC 对比较简单的。给定一个虚地址X,其对应的物理地址为“X-PAGE_OFFSET”;反之,给定一个物理地址Y,则其对应的虚地址为“Y+PAGE_OFFSET相对于内核空间而言,Linux形成的空洞(holes)则可以放入动态文件。尽管每个用户进程可以拥3GBLinux每个Linux进程都需要创建多个段,这些段对应不同的虚拟区域。一个虚存区域是虚存空间中的续区域,在这个区域中的信息具有相同的操作和特性。Linuxtaskstructstructvolatile unsigned structmm_struct structthread_struct /*其他省略task_struct被称为进程控制块PCB,因为它记录每一个进程所mmstruct,被称为“内存描述符”。mmstructLinux在Linux系统中,进程控制块task_struct是内核中的数据结mmmm_struc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论