添加系统调用实验报告
linux实验_添加系统调用-完整版

实验一添加一个新的系统调用一、实验目的理解操作系统内核与应用程序的接口关系;加深对内核空间和用户空间的理解;学会增加新的系统调用。
二、实验内容与要求首先增加一个系统调用函数,然后连接新的系统调用,重建新的Linux内核,用新的内核启动系统,使用新的系统调用(2.4内核和2.6内核任选一个)三、实验指导(2.6版本)⑴获得源代码(本次实验的内核版本是2.6.22.5,必须是root用户)1.从教育在线上下载内核源代码到本地磁盘;保存在/usr/src目录下2.进入终端,输入命令cd /usr/src 进入/usr/src目录(可以输入ls命令会发现目录下有一个名为LINUX_2_6_22_5.TAR.BZ2的压缩文件)3.当前目录下(/usr/src)输入命令tar –xjvf LINUX_2_6_22_5.TAR.BZ2 解压缩源代码,命令执行完毕后,会出现/usr/src/linux-2.6.22.5文件夹4.修改文件夹下的3个文件第一,编辑/usr/src/linux-版本号/kernel/sys.c文件,添加函数:asmlinkage long sys_mycall(long number){printk(“call number is %d\n”,number);return number;}第二,修改/usr/src/linux-版本/include/asm-i386/unistd.h添加一行#define __NR_mycall 324 到当前的最大系统调用号之后,比如原来最大的是323,在323的这一行之后加上一行#define __NR_mycall 324修改#define NR_systemcalls 的值,改成原来的值+1,比如原来是324 改成325第三,编辑/usr/src/linux-版本/arch/i386/kernel/syscall_table.S,在文件最后加上一行:.long sys_mycall5.重新编译内核在终端输入命令,进入源代码文件夹,cd /usr/src/linux-2.6.22.5 依次执行如下命令:make mrpropermake cleanmake xconfig (自己配置内核,出现图形对话框后,直接点保存,关闭)make(耗时最长,大约20分钟)make modules_install (安装模块)以上命令执行完毕后,会在当前目录下生成一个名为System.map的文件,会在/usr/src/linux-版本号/arch/i386/boot/下生成一个bzImage文件。
实验3:添加系统调用

实验6:实现同步事件原语(参考课本中的实验六)采用添加模块的方法,实现下面四个系统调用:(1)int eventopen(int key)创建或打开一个同步事件,返回其句柄。
参数:key=0时,创建新同步事件,返回其句柄;key>0时,如果关键字为key的同步事件已经创建,则返回其句柄,否则创建关键字为key的同步事件并返回其句柄。
key<0时,报错,返回-1。
注意:一个进程可以多次打开同一个事件,应该获得不同的句柄。
(2)int eventclose(int evtid)关闭由事件句柄evtid指定的同步事件。
返回值=0时,正常完成。
注意:一个同步事件可以被多个进程打开,只有当所有打开者都执行关闭后,才能删除该同步事件。
(3)int eventwait(int evtid)调用进程在同步事件evtid上阻塞,挂入与evtid相关的等待队列中。
(4)int eventsig(int evtid)解挂所有在同步事件evtid上阻塞的进程。
实验步骤:1)实现上述4个系统调用的函数体asmlinkage long sys_xxx(···){······}需要注意:(1)事件句柄设计·是一个整数·系统可以验证句柄的合法性·通过句柄可以找到唯一对应的同步事件的数据结构(2)在编程中考虑多机环境下的互斥问题(3)内核中与等待队列相关的数据结构和函数:wait_queue_head_t wq;定义一个进程等待队列wqinit_waitqueue_head(&wq);初始化进程等待队列wqinterruptible_sleep_on(&wq);调用者挂入等待队列wq中并置为阻塞状态(无返回值)wake_up_interruptible(&wq);从等待队列wq中解挂一个进程并置为就绪状态wait_event_interruptible(wq, conditin);调用者挂入等待队列wq中并置为阻塞状态,有返回值:当条件condition为真时,返回0;为假时,返回值≠0。
操作系统实验一向LINUX内核增加一个系统调用

操作系统实验一向LINUX内核增加一个系统调用一、背景介绍操作系统是计算机硬件与应用程序之间的接口,负责管理和调度计算机系统的各种资源,并提供用户与计算机系统的交互界面。
内核是操作系统的核心部分,负责管理和分配计算机系统的资源,执行各种任务。
系统调用是操作系统提供给应用程序的一种接口,可以让应用程序访问内核提供的功能,例如文件操作、进程管理、网络通信等。
在一些情况下,我们可能需要在LINUX内核中增加新的系统调用,以满足特定的需求。
本文将介绍如何向LINUX内核增加一个系统调用的具体步骤。
二、增加系统调用的步骤1.编写系统调用的具体实现代码首先,我们需要编写一个具体的系统调用的实现代码。
在LINUX内核中,系统调用的实现代码通常位于内核的/syscalls目录下。
我们可以在该目录下新建一个.c文件,编写我们自己的系统调用代码。
2.修改内核源代码3.更新系统调用表每个系统调用都在内核中有一个唯一的标识符,存储在一个叫做系统调用表的地方。
我们需要更新系统调用表,将新增的系统调用添加到表中。
这样,用户程序才能够通过系统调用号来调用新增的系统调用。
4.重新编译内核在修改完内核源代码后,我们需要重新编译内核。
这通常涉及到一些繁琐的步骤,例如配置内核选项、编译内核、安装内核等。
在重新编译内核之后,我们需要重新启动计算机,使新的内核生效。
5.修改用户程序最后,我们需要修改用户程序,以便能够调用新增的系统调用。
用户程序通常是通过C语言编写的,我们可以在用户程序的代码中添加对新增系统调用的调用代码。
三、实验结果在完成上述步骤后,我们就成功地向LINUX内核增加了一个系统调用。
用户程序可以通过系统调用调用自己新增的系统调用,从而实现特定的功能。
总结:本文介绍了向LINUX内核增加一个系统调用的具体步骤,包括编写系统调用的具体实现代码、修改内核源代码、更新系统调用表、重新编译内核和修改用户程序。
在实施这些步骤之前,我们需要对操作系统和内核的相关概念有一定的了解,并具备一定的编程能力。
增加系统调用实验报告(3篇)

第1篇一、实验目的1. 了解系统调用的基本概念和作用。
2. 掌握在Linux内核中增加系统调用的方法。
3. 熟悉系统调用在用户空间和内核空间之间的交互过程。
4. 提高编程能力和系统理解能力。
二、实验环境1. 操作系统:Linux2. 编译器:gcc3. 开发工具:内核源代码、makefile三、实验原理系统调用是操作系统提供的一种服务,允许用户空间程序请求内核空间的服务。
在Linux内核中,系统调用通过系统调用表来实现。
增加系统调用需要修改内核源代码,并重新编译内核。
四、实验步骤1. 创建系统调用函数首先,我们需要创建一个系统调用函数,该函数将实现一个简单的功能,例如打印一条消息。
以下是一个简单的系统调用函数示例:```cinclude <linux/module.h>include <linux/kernel.h>include <linux/init.h>static int __init hello_init(void) {printk(KERN_INFO "Hello, World!\n");return 0;}static void __exit hello_exit(void) {printk(KERN_INFO "Goodbye, World!\n");}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Your Name");MODULE_DESCRIPTION("A simple system call module");MODULE_VERSION("0.1");```2. 修改系统调用表接下来,我们需要修改内核源代码中的系统调用表,以注册我们创建的系统调用。
实验报告增加新的系统调用参考模板

操作系统《实验2》实验报告实验项目2:增加新的系统调用学号1209050123 姓名宋玉美课程号实验地点指导教师万少华时间2013.11评语:成绩教师签字万少华线性表链式存储(双向链表)插入、删除运算1、预备知识:Linux内核结构、Linux内核源码、Linux系统调用2、实验目的:增加新的系统调用3、实验内容及要求:(1)增加新的系统调用新增的系统调用名为get_proc_run_time,其功能是根据指定的进程pid,从该进程的进程描述符task_struct结构中提取出它的系统时间stime与用户时间utime (2)编译内核用编译内核的方法,将其增加到内核源码并编译内核(3)程序测试在用户空间编写测试程序测试该系统调用。
程序中调用此系统调用能准确的度量一个程序的时间效率,考虑是否还有别的方法比这更准确的学生信息,参数x, i,j从键盘输入(4)给出程序运行截图。
4、该文档的文件名不要修改,存入<学号><姓名> 命名的文件夹中5、该表中的数据只需填空,已有内容不要修改1.添加系统调用函数,修改文件/usr/src/linux—3.5/kernel/sys.c2. 添加系统调用号,修改文件/arch/x86/systemcalls/syscall_32.tbl3. 添加声明到头文件,修改文件,/include/linux/syscalls.h4. 重新编译内核(前几步只顾着运行忘记截图了,不好意思哈老师~)1)安装ncurses2)make menuconfig3)make dep 确定依赖性4)make clean 清理编译中间文件5)make bzImage 生成新内核6)make modules 生成modules 7)安装modules9)安装内核make install 10)配置grub引导程序13)重启。
重启系统,从grub菜单中选中新内核引导linux。
linux系统调用实验报告

竭诚为您提供优质文档/双击可除linux系统调用实验报告篇一:linux系统调用实验报告西安邮电大学(计算机学院)课内实验报告实验名称:系统调用专业名称:软件工程班级:软件学生姓名:学号(8指导教师:xxxxx实验日期:20XX年5月31日一.实验目的及实验环境实验目的:1)了解系统调用,学习系统调用函数的使用;2)理解调用系统调用与直接调用内核函数的区别;实验环境:ubuntu二.实验内容1)对比调用系统调用和直接调用内核函数的区别;2)跟踪系统调用的执行;三.实验原理1)系统调用系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。
用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。
从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户空间。
总的概括来讲,系统调用在系统中的主要用途无非以下几类:?控制硬件——系统调用往往作为硬件资源和用户空间的抽象接口,比如读写文件时用到的write/read调用。
?设置系统状态或读取内核数据——因为系统调用是用户空间和内核的唯一通讯手段[2]所以用户设置系统状态,比如开/关某项内核服务(设置某个内核变量),或读取内核数据都必须通过系统调用。
比如getpgid、getpriority、setpriority、sethostname ?进程管理——一系统调用接口是用来保证系统中进程能以多任务在虚拟内存环境下得以运行。
比如fork、clone、execve、exit等第二,什么服务应该存在于内核;或者说什么功能应该实现在内核而不是在用户空间。
这个问题并没有明确的答案,有些服务你可以选择在内核完成,也可以在用户空间完成。
操作系统原理-实验-linux增加系统调用

中国地质大学(武汉)《操作系统原理》课程实验报告数据科学与大数据技术专业班级195182学生姓名钟欢任课教师康晓军完成时间2020年3月31日实验一——实现一个linux的系统调用一、实验目的1.加深对系统调用的理解,掌握增加与调用系统调用的方法。
2.掌握内核编译方法。
二、实验思路1.增加新的系统调用:新增的系统调用名为Hello,其功能是打印输出“This is ZhongHuan ’ s system call ! wo zhong yu cheng gong le !”2.编译内核:用编译内核的方法,将其增加进内核源码并编译内核。
3.测试:在用户控件编写测试程序测试该系统调用。
三、实验步骤1.系统调用的添加在Linux中添加新的系统调用,需执行多个步骤才能添加成功:(1)第一步完成系统调用函数在内核源码目录kernel/sys.c文件中编写待添加的系统调用函数。
该函数的名称应该是新的系统调用名称前面加上sys_标志。
新加的系统调用为hello(void),在kernel/sys.c文件中添加源代码:asmlinkage long sys_hello(void){printk("This is ZhongHuan's system call! wo zhong yu cheng gong le!");return 1;}(2)第二步在系统函数表中表项添加新的系统调用后,需要让Linux内核的其余部分知晓该程序的存在。
在内核源码目录arch/x86/entry/syscalls下修改文件syscall_64.tbl。
该文件用来对sys_call_table[]数组实行原始化,数组包含指向内核中每个系统调用的指针。
在该文件中的最后一行添加自己的系统调用表项:335 64 hello sys_hello(),这样就在数组中添加了新的内核函数指针。
(3)第三步添加系统调用号在内核源码目录arch/x86/include/asm下修改头文件unistd_32.h。
操作系统实验系统调用

操作系统实验系统调用As a person, we must have independent thoughts and personality.实验六系统调用学时:2学时1.实验内容:系统调用实验2.实验目的:通过调用PV操作解决生产者、消费者问题,了解系统中并发进程是怎样同步执行的。
3.实验题目:编写一段程序模拟PV操作实现进程同步,且用PV操作解决生产者、消费者问题。
4.实验提示:⑴PV操作由P操作原语和V操作原语组成。
P操作原语P(s)将信号量s减1,若s<0则执行原语的进程被置成等待状态。
V操作原语V(s)将信号量s加1,若s<=0则释放一个等待的进程。
⑵生产者、消费者问题主要解决的是进程并发执行时访问公共变量的问题。
假定有一个生产者和一个消费者。
生产者每次生产一个产品,并把产品存入共享缓冲区供消费者取走。
消费者每次从共享缓冲区取出一个产品去消费。
禁止生产者将产品放入已满的缓冲区,禁止消费者从空缓冲区内取产品。
⑶模拟程序中对应关系如下:实例代码:开始!当前的产品数[ 0] 加快生产速度呀,没有产品了。
当前的产品数[ 1] 生产了一个产品。
当前的产品数[ 2] 生产了一个产品。
当前的产品数[ 1] 消费了一个产品。
当前的产品数[ 2] 生产了一个产品。
当前的产品数[ 1] 消费了一个产品。
当前的产品数[ 2] 生产了一个产品。
当前的产品数[ 3] 生产了一个产品。
当前的产品数[ 2] 消费了一个产品。
当前的产品数[ 3] 生产了一个产品。
当前的产品数[ 2] 消费了一个产品。
当前的产品数[ 3] 生产了一个产品。
当前的产品数[ 4] 生产了一个产品。
当前的产品数[ 3] 消费了一个产品。
当前的产品数[ 4] 生产了一个产品。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、构建基本的实验环境1.1基本实验环境与前提条件Windows7 、Word 2010、Vmware WorkStation 8.5、AdobeReaderReadHatLinux 9.0,gcc,viLinux内核[V2.4.18]1.2虚拟机的安装及使用1.3将Linux 内核源代码及配置文件传送给虚拟机上的Red Hat Linux V9.0 系统配置网络时遇到这个问题,Determining IP information for eth0... failed; no link present. Check cable?通过查找资料发现是系统的Bug,解决方法如下:到/etc/sysconfig/network-scripts/ifcfg-eth0在文件最后一行中加入check_link_down () {return 1;}另外如果存在/etc/sysconfig/networking/profiles/default/ifcfg-eth0 文件,则同样在其中加入这一段东西即可,然后重启系统。
设置网络为DHCP,重新启动就可以,啦,直接上图最后将内核代码下载到/root目录下二、Linux 内核编译、配置与调试2.1 内核配置与编译2.1.1、解压内核源代码文件tar -zxf linux-2.4.18.tar.gz2.1.2、解压后如下2.1.3、拷贝linux,命名为linux-2.4.18cp -r linux linux-2.4.182.1.4、移动config-2.4.18forMP.txt到linux-2.4.18根目录,替换掉.config2.1.5、进入linux-2.4.18目录,配置和编译内核模块make oldconfigmake depmake cleanmake bzImagemake modules2.2 内核安装与测试2.2.1安装内核映像文件cp arch/i386/boot/bzImage /boot/vmlinux-2.4.182.2.2拷贝和安装Linux系统映射文件System.map,并创建其与系统映射文件System.map之间的符号链接2.2.3执行命令make modules_install 以安装可动态加载的内核模块2.2.4添加启动项的配置利用vi编辑器,vi grub.conf查看/ 所在的位置,为/dev/sda32.2.5reboot重新启动系统,从自己创建的内核启动系统启动后查看内核分别用uname –r,和dmesg查看三、Linux 系统调用添加与实现3.1 在内核增加系统调用3.1.1结构体struct srz_rusage可声明如下:.struct srz_rusage {struct timeval ru_utime; /* user time used */struct timeval ru_stime; /* system time used */long ru_majflt; /* major page faults */long ru_minflt; /* minor page faults */long ru_nswap; /* swaps */};3.1.2添加到linux-2.4.18/include/linux下的resource.h中3.1.3添加的系统调用名称为:int get_process_usage(pid_t, struct srz_rusage*);参考的getrusage和sys_getrusage的代码在linux-2.4.18/linux/kernel/sys.c下面3.1.4分析getrusage()和sys_getrusage()的源代码1)数据结构rusage 在头文件resource.h中定义。
struct rusage {struct timeval ru_utime; /* user time used */struct timeval ru_stime; /* system time used */long r u_maxrss; /* maximum resident set size */long r u_ixrss; /* integral shared memory size */long r u_idrss; /* integral unshared data size */long r u_isrss; /* integral unshared stack size */long r u_minflt; /* page reclaims */long r u_majflt; /* page faults */long r u_nswap; /* swaps */long r u_inblock; /* block input operations */long r u_oublock; /* block output operations */long r u_msgsnd; /* messages sent */long r u_msgrcv; /* messages received */long r u_nsignals; /* signals received */long r u_nvcsw; /* voluntary context switches */long r u_nivcsw; /* involuntary " */};2)函数getrusage()的作用是获取系统资源使用情况。
/** It would make sense to put struct rusage in the task_struct,* except that would make the task_struct be *really big*. After* task_struct gets moved into malloc'ed memory, it would* make sense to do this. It will make moving the rest of the information* a lot simpler! (Which we're not doing right now because we're not* measuring them yet).** This is SMP safe. Either we are called from sys_getrusage on ourselves* below (we know we aren't going to exit/disappear and only we change our* rusage counters), or we are called from wait4() on a process which is* either stopped or zombied. In the zombied case the task won't get* reaped till shortly after the call to getrusage(), in both cases the* task being examined is in a frozen state so the counters won't change.** FIXME! Get the fault counts properly!*/int getrusage(struct task_struct *p, int who, struct rusage *ru){struct rusage r;memset((char *) &r, 0, sizeof(r));switch (who) {case RUSAGE_SELF:r.ru__sec = CT_TO_SECS(p->times.tms_utime);r.ru__usec = CT_TO_USECS(p->times.tms_utime);r.ru__sec = CT_TO_SECS(p->times.tms_stime);r.ru__usec = CT_TO_USECS(p->times.tms_stime);r.ru_minflt = p->min_flt;r.ru_majflt = p->maj_flt;r.ru_nswap = p->nswap;break;case RUSAGE_CHILDREN:r.ru__sec = CT_TO_SECS(p->times.tms_cutime);r.ru__usec = CT_TO_USECS(p->times.tms_cutime);r.ru__sec = CT_TO_SECS(p->times.tms_cstime);r.ru__usec = CT_TO_USECS(p->times.tms_cstime);r.ru_minflt = p->cmin_flt;r.ru_majflt = p->cmaj_flt;r.ru_nswap = p->cnswap;break;default:r.ru__sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime);r.ru__usec = CT_TO_USECS(p->times.tms_utime +p->times.tms_cutime);r.ru__sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime);r.ru__usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime);r.ru_minflt = p->min_flt + p->cmin_flt;r.ru_majflt = p->maj_flt + p->cmaj_flt;r.ru_nswap = p->nswap + p->cnswap;break;}return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;}3)sys_getrusage()只是调用了内核函数getrusage(),是内核提供给用户的接口。