《哈工大《操作系统》实验(共5页).doc》由会员分享,可在线阅读,更多相关《哈工大《操作系统》实验(共5页).doc(5页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上2014级本科操作系统实验报告(实验2)学生姓名曾帅学号 院系软件学院任课教师范国祥实验TAXXX实验地点软件学院三楼实验室实验时间2016年05月19日 星期四实验题目系统接口实验学时2学时实验目的:l 建立对系统调用接口的深入认识;l 掌握系统调用的基本过程;l 能完成系统调用的全面控制;l 为后续实验做准备。实验内容及要求:在Linux 0.11上添加两个系统调用,并编写两个简单的应用程序测试它们:(1)第一个系统调用是iam(),其原型为:int iam(const char * name);完成的功能是将字符串参数name的内容拷贝到内核中保存下来。要求na
2、me的长度不能超过23个字符。返回值是拷贝的字符数。如果name的字符个数超过了23,则返回“-1”,并置errno为EINVAL。在kernel/who.c中实现此系统调用。(2)第二个系统调用是whoami(),其原型为:int whoami(char* name, unsigned int size);它将内核中由iam()保存的名字拷贝到name指向的用户地址空间中,同时确保不会对name越界访存(name的大小由size说明)。返回值是拷贝的字符数。如果size小于需要的空间,则返回“-1”,并置errno为EINVAL。在kernel/who.c中实现。(3)测试程序:运行添加过新
3、系统调用的Linux 0.11,在其环境下编写两个测试程序iam.c和whoami.c。最终的运行结果例子:$ ./iam abcdefg$ ./whoamiabcdefg实验过程描述、结果及思考:简要描述实验过程(含操作步骤及看到的结果),关键是向Linux 0.11添加一个系统调用xxxx()的步骤。(1) 修改oslab/linux-0.11/include/linux/sys.h根据Linux调用系统调用的过程,需要把 iam()与whoami()两个函数加到全局变量,和中断函数表中就可以了,中断被调用的时候,先查找中断向量表,找到相应的函数名,调用其函数。分别添加声明到最下面和数组中
4、extern int sys_ssetmask();extern int sys_setreuid();extern int sys_setregid();extern int sys_iam();extern int sys_whoami();fn_ptr sys_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
5、_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, s
6、ys_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_sgetm
7、ask, sys_ssetmask,sys_setreuid,sys_setregid, sys_iam, sys_whoami ;(2) linux-0.11/kernel/system_call.s需要把nr_system_calls由72改为 74 表示了中断函数的个数。# offsets within sigactionsa_handler = 0sa_mask = 4sa_flags = 8sa_restorer = 12nr_system_calls = 74(3) 修改linux-0.11/include/unistd.h需要把两个自定义函数的宏定义在这里,修改后为#define
8、 _NR_setregid 71#define _NR_iam 72#define _NR_whoami 73(4) 修改Makefile要想让我们添加的kernel/who.c可以和其它Linux代码编译链接到一起,必须要修改Makefile文件。Makefile里记录的是所有源程序文件的编译、链接规则,注释3.6节有简略介绍。我们之所以简单地运行make就可以编译整个代码树,是因为make完全按照Makefile里的指示工作。Makefile在代码树中有很多,分别负责不同模块的编译工作。我们要修改的是kernel/Makefile。需要修改两处。一处是:OBJS = sched.o sys
9、tem_call.o traps.o asm.o fork.o panic.o printk.o vsprintf.o sys.o exit.o signal.o mktime.o改为:OBJS = sched.o system_call.o traps.o asm.o fork.o panic.o printk.o vsprintf.o sys.o exit.o signal.o mktime.o who.o另一处:# Dependencies:exit.s exit.o: exit.c ./include/errno.h ./include/signal.h ./include/sys/t
10、ypes.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.s who.o: who.c ./include/linux/kernel.h ./include/unistd.hexit.s exit.o
11、: 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 放到linu
12、x-0.11/kernel目录下,在linux-0.11目录执行make all命令,who.c被编译到内核中 who.c#define _LIBRARY_ #include #include #include #include char username64=0; int sys_iam(const char* name) int i = 0; while(get_fs_byte(&namei) != 0) i+; if(i 23) return -EINVAL; i=0; while(1) usernamei = get_fs_byte(&namei); if(usernamei = 0)
13、 break; i+; return i; int sys_whoami(char* name,unsigned int size) int i,len; len = strlen(username); if (size len) return -1; i=0; while(i len) put_fs_byte(usernamei,&namei); i+; return i; iam.c#define _LIBRARY_#include unistd.h#include #include _syscall1(int,iam,const char*,name)int main(int argc,
14、char* argv) iam(argv1); return 0; whoami.c#define _LIBRARY_ #include unistd.h #include #include _syscall2(int, whoami,char*,name,unsigned int,size);int main(int argc ,char *argv) char *username; username = (char *)malloc(sizeof(char)*128); whoami(username,128); printf(%sn,username); free(username);
15、return 0;(6) 将hdc挂载,把写好的unistd.h、whoami.c、iam.c放入oslab/hdc/usr/root文件夹中,再运行run,进入linux0.11,编译whoami.c、iam.c,gcc -o iam iam.c Wall,gcc -o whoami whoami.c -Wall运行并输入参数,检查是否正确,运行正确,实验成功。问题回答:Linux 0.11的系统调用最多能传递几个参数?你能想出办法来扩大这个限制吗? 答:Linux 0.11内核中用户程序能够向内核最多直接传递三个参数,当然也可以不带参数。为了方便执行,内核源代码在include/unistd文件中定义了宏函数_syscalln(),其中n代表携带的参数个数,可以分别0至3。因此最多可以直接传递3个参数。如果需要传递多个参数,大块数据给内核,则可以传递这块数据的指针值。例如系统调用int read(int fd,char buf,int n)在其宏形式_syscall3(int, read, int, fd, char, buf, int, n),对于include/unistd中给出的每个系统调用宏,都有2+2*n个参数。其中第一个参数对应系统调用返回值的类型;第2个参数是系统调用的名称;随后是系统调用所携带参数的类型和名称。专心-专注-专业