ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:473.72KB ,
资源ID:8390461      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8390461.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(操作系统实验三文件系统和设备管理.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

操作系统实验三文件系统和设备管理.docx

1、操作系统实验三文件系统和设备管理 实验三 文件系统和设备管理 作者:学 号:班 级学院(系):计算机学院专业:指导教师:分 数:目 录 1. 实验目的 22. 实验要求 23. 具体实现 23.1. LINUX下串口的非阻塞读写程序 23.2. 模块 3 3.3 实现一个procfs文件系统的模块 7 4. 实验心得5.附录 源代码 91. 实验目的了解LINUX下文件系统和I/O的实现,了解其中模块的设计。2. 项目要求(a) 实现一个LINUX下串口的非阻塞读写程序。(b) 了解LINUX下模块的实现方式,及相应的编译和安装及卸载过程。实现一个模块,在模块安装时可打印信息(Hello)和卸

2、载时打印信息(Goodbye).(c) 实现一个procfs文件系统的模块。3. 具体实现3.1 LINUX下串口的非阻塞读写程序在 Linux 下串口文件是位于 /dev 下,串口一 为 /dev/ttyS0,串口二为 /dev/ttyS1打开串口是通过使用标准的文件打开函数操作:int fd;/*以读写方式打开串口*/fd = open( /dev/ttyS0, O_RDWR);if (-1 = fd) /* 不能打开串口一*/ perror( 提示错误!);在使用时还应当设置串口、读写串口、关闭串口等,通过查阅资料实现了对串口的读写代码见附录3.2 模块模块是具有独立功能的程序,它可以被

3、单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。 首先在电脑里编写一段C语言代码,hello.c。代码如下分析:(1)在内核模块的开始一部分,跟C语言的一般程序一样,是模块所需要的头文件。(2)模块许可证声明,这部分是必须有的。模块许可证(LICENSE)声明描述内核模块的许可权限,如果不声明LICENSE,模块被加载时,将收到内核被污染(kernel tainted)的警告。大多数情况下,内核模块应遵守GPL兼容许可权。Linux2.6内

4、核模块最常见的是以MODULE_LICENSE(Dual BSD/GPL)语句声明模块采用BSD/GPL双LICENSE。(3)模块加载函数,这部分是必须的。模块加载函数必须“module_init(函数名)“的形式被指定。它返回整形值,若初始化成功,应返回0。在上面那个例子当中,hello_init()函数就是模块加载函数需要执行的,主要是打印一条信息。(4)跟模块加载函数相对应的就是模块卸载函数,这部分也是必须的。模块卸载函数在模块卸载的时候执行,不返回任何值,必须以“module_exit(函数名)“的形式来指定。在上面的例子中,hello_exit()函数就是模块卸载函数需要执行的,只

5、要是打印了一条退出信息。(5)函数最后的一部分,是模块声明与描述部分。这部分可有可无。在Linux内核模块中,我们可以用MODULE_AUTHOR,MODULE_DESCRIPTION,MODULE_VERSION,MODULE_DEVICE_TABLE,MODULE_ALIAS分别声明模块的作者、描述、版本、设备表和别名。(6)module_init()是驱动程序初始化的入口点。它就相当于c语言程序中的main()函数。对于内置的模块,内核在引导时调用该引导点,对于可加载模块则在模块插入到内核时才调用。(7)模块加载函数和模块卸载函数中都用到了printk()函数,该函数是由内核定义的,功能

6、与C库中的printf()类似,它把要打印的信息输出到终端或系统日志中。其次,编写Makefile文件,通过它来管理一个庞大的项目是再好不过的。下面我们就在刚才.c文件目录下编写一个Makefile文件。对应的代码如下: pwd是获得当前的相对路径,然后就是获得当前的内核版本号,我们可以用uname -r命令,这样我们就获得了当前内核的绝对路径。这样做的一个好处,就是你可以在不同的内核版本中进行移植,而且可读性也增强了。 有了Makefile文件后,就离成功不远了。在.c文件的同一目录下,执行make命令,系统会在当前目录下生成各种文件。其中就有与之相关的.o和.ko文件。hello.ko就是

7、模块目标文件。到此,模块编译好了。截图如下: 模块编译好了,但是还不能为我们工作。下面就是将目标模块插入到内核和从内核中删除。这里需要用到两个命令,insmod和rmmod 我们光看这两个命令单词就能猜出他们的意思。输入命令:sudo insmod hello.ko。要看信息必须要进入到日志文件中,可输入命令进到系统日志:dmesg,会发现有一条信息,Hello World,说明我们刚才编写的模块已经插入到内核当中了。接下来输入命令:sudo rmmod hello.ko。再输入命令打开系统日志,我们会发现在会有一个新的信息Goodbye,这说明我们的模块卸载成功。至此,实现一个模块,在模块安

8、装时可打印信息(Hello world)和卸载时打印信息(Goodbye)完成3.3 实现一个procfs文件系统的模块/proc文件系统是在LINUX系统中的一个特殊部分,它并不属于任何应用的文件系统,它的主要作用是用于用户与系统的参数交换,但使用更多的是通过/proc系统中的文件内容来查看系统当前运行状态。程序中主要是要靠调用LINUX提供的系统函数来创建表项和文件夹,并且通过修改读写函数的指针,可以实现对于该文件读写的重调用。其中,建立文件和文件夹的函数是:static struct proc_dir_entry *mydir;static struct proc_dir_entry *

9、pfile;static int myproc_write(struct file *, const char _user *, unsigned long, void *)static int myproc_read(char *, char *, off_t , int , int *, void *)编写Makefile文件,和上面的类似,这里就不过多赘述。编写编译procfc_模块,:生成如下文件:在/procfc_os中创建mydir文件夹4 实验心得(a)在实验中初步学习了LINUX串口编程,了解了各个函数的功能。因为硬件的关系,故只是模拟了串口的写入及读出。实际中应该将两个串口相

10、 连来实现(b)本次实验中亲自动手实践了LINUX内核的模块编程,并初步了解了内核模块在LINUX内核中的位置和运行方式。加强了对linux模块的了解(c)本次实验中结合内核模块的编程方式,通过上网查找资料及去图书馆借阅书籍,学会写PROC文件系统的文件。 5 附录(3.1及3.3的原程序)5.1#include #include #include #include #include int main() int fd,flag,wr_num=0,rd_num=0; char send_buf512,recv_buf512; while(1) fd=open(/dev/minttyS0,O_R

11、DWR|O_NOCTTY|O_NDELAY); if(fd=-1) printf(can not open the COM1!n); else fcntl(fd, F_SETFL, 0); printf(open Input-serial port successfully!n); printf(Input:n); scanf(%s,send_buf); wr_num=write(fd,send_buf,sizeof(send_buf);/*先写入*/ if(wr_num0) printf(write success!nn); else printf(write fail!nn); sleep

12、(1); close(fd); fd=open(/dev/minttyS0,O_RDWR|O_NOCTTY|O_NDELAY); if(fd=-1) printf(can not open the COM2!n); else fcntl(fd, F_SETFL, 0); printf(open Output-serial port successfully!n); rd_num=read(fd,recv_buf,sizeof(recv_buf);/*再读出*/ if(rd_num0) recv_bufrd_num = 0; printf(we can read %s from the COM1

13、.total:%d charactersnn,recv_buf,rd_num); else printf(read fail!n); sleep(2); close(fd); 5.2 #include #include #include static struct proc_dir_entry *mydir;static struct proc_dir_entry *pfile;static char msg255;static int myproc_read(char *page, char *start, off_t off, int count, int *eof, void *data

14、) int len = strlen(msg); if (off = len) return 0; if (count len - off) count = len - off; memcpy(page + off, msg + off, count); return off + count;static int myproc_write(struct file *file, const char _user *buffer, unsigned long count, void *data) unsigned long count2 = count; if (count2 = sizeof(m

15、sg) count2 = sizeof(msg) - 1; if (copy_from_user(msg, buffer, count2) return -EFAULT; msgcount2 = 0; return count;static int _init myproc_init(void) mydir = proc_mkdir(mydir, NULL); if (!mydir) printk(KERN_ERR Cant create /procfc_os/mydirn); return -1; pfile = create_proc_entry(Pool, 0666, mydir); if (!pfile) printk(KERN_ERR Cant create /procfc_os/mydir/pooln); remove_proc_entry(mydir, NULL); return -1; pfile-read_proc = myproc_read; pfile-write_proc = myproc_write; return 0;static void _exit myproc_exit(void) remove_proc_entry(pool, mydir); remove_proc_entry(mydir, NULL);

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1