linux添加系统调用实验步骤

合集下载

编译Linux2.6内核并添加一个系统调用

编译Linux2.6内核并添加一个系统调用

1. 0 让新 内核和 旧内核 都可 以加载 的配置 的步骤 :
my. r h i 8 / o t z ma e/ o t / c /3 6 b o / l g b o a b mv. y t m. p/ o t / s e ma b o S
mv/ o t zma e/o t mln z 261 ..5 3 b / l g b b / i u - ..510 0 v
2 1 年第 4期 0 1

建 电

19 4
编 译 iu26内 并 添 加 一 个 系统调 用 Ln x . 核
张 伟 华 .王 海 英 。高 静
(河南 财经政 法 大学成 功 学院 河 南 郑 州 4 10 5 2 0)
【 摘 要 】 本 文 以实例 来详 细描 述 了从 准备 一直 到使 用新 内核 的 Lnx 。 : iu 26内核 编译过 程 , 然后介 绍 了
轻 易地 对它进 行修 改 .使 我们 能够 根据 自己的要 求 度 身 定制 一个更 高效 、 更稳 定 的 内核 。
系统调 用【 用户 进程 与 系统之 间 的接 口, 们在 2 ] 是 它 内核 中实 现 .其 主要 目的是 使得 用户 可 以使 用操 作 系 统提 供 的操作底 层设 备 的功 能 用 户 程序 肯定 要 操作
mv/ o t y tm. p/ o ' y t m. p 2 6 1 .. 5 b / se ma b oJ s e ma - .. 5 10 03 S , S mk n td/ o g n td 2.. 5 10 0 . 6.5 1 ii b r i i - 6 1 . . 5 3 i 2. 1 r mg v / o t rbgu e n ib / u / r b.o f g

动态添加系统调用

动态添加系统调用

静态及动态添加系统调用――――――――摘之“Linux1.0核心游记”A2.系统调用的添加A2-1静态添加系统调用所谓的静态静态添加系统调用,是指我们直接通过修改核心的源代码而达到的。

只要我们知道Linux下系统调用实现的框架,添加(当然也可以修改)系统调用将会是件非常简单的事情。

该方法的缺点还是有的:1.修改好源代码后需要重新编译核心,这是个非常长和容易发生错误的过程。

2.对于你修改及编译好后所得到的核心,你所做的添加(修改)是静态的,无法在运行时动态改变(所以也就有了下面的动态方法)A2-1-1讨论Linux系统调用的体系在Linux的核心中,0x80号中断是所有系统调用的入口(当然你也可以修改,因为我们有源代码吗:),不过你改了之后只能自己玩玩,要不然人家0x80号中断的程序怎么执行呢?)。

但是还是有办法(可能还有其他办法)。

办法是在你看了下面的“动态添加系统调用”后就知道,这个就留给读者考虑了。

用0x80中断号功能作为所有的系统调用入口点,是系统编写者定义的(也可以说是Linus定义的)。

下面我们看一下其设置的代码(取之2.4核心,我们只看x386)定义于Arch/i386/kernel/traps.c(很简单,就一个函数调用)set_system_gate(SYSCALL_VECTOR,&system_call);!设置0x80号中断SYSCALL_VECTOR默认是0x80(你可以修改)system_call定义在Arch\i386\kernel\entry.Sset_system_gate定义在Arch/i386/kernel/traps.c,具体的代码分析这里就不做介绍了。

大致的功能是把system_call的地址(当然还有其他内容,比如类型值及特权级)设置到IDT (中断描述符表)的第0x80项中(请注意每项是8个字节,在基础有所介绍)。

当用了set_system_gate设置好中断号,并且已经开中断。

LINUX系统实验指导书

LINUX系统实验指导书

《 LINUX系统级应用》课程实验指导书一.实验总学时(课外学时/课内学时):4/6 总学分:2.5(课程)必开实验个数: 4 选开实验个数:2二.适用专业:计算机网络技术(专科)三.三.考核方式及办法:在规定实验时间内完成实验要求,依据实验过程及实验结果在实验现场逐一检查考核。

四.配套的实验教材或指导书:自编实验指导书五. 实验项目:实验1 UNIX基本操作1、实验目的掌握UNIX(LINUX)系统的基本使用方法:系统启动、注销、关闭和关机;帐号管理;文件系统的日常管理;文件系统的权限控制。

2、实验工具及环境UNIX(LINUX)系统网络环境或单机。

3、实验计划学时4学时上机实际操作。

4、实验内容及操作步骤⑴系统启动和关闭①使用自己的账户登录UNIX系统,查看系统提示符确定自己使用的shell程序类型别。

◎开机后,系统自检启动后提示login:(输入:root↙)password:(输入:用户口令↙,root用户为redhat)◎查看/etc/passwd文件可以获得用户使用的shell#grep $LOGNAME /etc/passwd↙可能的显示为:user001:*:200:50::/usr/user001:/bin/sh请思考上述命令怎样得到了当前使用的shell类型的?使用下面的命令也可以查看当前shell:#echo $SHELL②注销和关机命令。

◎用户注销使用:$exit↙或$<ctrl>+<D>↙或$logout↙◎超级用户关机使用:#shutdown↙该命令将结束所有的进程,当执行此命令后系统提示“Safe to Power off or Press Any Key to Reboot”时可以关闭电源或按任一键重启系统。

◎haltsys(halt),reboot只能由超级用户在单用户模式下使用。

⑵帐号管理①添加用户,删除用户,修改个人口令后重新进行登录;◎添加用户的shell命令:#useradd user08↙(Linux系统中可以为adduser)上述命令采用默认属性,UNIX也可以使用选项来指定创建帐户的属性:-c comment用户说明-d directory 指定用户主目录-m 若用户的起始目录不存在则创建-g group指定用户所属组-s shell 指定用户使用的shell-u uid为用户分配标识◎修改口令对linux系统而言,用adduser增加的用户应该随即用passwd命令来修改口令。

计算机操作系统实验指导计算机系统调用

计算机操作系统实验指导计算机系统调用

使用内核编译法添加系统调用
为了验证系统调用是否成功,编写验证代码如下。 #include <stdio.h> #include <linux/kernel.h> #include <sys/syscall.h> #include <unistd.h> int main() { long int a = syscall(三三三); printf("System call sys_helloworld reutrn %ld\n", a); return 0; }
如图地执行结果,我们得到sys_call_table地址:ffffffffabe00一a0 三. 编写Makefile文件,可参考实验指导书地内容。 四. 编译并装入模块 # sudo make //编译 # sudo insmod hello.ko //装入模块 # lsmod //该命令查看所有模块,用以检查hello是否被装入系统 # sudo rmmod hello.ko //卸载模块
三三三 六四 helloworld
sys_helloworld
使用内核编译法添加系统调用
六. 配置内核 # cd /usr/src/linux-四.一六.一0 # sudo make mrproper # sudo make clean # sudo make menuconfig 七. 编译与安装内核(与第七章类似) # sudo make -j八 # sudo make modules -j八 # sudo make modules_install # sudo make install 八. 重启系统 # uname -r 查看此时地内核版本
编译验证代码: # gcc hello.c

linux进程管理的实验报告

linux进程管理的实验报告

实验报告:Linux进程管理1. 引言本实验报告将详细介绍Linux系统中进程管理的相关知识和操作。

进程管理是操作系统中的一个重要组成部分,它负责控制和调度系统中运行的各个进程,确保系统资源的合理分配和进程的正常运行。

在本实验中,我们将通过一系列步骤来了解Linux系统中进程的创建、监控和控制。

2. 实验环境为了完成本实验,我们需要在一台运行Linux操作系统的计算机上进行操作。

本实验报告基于Ubuntu 20.04 LTS操作系统进行撰写,但是适用于大多数Linux 发行版。

3. 实验步骤步骤一:创建新进程在Linux系统中,可以通过fork()系统调用来创建新的进程。

以下是一个简单的示例代码:#include <stdio.h>#include <unistd.h>int main() {pid_t pid = fork();if (pid == 0) {// 子进程逻辑printf("这是子进程\n");} else if (pid > 0) {// 父进程逻辑printf("这是父进程\n");} else {// 进程创建失败printf("进程创建失败\n");}return0;}步骤二:查看进程信息Linux系统提供了多种命令来查看系统中运行的进程信息。

以下是一些常用的命令:•ps:显示当前终端下的进程列表。

•top:实时显示进程的CPU、内存等资源占用情况。

•pstree:以树状结构显示进程的层次关系。

步骤三:杀死进程有时候我们需要终止一个运行中的进程,可以使用kill命令来发送终止信号给目标进程。

以下是一个示例:kill <PID>请将<PID>替换为目标进程的进程ID。

步骤四:进程优先级调整通过调整进程的优先级,可以影响进程在系统中的调度顺序。

在Linux系统中,可以使用nice命令来调整进程的优先级。

linux的进程管理实验总结

linux的进程管理实验总结

linux的进程管理实验总结Linux的进程管理实验总结1. 引言Linux中的进程管理是操作系统的核心功能之一,在实际的系统运行中起着重要的作用。

进程管理能够有效地分配系统资源、管理进程的运行状态和优先级,以及监控进程的行为。

本文将以Linux的进程管理实验为主题,分步骤介绍实验过程及总结。

2. 实验目的本次实验的目的是理解Linux中进程的概念,掌握进程的创建、运行和终止的基本操作,以及进程的状态转换过程。

3. 实验环境本次实验使用的是Linux操作系统,可以选择使用虚拟机安装Linux或者使用Linux主机进行实验。

4. 实验步骤4.1 进程的创建在Linux中,可以使用系统调用fork()来创建一个新的子进程。

在实验中,可以编写一个简单的C程序来调用fork()系统调用,实现进程的创建。

具体步骤如下:(1)创建一个新的C程序文件,例如"process_create.c"。

(2)在C程序文件中,包含必要的头文件,如<stdio.h>和<unistd.h>。

(3)在C程序文件中,编写main()函数,调用fork()函数进行进程的创建。

(4)编译并运行该C程序文件,观察控制台输出结果。

实验中,可以通过观察控制台输出结果,判断新的子进程是否被成功创建。

4.2 进程的运行在Linux中,通过调用系统调用exec()可以用一个新的程序替换当前进程的执行。

可以使用exec()函数来实现进程的运行。

具体步骤如下:(1)创建一个新的C程序文件,例如"process_run.c"。

(2)在C程序文件中,包含必要的头文件和函数声明,如<stdio.h>和<unistd.h>。

(3)在C程序文件中,编写main()函数,调用execl()函数来执行一个可执行程序。

(4)编译并运行该C程序文件,观察控制台输出结果。

实验中,可以通过观察控制台输出结果,判断新的程序是否被成功执行。

linux系统使用实验报告

linux系统使用实验报告Linux 系统使用实验报告一、实验目的本次实验旨在深入了解和熟悉 Linux 操作系统的基本操作、命令行使用以及系统配置,掌握常见的文件管理、进程管理、用户权限管理等功能,提高对 Linux 系统的实际应用能力。

二、实验环境1、操作系统:Ubuntu 2004 LTS2、实验工具:终端模拟器(Terminal)三、实验内容与步骤(一)系统登录与基本命令1、启动计算机,选择 Ubuntu 操作系统,输入用户名和密码登录系统。

2、打开终端模拟器,熟悉常用的基本命令,如`ls` (列出当前目录下的文件和文件夹)、`cd` (切换目录)、`mkdir` (创建新目录)、`rmdir` (删除空目录)等。

(二)文件管理1、在用户主目录下创建一个名为`experiment` 的文件夹,使用`mkdir experiment` 命令。

2、进入该文件夹,使用`cd experiment` 命令。

3、在`experiment` 文件夹中创建一个文本文件`filetxt` ,使用`touch filetxt` 命令。

4、使用`vi` 或`nano` 编辑器打开`filetxt` 文件,输入一些文本内容,并保存退出。

5、查看文件的内容,使用`cat filetxt` 命令。

6、复制文件,使用`cp filetxt file_copytxt` 命令。

7、移动文件,使用`mv filetxt/`命令将文件移动到上级目录。

8、删除文件,使用`rm file_copytxt` 命令。

(三)进程管理1、运行一个后台进程,例如`ping &`,然后使用`jobs` 命令查看后台进程。

2、将后台进程切换到前台,使用`fg %1` (其中%1 为后台进程的编号)命令。

3、终止进程,使用`Ctrl + C` 组合键终止正在运行的进程。

4、查看系统当前运行的进程,使用`ps aux` 命令。

(四)用户权限管理1、创建一个新用户,使用`sudo adduser username` 命令,其中`username` 为新用户的用户名。

1Linux教程实验指导书

Linux程序设计实验指导书目录实验一:linux安装 (3)实验二:常用命令的使用 (10)试验三vi编辑器 (11)实验四 shell编程 (11)实验五常用开发工具 (12)实验六 makefile的编写与使用 (14)实验七 Linux环境编程 (14)实验八 (15)实验一:linux安装一、实验目的1.学会在操作系统安装之前,根据硬件配置情况,指定安装计划2.掌握多操作系统安装前,利用硬盘分区工具(如PQMagic)为Linux准备分区3.掌握Linux操作系统的安装步骤4.掌握Linux系统的简单配置方法5.掌握Linux系统的启动、关闭步骤6.掌握在虚拟机上的Linux安装步骤和使用方法二、实验内容1.安装并使用硬盘分区工具,为Linux准备好分区2.安装Linux系统(如红旗Linux桌面版)3.配置Linux系统运行环境4.正确的启动、关闭系统注意:为了避免新手在第一次安装Linux时,破坏掉磁盘上的有用数据,推荐第一次在winxp系统上的虚拟机上安装linux。

因此需要一下步骤:1.安装winxp下的虚拟机软件vmware,并创建一个虚拟机。

2.在虚拟机环境中安装linux系统。

3.配置Linux系统运行环境4.正确启动、关闭系统。

三、背景知识Linux安装有三种方式,分别是:通过光盘安装、硬盘安装和网络安装。

另外有三种形式,分别是:Linux独立操作系统、Linux与windows共存的双(多)操作系统、Windows下虚拟机安装Linux的双(多)操作系统。

在三种安装方式中,通过光盘安装最为简单,但是需要事先从网络上下载安装镜像文件,并将其刻录到光盘上;或者直接从外面买别人刻好的安装光盘。

由于Linux是开源的操作系统,因此不存在“盗版”的说法。

另一种是通过硬盘安装,需要事先将安装镜像文件下载到本地fat32格式的磁盘分区上,然后重新启动进入纯dos下,进行一些必要的设置就可以从硬盘自动安装了,其后的安装步骤跟光盘安装一样。

实验二 系统调用实验

实验二:系统调用实验实验学时:2学时一、实验目的(1)设计程序,实现结果的不可再现性;使用同步原语,实现结果的可再现性(2)设计程序,使用递归及非递归方法对系统的进程数目进行压力测试,对运行时间进行监控二、实验基本原理简单的系统调用(1)fork();当fork()函数返回值为0时,子进程成功创建,以下为子进程作用域(2)syscall(SYS_getpid);调用系统函数syscall(),返回当前进程号(3)getpid();调用系统函数getpid(),返回当前进程号(4)execl( );头文件:#include <unistd.h>原型:int execl(const char *path, const char *arg, ...);函数说明:execl()用来执行参数path字符串所代表的文件路径,接下来的参数代表执行该文件时传递的argv[0],argv[1].....是后一个参数必须用空指针NULL作结束返回值:成功则不返回值,失败返回-1,失败原因存于errno中三、参考程序1.程序的不可再现性:$cat tc_print.c#include<stdio.h>int main(int argc,char *argv[]){printf("Thead %s has start!\n ",argv[1]);sleep(3);printf("Thread %s ended\n",argv[1]);return(0);}$cat ecp1.c#include<stdio.h>#include<unistd.h>#include<sys/wait.h>#include<sys/types.h>void main(){int *status;char *f="./tc_print"; /*要执行的程序名*/char *argv1[3],*argv2[3],*argv3[3],*argv4[3]; /*执行程序所需的参数*/argv1[0]="./tc_print";argv1[1]="1";argv1[2]=0; /*参数结束的标志*/argv2[0]="./tc_print";argv2[1]="2";argv2[2]=0;argv3[0]="./tc_print";argv3[1]="3";argv3[2]=0;argv4[0]="./tc_print";argv4[1]="4";argv4[2]=0;if(fork()==0) /*创建进程*/{execvp(f,argv1); /*执行程序*/sleep(1);execvp(f,argv2);sleep(1);}else{if(fork()==0) /*创建进程*/{execvp(f,argv3);sleep(1);}else{ wait(status);execvp(f,argv3);sleep(1);}}printf("End program!\n");}2.实现程序结果的可再现性(1)用wait()函数实现程序可再现性#include<stdio.h>int n=0;int status; //改动地点void pp(){n++;if(n>=10)return;wait(&status); //改动地点wait系统调用会使父进程阻塞直到一个子进程结束if(fork()==0){printf("%d",n);for(n=0;n<1000000;n++);}else pp();}int main(){int i;for(i=0;i<3;i++){ pp();printf("\n");}return 0;}(2)用信号量semget()、semctl()、semop()实现进程同步#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include<errno.h>#include<stdlib.h>#include<stdio.h>#include<fcntl.h>#include<unistd.h>#define SEMKEY (key_t)0x200typedef union _senum{int val;struct semid_ds *buf;ushort *array;}semun;static int semid;struct sembuf p1={0,-1,0};//第一个是索引量,第二个-1是p操作,1是v操作。

实验报告 linux系统安装实验

实验报告 linux系统安装实验实验报告:Linux系统安装实验实验目的:通过实际操作,掌握Linux系统的安装步骤及注意事项,了解Linux系统的基本知识。

实验材料:一台个人电脑、Linux系统安装光盘或USB启动盘、安装所需的硬件设备。

实验步骤:1. 准备工作:在进行Linux系统安装之前,首先需要备份好个人电脑中的重要数据,以防在安装过程中数据丢失。

同时,确保安装光盘或USB启动盘的正常性。

2. 设置BIOS:将电脑启动时的引导设备设置为安装光盘或USB启动盘,以便从中启动并进行Linux系统的安装。

3. 启动系统:将安装光盘或USB启动盘插入电脑,重启电脑并按照提示进入系统安装界面。

4. 分区设置:在安装界面中,选择适合自己的磁盘分区方式,可以选择手动分区或者自动分区,根据自己的需求进行设置。

5. 安装系统:选择安装目标,设置主机名和密码等基本信息,然后开始系统的安装过程。

6. 完成安装:安装完成后,根据提示重启电脑,进入新安装的Linux系统。

实验注意事项:1. 在进行安装之前,一定要备份好重要数据,以免在安装过程中造成数据丢失。

2. 在设置BIOS时,确保选择正确的引导设备,以便从安装光盘或USB启动盘中启动系统。

3. 在分区设置时,根据自己的需求选择适合的分区方式,并注意不要误操作导致数据丢失。

4. 在安装过程中,耐心等待系统自动完成安装,不要随意中断或操作,以免造成安装失败。

实验总结:通过本次Linux系统安装实验,我对Linux系统的安装步骤有了更深入的了解,并且掌握了一些安装过程中需要注意的事项。

同时,我也对Linux 系统有了更多的认识,对其使用和管理有了更多的信心和能力。

希望通过今后的实践操作,能够更加熟练地使用Linux系统,为今后的学习和工作打下良好的基础。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

首先,进入到内核源码目录/usr/src/linux-2.6.34中,添加自己的系统调用号。

lyh@lyh:~$ cd /usr/src/linux-2.6.34/
系统调用号在unistd_32.h文件中定义。

内核中每个系统调用号都是
以“__NR_"开头的,在该文件中添加自己的系统调用号
lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/include/asm/unistd_32.h
#define __NR_pwritev 334
#define __NR_rt_tgsigqueueinfo 335
#define __NR_perf_event_open 336
#define __NR_recvmmsg 337
#define __NR_mycall 338
#ifdef __KERNEL__
#define NR_syscalls 339
在内核源文件中该行为#define NR_syscalls 338,在系统调用执行的过程中,system_call()函数会根据该值来对用户态进程的有效性进行检查。

如果这个号大于或等于NR_syscalls,系统调用处理程序终止。

所以应该将原来的#define NR_syscalls 338修改为#define NR_syscalls 339
其次,在系统调用表中添加相应的表项
(1)lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/kernel/syscall_table_32.S
ENTRY(sys_call_table)
.long sys_restart_syscall
.long sys_exit
………………(这里省略了部分)
.long sys_rt_tgsigqueueinfo
.long sys_perf_event_open
.long sys_recvmmsg
.long sys_mycall
(2)lyh@lyh:/usr/src/linux-2.6.34$ sudo vim
arch/h8300/kernel/syscalls.S
#include <linux/sys.h>
#include <asm/linkage.h>
……………………(这里省略了部分)
.long SYMBOL_NAME(sys_vmsplice)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_getcpu)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_mycall)
最后,实现系统调用服务例程。

系统调用服务例程函数名为"sys_xxx”
lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/kernel/sys_i386_32.c asmlinkage long sys_mycall(void)
{
printk("hello, world!\n mycall worked!\n");
}
其中,asmlinkage修饰符是gcc中一个特殊的标志,加了该修饰符的函数必须从堆栈中获取参数。

内核中所有系统调用的实现都使用这个修饰符。

接下来的任务就是重新编译内核了!注意:内核编译完了之后必须重启,否则已经添加的用户系统调用不能使用。

lyh@lyh:~$ sudo /usr/include/bits/syscall.h
#ifndef _SYSCALL_H
# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
#endif
#include <bits/wordsize.h>
#define SYS__sysctl __NR__sysctl
#define SYS_access __NR_access
………………(这里省略了部分)
#define SYS_vm86old __NR_vm86old
#define SYS_waitpid __NR_waitpid
#define SYS_mycall __NR_mycall
#endif
为了检验添加的系统调用是否成功,特编写下面的测试程序。

lyh@lyh:~/linux课程实验/系统调用$ vim test.c
#include <stdio.h>
#include <stdio.h>
#include <syscall.h>
#include <sys/types.h>
#define mycall() syscall(SYS_mycall)
int main()
{
mycall();
return 0;
}
lyh@lyh:gcc test.c -o test
lyh@lyh: ./test
这样一个简单的系统调用便添加成功了!。

相关文档
最新文档