哈工大《操作系统》实验2

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

2014级本科《操作系统》实验报告(实验2)学生姓名曾帅学号1143710412院系软件学院任课教师范国祥实验TAXXX实验地点软件学院三楼实验室实验时间2016年05月19日星期四实验题目系统接口实验学时2学时实验目的:建立对系统调用接口的深入认识;掌握系统调用的基本过程;能完成系统调用的全面控制;为后续实验做准备。实验内容及要求:在Linux0.11上添加两个系统调用,并编写两个简单的应用程序测试它们:(1)第一个系统调用是iam(),其原型为:intiam(constchar*name);完成的功能是将字符串参数name的内容拷贝到内核中保存下来。要求name的长度不能超过23个字符。返回值是拷贝的字符数。如果name的字符个数超过了23,则返回“-1”,并置errno为EINVAL。在kernel/who.c中实现此系统调用。(2)第二个系统调用是whoami(),其原型为:intwhoami(char*name,unsignedintsize);它将内核中由iam()保存的名字拷贝到name指向的用户地址空间中,同时确保不会对name越界访存(name的大小由size说明)。返回值是拷贝的字符数。如果size小于需要的空间,则返回“-1”,并置errno为EINVAL。在kernel/who.c中实现。(3)测试程序:运行添加过新系统调用的Linux0.11,在其环境下编写两个测试程序iam.c和whoami.c。最终的运行结果例子:$./iamabcdefg$./whoamiabcdefg实验过程描述、结果及思考:简要描述实验过程(含操作步骤及看到的结果),关键是向Linux0.11添加一个系统调用xxxx()的步骤。(1)修改oslab/linux-0.11/include/linux/sys.h根据Linux调用系统调用的过程,需要把iam()与whoami()两个函数加到全局变量,和中断函数表中就可以了,中断被调用的时候,先查找中断向量表,找到相应的函数名,调用其函数。分别添加声明到最下面和数组中externintsys_ssetmask();externintsys_setreuid();externintsys_setregid();externintsys_iam();externintsys_whoami();fn_ptrsys_call_table[]={sys_setup,sys_exit,sys_fork,sys_read,sys_write,sys_open,sys_close,sys_waitpid,sys_creat,sys_link,sys_unlink,sys_execve,sys_chdir,sys_time,sys_mknod,sys_chmod,sys_chown,sys_break,sys_stat,sys_lseek,sys_getpid,sys_mount,sys_umount,sys_setuid,sys_getuid,sys_stime,sys_ptrace,sys_alarm,sys_fstat,sys_pause,sys_utime,sys_stty,sys_gtty,sys_access,sys_nice,sys_ftime,sys_sync,sys_kill,sys_rename,sys_mkdir,sys_rmdir,sys_dup,sys_pipe,sys_times,sys_prof,sys_brk,sys_setgid,sys_getgid,sys_signal,sys_geteuid,sys_getegid,sys_acct,sys_phys,sys_lock,sys_ioctl,sys_fcntl,sys_mpx,sys_setpgid,sys_ulimit,sys_uname,sys_umask,sys_chroot,sys_ustat,sys_dup2,sys_getppid,sys_getpgrp,sys_setsid,sys_sigaction,sys_sgetmask,sys_ssetmask,sys_setreuid,sys_setregid,sys_iam,sys_whoami};(2)linux-0.11/kernel/system_call.s需要把nr_system_calls由72改为74表示了中断函数的个数。#offsetswithinsigactionsa_handler=0sa_mask=4sa_flags=8sa_restorer=12nr_system_calls=74(3)修改linux-0.11/include/unistd.h需要把两个自定义函数的宏定义在这里,修改后为#define__NR_setregid71#define__NR_iam72#define__NR_whoami73(4)修改Makefile要想让我们添加的kernel/who.c可以和其它Linux代码编译链接到一起,必须要修改Makefile文件。Makefile里记录的是所有源程序文件的编译、链接规则,《注释》3.6节有简略介绍。我们之所以简单地运行make就可以编译整个代码树,是因为make完全按照Makefile里的指示工作。Makefile在代码树中有很多,分别负责不同模块的编译工作。我们要修改的是kernel/Makefile。需要修改两处。一处是:OBJS=sched.osystem_call.otraps.oasm.ofork.o\panic.oprintk.ovsprintf.osys.oexit.o\signal.omktime.o改为:OBJS=sched.osystem_call.otraps.oasm.ofork.o\panic.oprintk.ovsprintf.osys.oexit.o\signal.omktime.owho.o另一处:###Dependencies:exit.sexit.o:exit.c../include/errno.h../include/signal.h\../include/sys/types.h../include/sys/wait.h../include/linux/sched.h\../include/linux/head.h../include/linux/fs.h../include/linux/mm.h\../include/linux/kernel.h../include/linux/tty.h../include/termios.h\../include/asm/segment.h改为:###Dependencies:who.swho.o:who.c../include/linux/kernel.h../include/unistd.hexit.sexit.o:exit.c../include/errno.h../include/signal.h\../include/sys/types.h../include/sys/wait.h../include/linux/sched.h\../include/linux/head.h../include/linux/fs.h../include/linux/mm.h\../include/linux/kernel.h../include/linux/tty.h../include/termios.h\../include/asm/segment.h(5)进入编写环节先编写who.c,who.c放到linux-0.11/kernel目录下,在linux-0.11目录执行makeall命令,who.c被编译到内核中①who.c#define__LIBRARY__#includeunistd.h#includeerrno.h#includeasm/segment.h#includestring.hcharusername[64]={0};intsys_iam(constchar*name){inti=0;while(get_fs_byte(&name[i])!='\0')i++;if(i23)return-EINVAL;i=0;while(1){username[i]=get_fs_byte(&name[i]);if(username[i]=='\0')break;i++;}returni;}intsys_whoami(char*name,unsignedintsize){inti,len;len=strlen(username);if(sizelen)return-1;i=0;while(ilen){put_fs_byte(username[i],&name[i]);i++;}returni;}②iam.c#define__LIBRARY__#includeunistd.h#includeerrno.h#includestdio.h_syscall1(int,iam,constchar*,name)intmain(intargc,char*argv[]){iam(argv[1]);return0;}③whoami.c#define__LIBRARY__#includeunistd.h#includestdlib.h#includestdio.h_syscall2(int,whoami,char*,name,unsignedint,size);intmain(intargc,char*argv[]){char*username;username=(char*)malloc(sizeof(char)*128);whoami(username,128);printf(%s\n,username);free(username);return0;}(6)将hdc挂载,把写好的unistd.h、whoami.c、iam.c放入oslab/hdc/usr/root文件夹中,再运行run,进入linux0.11,编译whoami.c、iam.c,gcc-oiamiam.c–Wall,gcc-owhoamiwhoami.c-Wall运行并输入参数,检查是否正确,运行正确,实验成功。问题回答:Linux0.11的系统调用最多能传递几个参数?你能想出办法来扩大这个限制吗?答:Linux0.11内核中用户程序能够向内核最多直接传递三个参数,当然也可以不带参数。为了方便执行,内核源代码在include/unistd文件中定义了宏函数_syscalln(),其中n代表携带的参数个数,可以分别0至3。因此最多可以直接传递3个参数。如果需要传递多个参数,大块数据给内核,则可以传递这块数据的指针值。例如系统调用intread(intfd,charbuf,intn)在其宏形式_syscall3(int,read,int,fd,char,buf,int,n),对于include/unistd中给出的每个系统调用宏,都有2+2*n个参数。其中第一个参数对应系统调用返回值的类型;第2个参数是系统调用的名称;随后是系统调用所携带参数的类型和名称。

1 / 5
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功