实验1 增加新的系统调用

合集下载

编译内核-新增Linux系统调用过程

编译内核-新增Linux系统调用过程

一、题目:新增Linux系统调用(1)需要重新编译Linux内核(2)增加一个Linux的系统调用(3)写一个用户程序进行调用测试。

系统调用实现的功能:计算一个数字的三次方,并打印出来。

二、版本:编译版本:Win10上虚拟机(Virtual Box) Ubuntu(64bit)15.04系统原内核版本:3.19.0编译的新内核源码版本:3.2.75不同内核版本,32位和64位文件位置以及文件名可能有所不同。

添加系统调用时要根据自己的版本的文件位置和文件名修改相应的三个文件。

三、步骤:1.前期准备:下载内核及解压1.1下载内核:1.2打开终端获得权限然后再输入su输入刚刚设置的密码。

1.3移动文件并解压下载目录2.添加系统调用2.1添加系统调用函数在文末添加调用函数。

然后保存,关闭。

2.2 添加调用函数声明在文末#endif前添加函数声明。

然后保存关闭。

2.3添加系统调用号因为前一个系统调用号是311 所以这里我们写312将原本的#defineNR_syscalls (__NR_syscall_max+1)修改为:#defineNR_syscalls (__NR_syscall_max + 2)然后保存,关闭。

3.编译内核3.1安装基本编译器套件3.2编译3.1make mrproper清除以前配置(如果是第一次编译,不用执行此操作)3.2 make menuconfig配置内核(此处选择了默认配置)3.3 make编译内核如果电脑是双核则也可以用make–j4代替make(双核编译会更快一些)接下来就是漫长的等待过程,不过要随时注意是否编译过程中因有错误而停止。

我的电脑用了两个小时。

(也有教程里用的是make bzlmage和makemodules,make bzlmage+make modules=make)4.安装内核4.1makemodules_install4.2makeinstall4.2 reboot重启(或不使用命令直接对电脑进行重启)ﻩ重启之后在开机时候开机时候,如果是虚拟机需要同时按esc和↑键出现开机启动项(如果是真机开机一般会自动出现开机启动项),选择新建的内核版本进入。

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

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文件。

添加系统调用实验报告

添加系统调用实验报告

一、构建基本的实验环境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中定义。

操作系统实验一向LINUX内核增加一个系统调用

操作系统实验一向LINUX内核增加一个系统调用

操作系统实验一向LINUX内核增加一个系统调用一、背景介绍操作系统是计算机硬件与应用程序之间的接口,负责管理和调度计算机系统的各种资源,并提供用户与计算机系统的交互界面。

内核是操作系统的核心部分,负责管理和分配计算机系统的资源,执行各种任务。

系统调用是操作系统提供给应用程序的一种接口,可以让应用程序访问内核提供的功能,例如文件操作、进程管理、网络通信等。

在一些情况下,我们可能需要在LINUX内核中增加新的系统调用,以满足特定的需求。

本文将介绍如何向LINUX内核增加一个系统调用的具体步骤。

二、增加系统调用的步骤1.编写系统调用的具体实现代码首先,我们需要编写一个具体的系统调用的实现代码。

在LINUX内核中,系统调用的实现代码通常位于内核的/syscalls目录下。

我们可以在该目录下新建一个.c文件,编写我们自己的系统调用代码。

2.修改内核源代码3.更新系统调用表每个系统调用都在内核中有一个唯一的标识符,存储在一个叫做系统调用表的地方。

我们需要更新系统调用表,将新增的系统调用添加到表中。

这样,用户程序才能够通过系统调用号来调用新增的系统调用。

4.重新编译内核在修改完内核源代码后,我们需要重新编译内核。

这通常涉及到一些繁琐的步骤,例如配置内核选项、编译内核、安装内核等。

在重新编译内核之后,我们需要重新启动计算机,使新的内核生效。

5.修改用户程序最后,我们需要修改用户程序,以便能够调用新增的系统调用。

用户程序通常是通过C语言编写的,我们可以在用户程序的代码中添加对新增系统调用的调用代码。

三、实验结果在完成上述步骤后,我们就成功地向LINUX内核增加了一个系统调用。

用户程序可以通过系统调用调用自己新增的系统调用,从而实现特定的功能。

总结:本文介绍了向LINUX内核增加一个系统调用的具体步骤,包括编写系统调用的具体实现代码、修改内核源代码、更新系统调用表、重新编译内核和修改用户程序。

在实施这些步骤之前,我们需要对操作系统和内核的相关概念有一定的了解,并具备一定的编程能力。

增加系统调用实验报告(3篇)

增加系统调用实验报告(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. 修改系统调用表接下来,我们需要修改内核源代码中的系统调用表,以注册我们创建的系统调用。

操作系统实验 为linux添加一个系统调用

操作系统实验 为linux添加一个系统调用

进程控制的基础
Linux进程创建及分析
第一个进程事实上就是Linux kernel本身,像所有其 他的进程一样,Linux kernel本身也有代码段,数据段, 堆栈。只不过Linux kernel这个进程自己来维护这些段, 这一点是与其他进程不同的地方。第一个进程是唯一一个 静态创建的进程,在Linux kernel编写并且编译的时候创 建。 在Linux内核中,这个进程被称作init task/thread(pid 0)。 系统中其他的进程都通过复制父进程来产生,Linux 提供两个系统调用fork和clone来实现这个功能,广义上, 我们都叫它们fork( ),这也是Unix系统的传统叫法,表示 一个进程分叉又产生两个进程。对fork( )具体使用方法我 们稍后阐述。
关键点五
一般来说,在fork之后时父进程先执行还是子进程先执行 是不确定的。这取决于内核所使用的调度算法。如果要求父子 进程之间相互同步,则要求某种形式的进程之间通信。
进程的创建和销毁——exec理解
关键点一
fork( )创建了一个程序,但是如果这个子程序只能 局限在自身的代码段范围之中(不能去执行别的程序), 那么fork( )也就没有太多的实际意义。在Linux中,exec 调用用于从一个进程的地址空间中执行另外一个进程, 覆盖自己的地址空间。有了这个系统调用,shell就可以 使用fork+exec 的方式执行别的用户程序了。一个进程 使用exec执行别的应用程序之后,它的代码段,数据段, bss段和堆栈段都被新程序覆盖,唯一保留的是进程号。
进程的创建和销毁——fork分析
1. 为新进程分配一些基本的数据结构。具体到Linux,最重要的 比如一个新的进程好pid,一个task_struct和一个8K大小的联合 体(存放thread_info和内核栈)等。 2. 共享或者拷贝父进程的资源,包括环境变量,当前目录,打 开的文件,信号量以及处理函数等。 3. 为子进程创建虚拟地址空间。子进程可能跟父进程共享代码 段,数据段也可能采用COM(写时拷贝)的策略使fork( )的速 度和灵活性得到提高。 4. 为子进程设置好调度相关的信息,使得子进程在适当的时候 独立于父进程,能被独立调度。 5. fork( )的返回。对于父进程来说,for( )函数直接返回子进程的 pid;而对于子进程来说,是在子进程被第一次调度执行的时候, 返回0。

实验一 操作系统系统调用 实验报告

实验一 操作系统系统调用 实验报告

Linux系统调用实验报告一、实验目的深入理解操作系统是虚拟机二、实验方法利用UNIX/LINUX所提供的系统调用来编写C语言程序,程序中要体现出一些典型的系统调用(函数)三、实验任务编写一个C语言程序,该程序将一个存放了一系列整数的文本文件进行排序,每个整数占据文件的一行,排序的结果存放到一个新的文件之中。

源文件和目标文件的文件名由命令行输入。

例如:假设可执行文件的文件名是sort,源文件与目标文件的名字分别是data和newdata,那么命令行的情形为如下所示内容:./sort data newdata四、实验要点命令行参数传递、系统调用的使用五、实验内容5.1 命令行参数传递C语言标准规定,C语言程序的入口函数(main 函数)的定义如下:int main(int argc, char** args)其中,argc 表示args这个指针数组元素的数量,而args则储存程序的命令行参数,其中,args[0]储存着可执行文件的文件名,args[1]储存第一个命令行参数,如此类推。

以在命令行中输入./sort data newdata 为例,args[0]的值为“./sort”,args[1]的值为”data”,args[2]的值为”newdata”。

5.2 打开文件在操作系统中,需要对一个文件进行读写操作前需要打开文件。

open这个系统调用的作用就是打开指定的文件,并返回一个文件描述符。

通过这个文件描述符可以对文件进行读写操作。

open系统调用的定义如下:int open(const char* pathname, int flags)int open(const char* pathname, int flags, mode_t mode)其中,pathname是要打开文件的路径,flags参数指定文件打开的方式,这个参数可以通过多个常数的位或运算传递多种的方式,其中包括只读(O_RDONLY),只写(O_WRONLY),读写(O_RDWR),创建文件(O_CREAT),追加方式打开(O_APPEND);当使用O_CREAT方式打开文件时,可以通过一个额外的mode参数来控制所创建文件的权限。

二.掌握系统调用的实现过程,通过编译内核方法,增加一个新

二.掌握系统调用的实现过程,通过编译内核方法,增加一个新

二.掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。

另编写一个应用程序,调用新增加的系统调用。

(1) 实现的功能是:文件拷贝;操作步骤:1。

先在/usr/src/linux-2.4.18-3/kernel/sys.c文件末尾添加mycopy_s.c里的代码。

2。

修改文件 /usr/src/linux-2.4.18-3/include/asm-i386/unistd.h文件在文件中相应位置加上:#define __NR_mycopy 2393.修改文件 /usr/src/linux-2.4.18-3/arch/i386/kernel/entry.S文件在文件中相应位置加上:.long SYMBOL_NAME(sys_mycopy)编译内核:(过程中要先后使用的命令如下,其中后两步操作为非必要,若不执行,则新内核下某些系统功能将无法实现)make mrpropermake oldconfigmake depmake cleanmake bzImagemake modulesmake modules_installmaek install这几步均成功完成后,新内核已经生成,执行如下步骤:cp /usr/src/linux-2.4.18-3/arch/i386/boot/bzImage /boot/bzImage-new cp /usr/src/linux-2.4.18-3/System.map /boot/System.map-newln –sf /boot/System.map-new /boot/System.map然后进入 /etc/lilo.conf(本机采用Lilo配置),添加如下代码:image=/boot/bzImage-newlabel=linux-newroot=/dev/hda1 /* hda1为安装linux的分区 */然后进入 /sbin,运行lilo,完成配置。

实验报告增加新的系统调用参考模板

实验报告增加新的系统调用参考模板

操作系统《实验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增加系统调用

中国地质大学(武汉)《操作系统原理》课程实验报告数据科学与大数据技术专业班级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&apos;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。

实验2.4_系统调用_实验报告

实验2.4_系统调用_实验报告

<系统调用>实验报告题目: 系统调用1、实验目的向现有Linux内核加入一个新的系统调用从而在内核空间中实现对用户空间的读写。

例如,设计并实现一个新的内核函数mycall( ),此函数通过一个引用参数的调用返回当前系统时间,功能上基本与gettimeofday( )相同。

也可以实现具有其它功能的系统调用。

2、实验内容与步骤1. 添加新调用的源代码在/usr/src/linux-3.16.6-10/kernel/sys.c中添加相应的调用代码asmlinkage int sys_mycall(struct timeval *tv){struct timeval ktv;MOD_INC_USE_COUNT;do_gettimeofday(&ktv);if (copy_to_user(tv,&ktv,sizeof(ktv))){MOD_DEC_USE_COUNT;return -EFAULT;}MOD_DEC_USE_COUNT;return 0;}2. 连接系统调用a、修改/usr/src/linux-3.16.6-10/include/asm-i386/unistd.h,在系统调用列表后面相应位置添加一行#define _NR_mycall 222新增加的调用号位222b、修改/usr/src/linux-3.16.6-10/arch/i386/kernel/entry.S在sys_call_table[]清单最后添加一行.long SYMBOL_NAME(sys_mycall)3. 重建新的Linux内核cd /usr/src/linux-3.16.6-10/make mrpropermake oldconfigmade depmake cleanmake bzImagemake modulesmake modules_installmake install保存配置文件, 开始编译内核:4. 重建引导信息a、在/boot/grub/grub.conf中自己添加一条新的启动选项,并使该选项指向vimlinuz-3.16.6-10customb、重新安装grub5. 重新引导从新的内核进入6. 修改/usr/lib/bcc/include/unistd.h,在系统调用列表后面相应位置添加一行#define _NR_mycall 2227.编写程序测试test.c:#include <linux/unistd.h>#include <linux/time.h>#include <stdio.h>_syscall1(int,mycall,struct timeval *,thetime)main(){struct timeval gettime;struct timeval mycalltime;gettimeofday(&gettime,NULL);mycall(&mycalltime);printf("gettimeofday:%d%d\n",_sec,_usec);printf("mycall:%d%d\n",_sec,_usec);}编译运行得到如下结果:参考程序当中有若干需要注意的地方, 在编译的时候遇到错误和警告, 提示没有声明NULL需要加上#include<stdio.h>头文件, 由程序的输出结果相同可知, mycall和gettimeofday具有相同的功能.实验结果正确.。

实验一DOS系统调用的扩充

实验一DOS系统调用的扩充

实验一DOS系统调用的扩充一.目的了解并掌握扩充DOS系统调用的方法。

二.要求1. 了解DOS中系统调用的实现机制(1) DOS中断类型(利用软中断)(2) 中断向量(3) 系统调用服务例程的驻留(4) 系统调用服务的激活2. 掌握扩充DOS系统调用的方法。

三.内容1. 找出一个空闲的中断类型号在DEBUG状态下,显示中断向量(每个占4个字节)表,找出一个空闲的中断类型号(F1H ~ F F H),以此软中断作为新增加的系统调用。

2. 编写系统调用服务例程并驻留除编写一个汇编程序syscall.asm,包括以下内容。

(1) 系统调用服务例程其功能可以很简单,如显示:已执行系统调用;(2) 初始化程序设置新的中断向量;驻留新增加的服务例程3. 编写一个用户程序user.asm先显示本程序已执行的信息,再调用新增加的系统调用服务例程(用int h )。

四.预备知识1. 中断向量表2. 用到的DOS 系统功能调用31H 终止用户程序并驻留内存09H 显示字符串35H 取中断向量25H 置中断向量3. 可执行文件的结构(1) COM 文件只有一个分段,无堆栈段;程序的长度小于64KB ;003FFH IP CS 中断 类型0 中断 类型255程序首部必须预留100H (256B )字节的空间,作为程序段前缀。

在位移100H 处是一条可执行指令;程序中的子程序必须为近过程属性(NEAR ,即不能修改段地址,缺省值)。

DOS 将一个COM 文件装入内存时,寄存器CS (代码段)、DS (数据段)、ES (附加数据段)、SS (堆栈段)等,均指向PSP(程序段前缀)的起始地址;程序的执行代码,装入在代码段偏移的100H 处。

(2) EXE 文件允许有多个分段;程序的长度只受当前内存可用空间的限制; 程序也必须预留出100H 的空间,且在位移100H 处也是一条可执行指令;CS=DS=ES=SS CS:100程序的起始标号与END语句说明的开始地址一致;程序中的子程序既可为NEAR,也可为FAR。

操作系统实验一 向LINUX 内核增加一个系统调用

操作系统实验一 向LINUX 内核增加一个系统调用

操作系统实验一:向Linux内核增加一个系统调用xx711103xx2012年3月18日一、实验目的通过实验,熟悉Linux操作系统的使用,掌握构建与启动Linux内核的方法;掌握用户程序如何利用系统调用与操作系统内核实现通信的方法,加深对系统调用机制的理解;进一步掌握如何向操作系统内核增加新的系统调用的方法,以扩展操作系统的功能。

二、实验内容1.Linux环境下的C或C++编译和调试工具的使用2.向Linux内核增加新的系统调用,系统调用名称和功能自行定义3.Linux新内核的编译、安装和配置4.编写应用程序以测试新的系统调用并输出测试结果三、实验步骤1、安装VirtualBox-4.0.8并在虚拟机上安装ubuntu11.10。

(电脑上本有ubuntu11.10 64位系统,但在编译内核完成后发现参考教程为32位系统,因64位系统与32位系统增加系统调用步骤差别较大,身为初学者的我选择安装虚拟机,并重新编译……)2、安装编译源环境sudo apt-get install build-essential、sudo apt-get install gcc、sudo apt-get install g++编写一个c++或c程序,并使用gcc–o xxx或g++-o xxx进行编译并运行。

3、用sudo apt-get update更新软件源,并用apt-get install linux-source命令下载适合自己的内核。

(当使用过老版本内核时,采用默认的内核配置make oldconfig时,将会造成错误,自己也因此重做一遍)。

4、增加系统调用:第一步:解压文件#cp linux-source-3.0.0.tar.bz2/usr/src拷贝至/usr/src目录#tar xvf linux-source-3.0.0.tar.bz2解压文件第二步:修改源程序,增加系统调用实现#gedit/usr/src/linux-source-3.0.0/kernel/sys.casmlinkage int sys_mycall(int number){printk("hello,my new kernel,xw~!");return number;}第三步:修改头文件,增加系统调用声名#gedit/usr/src/linux-source-3.0.0/arch/x86/kernel/syscall_table_32.S将223行.long sys_ni_syscall改为.long sys_mycall(不要放在其他地方,否侧可能出现错误)第四步:修改系统调用表,注册系统调用。

实验一新增系统调用

实验一新增系统调用

操作系统实验一:向Linux 内核增加一个系统调用一、实验目的通过实验,熟悉Linux 操作系统的使用,掌握构建与启动Linux 内核的方法;掌握用户程序如何利用系统调用与操作系统内核实现通信的方法,加深对系统调用机制的理解;进一步掌握如何向操作系统内核增加新的系统调用的方法,以扩展操作系统的功能。

二、实验类型设计型实验三、预习要求已完成操作系统相关课程,了解操作系统结构。

四、实验设备与环境PII以上电脑一台,已安装Linux操作系统,GCC或其他C语言编译环境。

五、实验原理内核:内核是整个操作系统的最底层,它负责了整个硬件的驱动以及提供了各种系统所需的内核功能,包括防火墙机制,是否支持LVM或Quota 文件系统,以及进程和内存管理和通信功能。

其实内核就是系统上面的一个文件而已,它包含了驱动主机各项硬件的检测程序与驱动模块。

内核文件通常被放置在/boot/vmlinuz中。

(uname –r 命令:显示内核版本信息) 内核模块:由于现在硬件更新速度太快,如果我的内核比较旧,我换了新的硬件,内核肯定无法支持,怎么办?重新拿一个新的内核来处理吗?内核编译的过程是很麻烦的。

为了这个缘故,Linux很早之前就已经开始使用所谓的模块化设置了。

即将一些不常用的类似驱动程序的内容独立出内核,编译成为模块,然后,内核可以在正常运行的过程当中加载这个模块到内核。

这样,在不需要改动内核的前提之下,只要编译出适当的内核模块并加载它,Linux就可以使用新的硬件。

模块被放置在/lib/modules/$(uname -r)/kernel中。

内核编译:内核其实是一个文件,由源代码编译而成的,开机读完BIOS 并加载MBR内的引导程序后,就开始加载内核到内存当中,所以要将它编译成系统可以认识的数据才行。

六、实验1. Linux 环境下的C 或C++编译和调试工具的使用2. 向Linux 内核增加新的系统调用,系统调用名称和功能自行定义3. Linux 新内核的编译、安装和配置4. 编写应用程序以测试新的系统调用并输出测试结果七、实验步骤1、开启电脑,从实验室共享了文件的机器上拷贝内核源码文件linux-2.6.30.tar.gz,以及ncurses-devel-5.5-24.20060715.i386.rpm文件。

操作系统实验报告Linux下的系统调用

操作系统实验报告Linux下的系统调用

操作系统实验报告----- Linux下的系统调用计算机10-4 赵俊楠10081407实验目的:实现多个系统调用实验实验内容:添加简单系统调用、添加随机抽牌系统调、用模块添加系统调用实验步骤:(我是将三个系统调用添加完毕后一起编译的)1.在usr/src/linux-2.4/include/asm i386/unistd.h中添加#define __NR_print_info 259和#define __NR_rank 2602.在usr/src/linux-2.4/arch/i386/kernel/entry.S中添加.long SYMBOL_NAME(sys_print_info)和.long SYMBOL_NAME(sys_rank);3.在usr/src/linux-2.4/kernel中添加asmlinkage int sys_rank(int value,int suit){if (value==1) return (int)(4*13+suit);else return (int)(4*(value-1)+suit);};和asmlinkage int sys_print_info(int testflag){printk(KERN_EMERG " It's my syscall function!\n");return 0;}4.在usr/src/linux-2.4/kernel/ksyms中添加#ifndef __mips__EXPORT_SYMBOL(sys_call_table);#endif至此,三个实验的系统调用添加完毕下面开始编译内核。

5.make cleanmake mrpropermake oldconfigmake depmake bzImagemake modulesmake modules_installmake install在添加系统调用时候一定要专心、仔细,否则在编译的时候会出现错误,改起来很麻烦!!6.重启Linux后,显示界面如下(没有改内核版本号)7.进入新内核后不要忘了将#define __NR_print_info 259和#define __NR_rank260添加到中8.然后编写三个测试程序分别测试新的系统调用结果如下图:关于test_print_info关于card关于call和test_call实验总结:本次实验的内容涉及到Linux的系统调用。

操作系统实验1-系统调用实验

操作系统实验1-系统调用实验

实验一系统调用1. 基本信息2. 实验内容使用系统调用,用C或C++写一个程序,实现如下功能:从一个文件中读出数据,写入另一个文件中。

3. 实验目的(1) 通过实验,加深对系统调用概念的理解,了解其实现机制以及使用方式。

(2) 通过在Linux操作系统上编写和调试简单程序,进一步熟悉Linux操作系统的使用,初步掌握linux环境下的C或C++编译和调试工具,为进一步理解和学习Linux操作系统的内核结构和核心机制作准备。

4. 设计思路和流程图(1)使用C++语言编写程序,由于Ubuntu系统上尚未安装开发工具,故用文本编写代码,继而在终端编译程序。

(2)该实验涉及I/O操作,使用<fstream>类库将文件数据读取和写入另一文件。

(3)代码:#include <iostream>#include <fstream>using namespace std;int main(int argc, char **argv){ifstream in(argv[2],ios::binary | ios::in);//创建输入流对象 ofstream out(argv[3],ios::binary | ios::out);//创建输出对象char it;while(in.get(it))//循环读取源文件数据out << it;//将数据写入目标文件in.close();out.close();cout << "successful" << endl;system("pause");return 0;}(4)在终端中将程序编程生成可执行程序文件cd /home/irewest/桌面 // cd 文件路径g++ -o copy.out copy.cpp 2 /home/irewest/桌面/in.txt /home/irewest/桌面/out.txt //g++ -o 程序转化的文件名 程序文件名./ copy.out // ./ 程序转化的文件名5. 实验体会(1) 在你的程序中用到了哪些系统调用?这些系统调用的功能是什么?在使用g++编译程序时,会用到系统调用的文件系统控制部分的函数,主要是文件的读与写,这些系统调用主要是文件的读写操作:read 读文件write 写文件open 打开文件create 创建新文件lseek 移动文件指针close 关闭文件(2) 在Windows操作系统中与这些系统调用相对应的Windows32 API分别是什么?写出其函数原型。

实验课一 增加系统调用

实验课一 增加系统调用

NachOS系统调用原理与实现•OS文章由starfire一、背景知识Nachos的全称是“Not Another Completely Heuristic Operating System”,它是一个可修改和跟踪的操作系统教学软件。

它给出了一个支持多线程和虚拟存储的操作系统骨架,可让学生在较短的时间内对操作系统中的基本原理和核心算法有一个全面和完整的了解。

该操作系统核心部分使用C++实现,代码可读性较强。

我们操作系统课程的第一个实验就是基于NachOS。

二、任务简介实验任务内容是为NachOS添加两个系统调用,分别为Print( char * msg)和PrintNum( int num ),作用是在系统控制台上打印字符串和数字。

从API手册可知,操作系统为该任务提供的基础设施有:kernel->synchConsoleOut->PutChar(char ch); // 向控制台写字符kernel->machine->ReadRegister(int num); // 读寄存器kernel->machine->WriteRegister(int num, int value); // 写寄存器kernel->machine->ReadMem(int addr, int size, int * value); // 从用户进程内存读值三、系统虚拟机运行原理使用该系统运行用户空间程序使用nachos –x program_name 命令。

程序从code/threads/启动,创建了Kernel对象并进行初始化(启动主线程、创建线程调度表、中断处理模块、CPU、控制台、文件系统、中断使能等)。

之后,程序创建了用户空间程序,初始化的时候加载了指令集并调用了kernel->machine->WriteRegister 填写CPU寄存器,然后开始执行。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
间的接口。 内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用 (system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调 用相应的的内核函数完成所需的处理,将处理结果返回给应用程序。系统调 用运行在内核态,是用户态进入内核态的唯一入口。
2014-11-14
系统调用分类
。。。。。。。。。。。。。
2014-11-14
编译安装内核
# make modules_install(安装模块)
。。。。。。。。。。。。。。。。
2014-11-14
编译安装内核
#make install(安装内核)
。。。。。。。。。。。。
2014-11-14
系统调用的名字
• 系统调用的名字,比如mysyscall。一旦这个名字确定,那么在系 统调用中几个相关的名字也就确定了。 • 系统调用编号:#define __NR_name NNN (name为系统调用名称,NNN为系统调用对应的号码) 例如: #define __NR_mysyscall 338 • 内核中系统调用的实现程序的函数名字:sys_mysyscall
2014-11-14
添加系统调用函数
• 在内核源码目录(linux-3.17.1)kernel下修改sys.c文件
asmlinkage long sys_mysyscall(int num) { printk("This is my system calling."); return num ; }
2014-11-14
配置内核
• 在usr/src下的内核源码目录(linux-3.17.1)下,输入如下命令: # make menuconfig(需要安装ncurses)
2014-11-14
编译安装内核
• 在usr/src下的内核源码目录(linux-3.17.1)下,输入如下命令: # make (编译内核)
2014-11-14
实验要求
• 按照要求完成实验,写出实验报告。 • 自定义新的系统调用,添加到内核。 • 分析系统调用与库函数之间的区别。 • 完成实验报告,按时提交。
ቤተ መጻሕፍቲ ባይዱ
实验1 增加新的系统调用
目录
实验基础知识介绍
• 系统调用概念 • 系统调用分类 • 系统调用实现
实验目的 实验内容和步骤 实验要求
2014-11-14
系统调用概念
由操作系统实现提供的所有系统调用所构成的集合即程序接口或应用编程接
口(Application Programming Interface,API)。系统调用是应用程序同系统之
2014-11-14
系统调用实现
Linux的系统调用通过int 80h实现,用系统调用号来区分入口函数。 操作系 统实现系统调用的基本过程是:
• • • • • • 应用程序调用库函数(API); API将系统调用号存入EAX,然后通过中断调用使系统进入内核态; 内核中的中断处理函数根据系统调用号,调用对应的内核函数(系统调用); 系统调用完成相应功能,将返回值存入EAX,返回到中断处理函数; 中断处理函数返回到API中; API将EAX返回给应用程序。
Linux操作系统中系统调用分类:
• • • • • • • • • 进程管理,如fork(), clone(), execve(), exit()等。 进程通信,如signal(), msgctl(), pipe()等。 控制硬件,如open(), read(), write()等。 设置系统状态或读取内核信息,如getpid(), getpriority(), setpriority()等。 内存管理,如brk(), mmap(), mlock()等。 系统控制 网络管理 socket控制 用户管理
实验内容
•下载、解压内核 •配置内核 •编译安装内核 •添加系统调用函数 •添加系统调用号 •声明 •测试新的系统调用
下载、解压内核
• 下载内核 在官网:/下载linux内核, 完成后, 将下载文件放入 /usr/src/目录下 • 解压内核 将下载的文件解压缩, 在 /usr/src/目录下, 输入如下命令: # xz -d linux-3.17.1.tar.xz # tar -xvf linux-3.17.1.tar 解压后的文件夹名为:linux-3.17.1
2014-11-14
声明
• 在在内核源码目录(linux-3.17.1)include/linux下修改文件 syscalls.h文件。 文件中加入如下代码: asmlinkage long sys_mysyscall(int num);
2014-11-14
测试新的系统调用
• 编写测试程序(test.c) #include <unistd.h> #include <stdio.h> int main() { syscall(380,1); return 1; } • 执行如下命令查看结果 # cc -o xtdy test.c # cc -o xtdy tese.c
应用程序调用系统调用的过程是:
• 把系统调用的编号存入EAX • 把函数参数存入其它通用寄存器 • 触发0x80号中断(int 0x80)
2014-11-14
实验目的
阅读Linux内核源代码,通过添加一个简单的系统调用实验,进
一步理解Linux操作系统处理系统调用的统一流程。
掌握Linux内核编译方法
2014-11-14
添加系统调用号
• 在内核源码目录arch/x86/include/asm下修改文件unistd.h,在 unistd.h中添加系统调用号,格式为: #define __NR_name NNN • (name为系统调用名称,NNN为系统调用对应的号码) 例如: #define __NR_mysyscall 380 • 然后修改系统中所用的系统调用总数 #define __NR_syscalls 381
2014-11-14
配置内核
• 安装ncurses-5.9: 下载ncurses-5.9.tar.gz文件,并解压 # tar zxvf ncurses-5.9.tar.gz (解压) #cd ncurses-5.9(当前目录) #./configure(检查) #make (编译) #make install(安装)
相关文档
最新文档