网络工程专业毕业论文—添加一个系统调用课程设计43394.doc

上传人:西安人 文档编号:3968012 上传时间:2019-10-11 格式:DOC 页数:18 大小:589.02KB
返回 下载 相关 举报
网络工程专业毕业论文—添加一个系统调用课程设计43394.doc_第1页
第1页 / 共18页
网络工程专业毕业论文—添加一个系统调用课程设计43394.doc_第2页
第2页 / 共18页
网络工程专业毕业论文—添加一个系统调用课程设计43394.doc_第3页
第3页 / 共18页
网络工程专业毕业论文—添加一个系统调用课程设计43394.doc_第4页
第4页 / 共18页
网络工程专业毕业论文—添加一个系统调用课程设计43394.doc_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《网络工程专业毕业论文—添加一个系统调用课程设计43394.doc》由会员分享,可在线阅读,更多相关《网络工程专业毕业论文—添加一个系统调用课程设计43394.doc(18页珍藏版)》请在三一文库上搜索。

1、添加一个系统调用设计说明书学院名称: 计算机与信息工程学院 班级名称: 网工111班 学生姓名: 学 号: 题 目: 添加一个系统调用 指导教师姓 名: 起止日期: 2013-6-32013-6-30 第一部分:正文部分一、选题背景本设计是专业基础课计算机操作系统的课程设计。由于操作系统课的学时有限,没有安排实验。为了理论联系实际,加强分析问题、解决问题能力的培养,加深理解和更好地掌握操作系统的基本概念、原理、技术和方法。特安排操作系统课程设计。它是操作系统课程的实践环节。由于具体的操作系统相当复杂,在短短的一周之内,不可能对所有管理系统进行详细地分析。因此,选择了操作系统中的对Linux系统

2、添加一个新的函数,作为本设计的任务,使学生在使用系统调用的同时,进一步了解系统内部是如何实现系统调用的全过程,使学生在更深层次上对操作系统有所了解。二、设计思路2.1课程设计题目添加一个系统调用2.2 课程设计任务根据red hat 9平台下系统调用的调用方式,在系统中添加一个功能为打印一句话“hello,system call”的系统调用。按照要求撰写课程设计报告。2.3 课程设计思想操作系统的主要功能是为应用程序的运行创建良好的环境,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调

3、用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序。Linux系统调用,包含了大部分常用系统调用和由系统调用派生出的的函数。2.4 软硬件运行环境计算机一台、Windows XP系统、VMware Workstaion 软件、red hat 9软件2.5 开发工具Linux、gcc编译器、vi编辑器三、过程论述3.1 流程图图3.1 添加系统调用流程图3.2 实验方法每个系统调用都是通过一个单一的入口点多路传入内核。eax 寄存器用来标识应当调用的某个系统调用,这在 C 库中做了指定(来自用户空间应用程序的每个调用)。当加载了系统

4、的 C 库调用索引和参数时,就会调用一个软件中断(0x80 中断),它将执行 system_call 函数(通过中断处理程序),这个函数会按照 eax 内容中的标识处理所有的系统调用。在经过几个简单测试之后,使用 system_call_table 和 eax 中包含的索引来执行真正的系统调用了。从系统调用中返回后,最终执行 syscall_exit,并调用 resume_userspace 返回用户空间。然后继续在 C 库中执行,它将返回到用户应用程序中。3.3 实验原理图3.2 使用中断方法的系统调用的简化流程图图3.3 系统调用表和各种链接3.4 程序结构框图图3.4 程序结构框图3.5

5、操作步骤第一步:编译前准备下载一份内核源代码,例如linux-2.4.tar.gz检查redhat中是否已有模块工具软件module-init-tools:# rpm qmodutils安装:# rpm ivh modutils-2.4.21-23.src.rpm将linux-2.4.tar.gz拷贝到目录/usr/src/下,解压源码:# tar zxvf linux-2.4.tar.gz生成源码文件子目录/usr/src/linux-2.4,进入此目录:# cd linux-2.4.第二步:编译新内核配置内核,有三种方式配置内核:# make config命令行界面# make menuc

6、onfig 字符菜单界面# make xconfig 图形界面虽然选择图形界面比较方便,但配置过程很繁琐,可将现有的配置文件拷贝过来使用(/usr/src/linux-2.4/.config)。编译生成新内核:# cd /usr/src/linux-2.4# make dep创建代码依赖文件(.depend),每次重新配置后都必须做这一步。# make bzImage开始编译系统内核(不包括带M选项的模块),生成的压缩文件bzImage在./arch/i386/boot/下。同时生成未压缩的内核执行文件(vmlinux)和内核符号表(System.map)。# make modules 开始编

7、译外挂模块。以后重新编译内核时,可省去这一步。# make modules_install将外挂模块放在系统模块安装目录(/lib/modules/2.4/)下,以便核心在需要时加载它们。同时在此目录下产生模块依赖文件(modules.dep)。# make install将bzImage和System.map拷贝到/boot/下,并建立相应的符号链接(vmlinuz和System.map);生成/dev/initrd映象文件(initrd-2.4.img);在/etc/下的启动配置文件lilo.conf或grub.conf中添加相应项。第三步:运行新内核# reboot,选择启动新内核:需要

8、注意的是,如果编译的内核版本号(在Makefile中定义)与正在运行的内核一样,就会覆盖现有内核的文件。为了防止新内核影响原内核,让新内核有一个不同的版本号。最好将编译内核前的虚拟机备份,以便在发生新内核导致系统无法正常运行时使用备份的系统。第四步:启动新内核后启动新内核后需要重新运行VMware tools的配置程序/usr/bin/vmware-config-tools.pl,以使网络界面正常和共享windows主机的文件夹。四、结果分析4.1添加新函数先用uname a命令获取当前linux内核版本。在/usr/src/linux-2.4/kernel/sys.c中,添加一个系统调用函数

9、内核,命令如图4.1所示。图4.1 初始界面 4.2 更新头文件在/usr/src/linux-2.4/include/asm-i386更新头文件,如图4.3所示。图4.3 命令界面图4.4 更新操作4.3针对这个新函数更新系统调用表在/usr/src/linux-2.4/arch/i386/kernel/entry.S中,添加一个系统调用,如图4.5所示。图4.5 命令界面图4.6 更新系统调用表4.4 重新编译内核将/usr/src/linux-2.4/Makefile中的版本号里的customer去掉,防止内核版本冲突。如图4.8所示。图4.7 命令界面编译内核 make mrprope

10、r; /*文件归位。清除上次编译内核的文件*/make xconfig;必选的配置选项如下:SCSI device support-SCSI low-level drivers- BusLogic SCSI support。如图4.9所示。图4.9 SCSI support界面Fusion MPT device support- Fusion MPT (base + ScsiHost) drivers和Fusion MPT misc device (ioctl) driver。如图4.10所示。图4.10 Fusion MPT device support界面Network devices s

11、upport-Ethernet (10 or 100Mbit)- AMD PCnet32 PCI support。如图4.11所示。图4.11 Network device support界面block devices-RAM disk support 和Initial disk(initrd) support。如图4.12所示。图4.12 Block device界面File systems-ext3 journalling system support。如图4.13所示。图 4.13 File systems 界面执行以下语句make dep; /作用:配置内核代码前需要进行配置;根据用户

12、的配置设置源代码的相关性make bzImage;/内核编译,生成一个新内核映像文件bzImage,即编译好的可以被cpu直接执行的二进制机器码。make modules;make modules_install;/配置的内核有模块支持make install;/将内核安装在系统中这之后新内核已经安装在了系统中,我们只需重启一下系统。五、结论在重新启动并成功进入系统之后,我们需要对之前增加的系统调用进行测试,测试代码如图 5.1所示。图5.1 测试代码部分击保存并退出gedit界面对C语言程序进行编译,最终得到文件名为test的可执行文件,在终端中输入。如图5.2所示。图5.2 命令代码通过观

13、察实验结果可得知,新添加的系统函数调用成功。第二部分:参考文献1 汤小丹,等.计算机操作系统.第三版.西安:西安电子科技大学出版社,20072 张尧学,史美林.计算机操作系统教程.北京:清华大学出版社,20003 尤晋元. UNIX操作系统教程.西安:西安电子科技大学出版社,1995 学生签名: 填表日期: 年 月 日第三部分:指导教师评语第四部分:成绩评定指导教师签名: 填表日期: 年 月 日附录解释调用系统调用的过程:测试程序test.c中的_syscall1是定义在include/asm-i386/unistd.h中的宏:#define _syscall1(type,name,type1

14、,arg1) type name(type1 arg1) long _res; _asm_ volatile (int $0x80 : =a (_res) : 0 (_NR_#name),b (long)(arg1); _syscall_return(type,_res); 其中_syscall_return也定义在该文件中#define _syscall_return(type, res) do if (unsigned long)(res) = (unsigned long)(-125) errno = -(res); res = -1; return (type) (res); whil

15、e (0)所以test.c中_syscall1(int,addtotal,int,num)展开后即:int addtotal(int num)long _res;_asm_ volatile(“int $0x80”:”=a”(_res):”0”(_NR_addtotal),”b”(long)(num);do if (unsigned long)(_res) = (unsigned long)(-125) errno = -(_res); _res = -1; return (int) (_res); while (0)通过软中断int $0x80,其中系统调用号为eax中的_NR_#name,

16、这里也就是_NR_addtotal,在上面的步骤3中有#define _NR_addtotal 259,即259号系统调用。寄存器ebx中存第一个参数num。IDT中第0x80个门(其类型为15,即陷阱门)为系统启动(init/main.c中start_kernel调用i386/kernel/traps.c中trap_init)时设置的,trap_init中set_system_gate(0x80,&system_call);故int $0x80指令通过该系统门后转到内核的system_call处执行。system_call定义在arch/i386/kernel/entry.S中:ENTRY(

17、system_call)/转到此处执行 pushl %eax # save orig_eax SAVE_ALL/把寄存器压入堆栈 GET_CURRENT(%ebx) testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS jne tracesys cmpl $(NR_syscalls),%eax jae badsys call *SYMBOL_NAME(sys_call_table)(,%eax,4) /此时eax=系统调用号=_NR_addtotal=259 movl %eax,EAX(%esp) # save the return valueENTRY(ret

18、_from_sys_call)/从系统调用返回 cli # need_resched and signals atomic test cmpl $0,need_resched(%ebx) jne reschedule /如果需要重新调度则跳去调度 cmpl $0,sigpending(%ebx) jne signal_returnrestore_all: RESTORE_ALLsys_call_table即第一部分2中修改的部分,可以看成一个函数指针数组,按下标指向对应系统调用的函数地址,此处即call *SYMBOL_NAME(sys_call_table)(,%eax,4)调用我们asml

19、inkage int sys_addtotal(int numdata)。上面的SAVE_ALL是定义在arch/i386/kernel/entry.S中的宏:#define SAVE_ALL cld; pushl %es; pushl %ds; pushl %eax; pushl %ebp; pushl %edi; pushl %esi; pushl %edx; pushl %ecx; pushl %ebx; movl $(_KERNEL_DS),%edx; movl %edx,%ds; movl %edx,%es;所以进入系统调用函数后(本文是sys_addtotal),堆栈中参数对应SA

20、VE_ALL中的ebx,即num。在系统调用时,Linux在用户空间通过寄存器而不是堆栈传递参数(可以从宏_systemcall0,_systemcall1,_systemcall5看到),这些传递参数的寄存器是:eax系统调用号,如果有参数的话,ebx,ecx,edx,esi,edi依次存第一个到第五个参数。系统调用时,传递的参数最多5个。进入内核system_call后通过SAVE_ALL把寄存器压入堆栈,系统调用函数定义时asmlinkage int sys_addtotal(int numdata)中asmlinkage表示通过堆栈传递参数。进入系统调用函数后看到堆栈中第一个参数即ebx,第二个参数为ecx,对应了用户空间5个参数的顺序。当然,如果系统调用定义时只有一个参数,则只会使用ebx(位于堆栈中)一个参数了。系统调用返回时保存返回值在寄存器eax中。然后到ret_from_sys_call:从系统调用返回,如果需要调度或有信号待处理则去调度或处理,这超出了本文的范围,最后返回用户空间。18

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1