实验1 增加新的系统调用
编译内核-新增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内核,用新的内核启动系统,使用新的系统调用(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内核增加一个系统调用的具体步骤。
二、增加系统调用的步骤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. 修改系统调用表接下来,我们需要修改内核源代码中的系统调用表,以注册我们创建的系统调用。
操作系统实验 为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,完成配置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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(安装)