搜档网
当前位置:搜档网 › GPFS通用并行文件系统之CentOS上部署GPFS集群

GPFS通用并行文件系统之CentOS上部署GPFS集群

GPFS通用并行文件系统之CentOS上部署GPFS集群
GPFS通用并行文件系统之CentOS上部署GPFS集群

GPFS通用并行文件系统之CentOS上部署GPFS集群

GPFS文件系统能够横跨在所有主机上,分布在所有磁盘上,条带化读写,高性能。信令管理机制,并发性好。可配置failgroup组,可用性高。下面是GPFS 集群的部署过程......

1.环境准备:

yum install -y compat-libstdc++-33 rpm-build kernel-headers kernel-devel imake gcc-c++ libstdc++ RedHat-lsb

2.GPFS安装:

多台服务器都要安装

rpm -ivh gpfs.base-3.4.0-0.x86_64.rpm

rpm -ivh gpfs.docs-3.4.0-0.noarch.rpm

rpm -ivh gpfs.gpl-3.4.0-0.noarch.rpm

rpm -ivh gpfs.msg.en_us-3.4.0-0.noarch.rpm

[root@Web02_a base]# rpm -qa|grep gpfs

gpfs.msg.en_US-3.4.0-0

gpfs.gpl-3.4.0-0

gpfs.base-3.4.0-0

gpfs.docs-3.4.0-0

3.GPFS升级

多台服务器都要安装

rpm -Uvhgpfs.base-3.4.0-21.x86_64.update.rpm

rpm -Uvh gpfs.docs-3.4.0-21.noarch.rpm

rpm -Uvh gpfs.gpl-3.4.0-21.noarch.rpm

rpm -Uvh gpfs.msg.en_US-3.4.0-21.noarch.rpm

[root@Web02_a update]# rpm -qa|grep gpfs

gpfs.gpl-3.4.0-21

gpfs.msg.en_US-3.4.0-21

gpfs.base-3.4.0-21

gpfs.docs-3.4.0-21

4.编译GPFS源码

多台服务器都要安装

[root@Web02_a update]# cd/usr/lpp/mmfs/src/

[root@Web02_a src]# makeLINUX_DISTRIBUTION=REDHAT_AS_LINUX Autoconfig [root@Web02_a src]# make World

[root@Web02_a src]# make InstallImages

[root@Web02_a src]# make rpm #生成rpm包,生成路径会有提示

[root@Web02_a src]# rpm -ivh

/usr/src/redhat/RPMS/x86_64/gpfs.gplbin-2.6.18-308.el5-3.4.0-21.x86_6 4.rpm

[root@Web02_a src]# rpm -qa|grep gpfs

gpfs.gpl-3.4.0-21

gpfs.msg.en_US-3.4.0-21

gpfs.gplbin-2.6.18-308.el5-3.4.0-21

gpfs.base-3.4.0-21

gpfs.docs-3.4.0-21

5.配置主机的时间同步

如果服务器之间时间不同步,部署GPFS集群时会失败

[root@Web02_a src]# crontab -l

#time sync by yangrong at 2014-1-24

*/10 * * * * /usr/sbin/ntpdate https://www.sodocs.net/doc/a014239729.html,>/dev/null 2>&1

[root@Nagios update]# crontab -l

#time sync by yangrong at 2014-1-24

*/10 * * * * /usr/sbin/ntpdate https://www.sodocs.net/doc/a014239729.html,>/dev/null 2>&1

6.配置ssh免密钥登陆

注:也可以配置rsh免密钥,且gpfs默认是使用rsh密钥登陆远端主机

[root@Web02_a src]# cd /root/.ssh/

[root@Web02_a .ssh]# ssh-keygen -t rsa

[root@Web02_a .ssh]# cp id_rsa.pubauthorized_keys

[root@Web02_a .ssh]# ssh Web02_a #登陆自己测试

[root@Web02_a .ssh]# cat /etc/hosts

10.0.0.243 Nagios

10.0.0.236 Web02_a

[root@Web02_a .ssh]# scp -r /root/.sshroot@Nagios:/root #把密钥拷贝到其它主机

[root@Web02_a .ssh]# ssh Nagios

Last login: Fri Jan 24 13:59:19 2014 from192.168.2.53

[root@Nagios ~]# exit

[root@Nagios src]# ssh Web02_a

Warning: Permanently added the RSA host keyfor IP address '10.0.0.236' to the list of known hosts.

Last login: Fri Jan 24 15:03:44 2014 fromlocalhost.localdomain

[root@Web02_a ~]# exit

7.配置GPFS环境变量

[root@Web02_a .ssh]# echo

'exportPATH=$PATH:/usr/lpp/mmfs/bin' >>/etc/profile

[root@Web02_a .ssh]# source /etc/profile

[root@Web02_a .ssh]# mmfs

mmfsadm mmfsd mmfsfuncs.Linux

mmfsck mmfsenv mmfsmnthelp

mmfsctl mmfsfuncs mmfsmount

#接下来的操作只需要在一台服务器上操作即可。此时已配置好互信,所有的配置文件信息自动同步到其它的服务器上。

8.创建集群

[root@Web02_a .ssh]# cat /tmp/gpfsfile

Web02_a:quorum-manager

Nagios:quorum-manager

[root@Web02_a .ssh]# mmcrcluster -N/tmp/gpfsfile -p Web02_a -s Nagios -r /usr/bin/ssh -R /usr/bin/scp

#默认GPFS使用rcp拷贝,使用rsh远程。此处修改远程方式和复制方式

#查询命令:mmlscluster

9.许可配置

[root@Web02_a ~]# mmchlicense server--accept -N Web02_a,Nagios

注:服务节点或quorum节点用server,其它节点用client,client节点只有挂载文件系统的权限,不能更改配置。命令如:

mmchlicense client --accept -N host_a,host_b

10.配置nsd盘

当前采用多个分区部署GPFS集群

当前分区:

[root@Web02_a ~]# fdisk -l /dev/sdb

Disk /dev/sdb: 1073 MB, 1073741824 bytes

255 heads, 63 sectors/track, 130 cylinders

Units = cylinders of 16065 * 512 = 8225280bytes

Device

Boot Start End Blocks Id System

/dev/sdb1 1 13 104391 83 Linux

/dev/sdb2 14 26 104422+

83 Linux

/dev/sdb3 27 39 104422+

83 Linux

/dev/sdb4 40 130 730957+ 5 Extended

/dev/sdb5 40 52 104391 83 Linux

/dev/sdb6 53 65 104391 83 Linux

/dev/sdb7 66 78 104391 83 Linux

[root@Nagios ~]# fdisk -l /dev/sdb

Disk /dev/sdb: 1073 MB, 1073741824 bytes

255 heads, 63 sectors/track, 130 cylinders

Units = cylinders of 16065 * 512 = 8225280bytes

Device

Boot Start End Blocks Id System

/dev/sdb1 1 13 104391 83 Linux

/dev/sdb2 14 26 104422+

83 Linux

/dev/sdb3 27 39 104422+

83 Linux

/dev/sdb4 40 130 730957+ 5 Extended

/dev/sdb5 40 52 104391 83 Linux

/dev/sdb6 53 65 104391 83 Linux

/dev/sdb7 66 78 104391 83 Linux

编辑nsd配置

[root@Web02_a ~]# cat /tmp/nsdfile

/dev/sdb1:Web02_a::dataAndMetadata:01:

/dev/sdb2:Web02_a::dataAndMetadata:01:

/dev/sdb3:Web02_a::dataAndMetadata:01:

/dev/sdb5:Web02_a::dataAndMetadata:01:

/dev/sdb1:Nagios::dataAndMetadata:02:

/dev/sdb2:Nagios::dataAndMetadata:02:

/dev/sdb3:Nagios::dataAndMetadata:02:

#注:此时failgroup组1与组2磁盘数并不相同,但是磁盘不等是没关系的。两个组相当于raid1。

[root@Web02_a ~]# mmcrnsd -F /tmp/nsdfile-v no

#生成NSD文件

[root@Web02_a ~]# cat /tmp/nsdfile

# /dev/sdb1:Web02_a::dataAndMetadata:01: gpfs1nsd:::dataAndMetadata:01::system

# /dev/sdb2:Web02_a::dataAndMetadata:01: gpfs2nsd:::dataAndMetadata:01::system

# /dev/sdb3:Web02_a::dataAndMetadata:01: gpfs3nsd:::dataAndMetadata:01::system

# /dev/sdb5:Web02_a::dataAndMetadata:01: gpfs4nsd:::dataAndMetadata:01::system

# /dev/sdb1:Nagios::dataAndMetadata:02: gpfs5nsd:::dataAndMetadata:02::system

# /dev/sdb2:Nagios::dataAndMetadata:02: gpfs6nsd:::dataAndMetadata:02::system

# /dev/sdb3:Nagios::dataAndMetadata:02: gpfs7nsd:::dataAndMetadata:02::system

# /dev/sdb5:Nagios::dataAndMetadata:02: gpfs8nsd:::dataAndMetadata:02::system

11.配置仲裁盘

#仲裁盘作用,当定义的仲裁盘有一半的磁盘不可用时,该集群不可用。

另:有效磁盘数小于等于整个磁盘数一半时,整个文件系统不可用。

[root@Web02_a ~]# mmchconfig

tiebreakerDisks="gpfs1nsd;gpfs2nsd;gpfs3nsd"

Verifying GPFS is stopped on all nodes ...

mmchconfig: Command successfully completed

mmchconfig: Propagating the clusterconfiguration data to all

affected nodes. This is anasynchronous process.

[root@Web02_a tmp]# mmgetstate -a

[root@Web02_a tmp]# mmgetstate -a

Nodenumber Node name GPFS state

------------------------------------------

1 Web02_a active

2 Nagios active

如果mmgetstate -a状态为down,请确保:防火墙关闭,两台服务器时间同步(注意时区也要一致),/etc/hosts中没有对应127.0.0.1字段。

gpfs错误日志路径:/var/adm/ras/https://www.sodocs.net/doc/a014239729.html,test

#修改节点IP mmchnode --daemon-interface=10.0.0.236 -NWeb02_a

12.创建GPFS文件系统

[root@Web02_a tmp]# mmcrfs vol_data -F/tmp/nsdfile -B 256K -m 2 -r 2 -j cluster -T /vol_data -v no

The following disks of vol_data will beformatted on node Web02_a:

gpfs1nsd: size 104391 KB

gpfs2nsd: size 104422 KB

gpfs3nsd: size 104422 KB

gpfs4nsd: size 104391 KB

gpfs9nsd: size 104391 KB

gpfs10nsd: size 104422 KB

gpfs11nsd: size 104422 KB

gpfs12nsd: size 104391 KB

Formatting file system ...

Disks up to size 6.4 GB can be added tostorage pool 'system'. Creating Inode File

Creating Allocation Maps

Creating Log Files

Clearing Inode Allocation Map

Clearing Block Allocation Map

Formatting Allocation Map for storage pool'system'

Completed creation of file system/dev/vol_data.

mmcrfs: Propagating the clusterconfiguration data to all

affected nodes. This is anasynchronous process.

13.挂载文件系统:

[root@Web02_a ras]# mmmount /vol_data -a

Fri Jan 24 20:04:25 CST 2014: mmmount:Mounting file systems ...

[root@Web02_a ras]# df -hT

Filesystem Type Size Used Avail Use% Mounted on

/dev/sda3 ext3 19G 11G 7.0G 60% /

/dev/sda1 ext3 190M 12M 169M 7% /boot

tmpfs tmpfs 123M 0 123M 0% /dev/shm

/dev/vol_data gpfs 814M 333M 481M 41% /vol_data

[root@Nagios ras]# df -hT

Filesystem Type Size Used Avail Use% Mounted on

/dev/sda3 ext3 6.6G 3.5G 2.8G 56% /

/dev/sda1 ext3 190M 12M 169M 7% /boot

tmpfs tmpfs 249M 0 249M 0% /dev/shm

/dev/vol_data gpfs 814M 333M 481M 41% /vol_data

安装完成。

14.开机自启动

mmchconfig autoload=yes

或在/etc/rc.local中添加:/usr/lpp/mmfs/bin/mmstartup -a

15.可靠性测试

down掉Nagiogs服务器测试。看数据是否读取正常

[root@Web02_a ras]# cd /vol_data/

[root@Web02_a vol_data]# cp /etc/hosts .

[root@Web02_a vol_data]# ll

total 0

-rw-r--r-- 1 root root 375 Jan 26 09:25hosts

[root@Web02_a vol_data]# cat hosts

# Do not remove the following line, orvarious programs

# that require network functionality willfail.

127.0.0.1 localhost.localdomain localhostbogon ::1 localhost6.localdomain6 localhost6

10.0.0.236 Web02_a

10.0.0.243 Nagios

[root@Web02_a vol_data]# ssh Nagios

Last login: Sun Jan 26 09:08:28 2014 fromweb02_a

[root@Nagios ~]# /etc/init.d/networkstop #down掉Nagios服务器网卡

Shutting down interface eth0:

[root@Web02_a vol_data]# mmgetstate -a #查看状态已经有一个节点down 掉

Nodenumber Node name GPFS state

------------------------------------------

1 Web02_a active

2 Nagios unknown

[root@Web02_a vol_data]# cat/vol_data/hosts #还能正常读取,保证集群的高可用。

# Do not remove the following line, orvarious programs

# that require network functionality willfail.

127.0.0.1 localhost.localdomain localhostbogon ::1 localhost6.localdomain6 localhost6

10.0.0.236 Web02_a

10.0.0.243 Nagios

GPFS通用并行文件系统之Python自动部署GPFS集群

GPFS文件系统能够横跨在所有主机上,分布在所有磁盘上,条带化读写,高性能。信令管理机制,并发性好。可配置fail组,可用性高。下面是GPFS集群的自动安装部署python代码......

注:该脚本只能自动识别到系统盘之外的物理磁盘,不会识别到分区。

1、gpfs文件包目录结构

脚本中都按照这个目录结构进行安装

2、脚本执行方法

输入的是拥有存储磁盘的主机名。按回车完成

[root@vuestor01 scripts]# python auto.py

Input node's info. Usage:hosta/192.168.0.101. Press Enter is complete. Please input Node info: stor01/192.168.2.67

check ip address success!

Input node's info. Usage:hosta/192.168.0.101. Press Enter is complete. Please input Node info: stor02/192.168.2.85

执行成功后,自动挂载到/vol_data目录下。

[root@vuestor01 scripts]# df -hT

Filesystem Type Size Used Avail Use% Mounted on /dev/sda2 ext4 197G 1.6G 185G 1% /

tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm /dev/sda1 ext4 504M 46M 433M 10% /boot

/dev/vol_data gpfs 1.2T 918M 1.2T 1% /vol_data

[root@stor02 ~]# df -hT

Filesystem Type Size Used Avail Use% Mounted on /dev/sda2 ext4 197G 1.6G 185G 1% /

tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm /dev/sda1 ext4 504M 46M 433M 10% /boot

/dev/vol_data gpfs 1.2T 918M 1.2T 1% /vol_data 3、gpfs自动安装python代码分析

#!/usr/bin/python

import datetime

import os,sys,time

import commands

def output_log(): #定义输出log函数

time=datetime.datetime.now()

with open('loginfo.txt','wb') as f:

f.write('%s \n'%time)

def check_ip(ipaddr): #校验IP有效性函数

import sys

addr=ipaddr.strip().split('.')

#print addr

if len(addr) != 4:

print "check ip address failed!"

sys.exit()

for i in range(4):

try:

addr[i]=int(addr[i])

except:

sys.exit()

if addr[i]<=255 and addr[i]>=0:

pass

else:

print "check ip address failed!"

sys.exit()

i+=1

else:

print "check ip address success!"

def install_rpm():#定义安装gpfs相关软件包函数

print "Install rpm packages..."

os.system("rpm

-ivh ../dependency/nss-softokn-freebl*.rpm >>/loginfo.txt;\

rpm -ivh ../dependency/rsh*.rpm >>/root/loginfo.txt;\

rpm -ivh ../dependency/glibc*.rpm >>/root/loginfo.txt;\

rpm -ivh ../dependency/libgcc*.rpm >>/root/loginfo.txt;\

rpm -ivh ../dependency/ksh*.rpm >>/root/loginfo.txt;\

rpm

-ivh ../dependency/compat-libstdc++*.rpm >>/root/loginfo.txt;")

os.system("rpm -ivh ../base/gpfs.base*.rpm >>/root/loginfo.txt") os.system("rpm -ivh ../base/*noarch.rpm >>/root/loginfo.txt")

os.system("rpm -Uvh ../update/*.rpm >>/root/loginfo.txt")

#判断内核版本,安装相应版本的源码编译包

a,b=commands.getstatusoutput("uname -r|grep 220")

c,d=commands.getstatusoutput("uname -r|grep 358")

if (a == 0):

commands.getstatusoutput("rpm

-ivh ../rpm/gpfs.gplbin-2.6.32-220.el6.x86_64-3.4.0-21.x86_64.rpm") elif (c==0):

commands.getstatusoutput("rpm

-ivh ../rpm/gpfs.gplbin-2.6.32-358.el6.x86_64-3.4.0-21.x86_64.rpm") else:

print "can't support this kernel!"

sys.exit()

#判断是否安装成功

num_status,num_result=commands.getstatusoutput("rpm -qa |grep gpfs|wc -l")

if (num_result<5):

print "RPM packages check failed!"

sys.exit()

print "Done."

#获取节点信息,该处需用户输入

node_dict={}

host_all=[]

def get_nodes():

while True:

node=raw_input("""Input node's info. Usage: hosta/192.168.0.101. Press Enter is complete.

Please input Node info: """)

if len(node)==0:

return 2

node_result=node.strip().split('/')

#print node_result

#获得信息后判断IP,主机名合法性

if len(node_result[0])==0:

print "Hostname is failed!"

sys.exit()

check_ip(node_result[1])

#node_dict[node_result[0]]=[node_result[1]] host_all.append(node_result[0])

#print node_dict

local_ip_status,local_ip_result=commands.getstatuso utput("""ifconfig |grep 'inet addr'|awk -F '[: ]+' '{print $4}' """) local_ip=local_ip_result.split('\n')

#print host_all

#指定第一个输入的IP必须为本地IP

if len(host_all)==1:

if node_result[1] in local_ip:

pass

else:

print "The first IP must be native IP."

sys.exit()

#获得磁盘信息

avail_disk={}

def get_disks():

import os,commands

print "Getting avail disks... ... list as fllow:"

#循环主机列表

for host in host_all:

#把对方的分区信息,系统盘信息输出文件并拷贝到本机

os.system("""ssh %s " cat

/proc/partitions >/tmp/part_%s;scp /tmp/part_%s %s:/root/"

"""%(host,host,host,host_all[0]))

os.system("""ssh %s " df -h >/tmp/osdisk_%s;scp /tmp/osdisk_%s %s:/root/" """%(host,host,host,host_all[0]))

disk_status,disk_result=commands.getstatusout put("cat /root/part_%s |awk '{print $4}'|grep -v name \

|grep -v [0-9]|grep -v ^$"%host)

disk_a=disk_result.split('\n')

#从所有磁盘列表中移除系统盘

os_status,os_result=commands.getstatusoutput( "cat /root/osdisk_%s |grep '/$'|awk '{print $1}' \

|awk -F '/' '{print $3}'|awk -F [0-9] '{print $1}'"%host)

#print '111',disk_a,'1111'

disk_a.remove(os_result)

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_mycall 5.重新编译内核 在终端输入命令,进入源代码文件夹,cd /usr/src/linux-2.6.22.5 依次执行如下命令:make mrproper make clean make xconfig (自己配置内核,出现图形对话框后,直接点保存,关闭) make (耗时最长,大约20分钟) make modules_install (安装模块) 以上命令执行完毕后,会在当前目录下生成一个名为System.map的文件,会在/usr/src/linux-版本号/arch/i386/boot/下生成一个bzImage文件。

添加系统调用实验报告

一、构建基本的实验环境 1.1基本实验环境与前提条件 Windows7 、Word 2010、Vmware WorkStation 8.5、AdobeReader ReadHatLinux 9.0,gcc,vi Linux内核[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.gz 2.1.2、解压后如下

2.1.3、拷贝linux,命名为linux-2.4.18 cp -r linux linux-2.4.18 2.1.4、移动config-2.4.18forMP.txt到linux-2.4.18根目录,替换掉.config 2.1.5、进入linux-2.4.18目录,配置和编译内核模块 make oldconfig make dep

linux添加系统调用实验步骤

首先,进入到内核源码目录/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 #include

Linux内核中增加一个系统调用

选题要求:在Linux内核中增加一个系统调用,并编写对应的linux应用程序。利用该系统调用能够遍历系统当前所有进程的任务描述符,并按进程父子关系将这些描述符所对应的进程id(PID)组织成树形结构显示。

目录 一.程序的主要设计思路,实现方式 (1) 1.1 添加系统调用的两种方法 (1) 1.1.1编译内核法 (1) 1.1.2内核模块法 (1) 1.2 程序的主要设计思路 (1) 1.3 环境 (2) 二.程序的模块划分,及对每个模块的说明 (2) 2.1 通过内核模块实现添加系统调用 (2) 2.1.1修改系统调用的模块 (2) 2.1.2获取sys_call_table的地址 (2) 2.1.3清除内存区域的写保护 (3) 2.2 编写系统调用指定自己的系统调用 (4) 2.2.1内核的初始化函数 (4) 2.2.2自己的系统调用服务例程 (4) 2.2.3移除内核模块时,将原有的系统调用进行还原 (6) 2.2.4模块注册相关 (6) 2.3 编写用户态的测试程序 (6) 2.4 编写Makefile文件 (7) 三.所遇到的问题及解决的方法 (8) 3.1 进程个数确定 (8) 3.2 被更改的系统调用号的选择 (8) 3.3 获取系统调用表的地址 (8) 3.4 内核和用户态数据交换 (8) 四.程序运行结果及使用说明 (8) 4.1 将编译出来的内核模块hello.ko加载到内核中 (8)

4.2通过dmesg查看输出信息是否正确 (9) 4.3运行测试程序,输出树状打印结果(部分结果截图) (9) 4.4卸载自定义模块 (10) 五.附录 (11) 5.1 内核模块程序hello.c (11) 5.2 测试程序hello_test.c (14) 5.3Makefile文件 (14)

Linux系统调用详解之pdbedit

Name pdbedit ? manage the SAM database (Database of Samba Users) Synopsis pdbedit [?a] [?b passdb?backend] [?c account?control] [?C value] [?d debuglevel] [?D drive] [?e passdb?backend] [?f fullname] [??force?initialized?passwords] [?g] [?h homedir] [?i passdb?backend] [?I domain] [?K] [?L] [?m] [?M SID|RID] [?N description] [?P account?policy] [?p profile] [??policies?reset] [?r] [?s configfile] [?S script] [?t] [??time?format] [?u username] [?U SID|RID] [?v] [?V] [?w] [?x] [?y] [?z] [?Z] DESCRIPTION This tool is part of the samba(7) suite. The pdbedit program is used to manage the users accounts stored in the sam database and can only be run by root. The pdbedit tool uses the passdb modular interface and is independent from the kind of users database used (currently there are smbpasswd, ldap, nis+ and tdb based and more can be added without changing the tool). There are five main ways to use pdbedit: adding a user account, removing a user account, modifing a user account, listing user accounts, importing users accounts. OPTIONS ?L|??list This option lists all the user accounts present in the users database. This option prints a list of user/uid pairs separated by the ′:′ character. Example: pdbedit ?L sorce:500:Simo Sorce samba:45:Test User ?v|??verbose This option enables the verbose listing format. It causes pdbedit to list the users in the database, printing out the account fields in a descriptive format. Example: pdbedit ?L ?v

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

操作系统实验报告 ----- Linux下的系统调用 计算机10-4 赵俊楠10081407 实验目的:实现多个系统调用实验 实验内容:添加简单系统调用、添加随机抽牌系统调、用模块添加系统调用 实验步骤: (我是将三个系统调用添加完毕后一起编译的) 1.在usr/src/linux- 2.4/include/asm i386/unistd.h中添加#define __NR_print_info 259和#define __NR_rank 260 2.在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 clean make mrproper make oldconfig make dep make bzImage make modules make modules_install make install 在添加系统调用时候一定要专心、仔细,否则在编译的时候会出现错误,改起来很麻烦!! 6.重启Linux后,显示界面如下(没有改内核版本号)

Linux 系统调用实现机制实验报告-内核安装详解

Linux系统调用实现机制实验报告 实验目的: 熟悉Linux系统调用过程,掌握系统调用的基本原理并在实验中实现系统调用的添加。 实验所需软件: 实验平台:VMware WorkStation; 系统环境:Red Hat Linux9.0; 传输工具:Ftp server(Serv USetup); 实验过程: 一、实验环境的搭建 (一)在Window下安装虚拟机VMware WorkStation; (二)在虚拟机上安装Red Hat 9.0系统; (三)在Window下安装Ftp Server,实现Linux与windows文件共享。 1. Ftp服务器的配置 打开Ftp Server,在[管理控制台]中选择[新建域],系统会弹出配置域向导的对话框,这里按要求填入相应信息,即可配置成功一个ftp服务器。步骤1要求用户填入域的[名称]和[说明],[名称]必须填写,[说明]可以不填。例如:在名称中输入[Linux实验],选择[下一步],便进入到域向导的步骤2。 步骤2是服务器访问协议和端口的配置,默认即可,点击[下一步]进入步骤3。步骤3是IP地址的配置,输入Windows主机的IP地址(202.112.147.176)。 确认无误后,点击[完成]。接下来要做的就是为域添加用户,根据添加用户向导,逐个填写[用户名],[密码],[根目录(即共享的文件目录)]以及[访问权限]。本次实验的配置为:tml(用户名),密码为空,E:\安全操作系统\实验材料(存放config-2.4.18forMP.txt和linux-2.4.18.tar.gz的目录),完全访问(访问权限)。到此,服务器的配置已经完成。 2. 在Linux下访问服务器,并下载文件

Exam02_实验2 添加系统调用

添加系统调用 实验目的 学习Linux内核的系统调用,理解、掌握Linux系统调用的实现框架、用户界面、参数传递、进入/返回过程。 实验内容 本实验分两步走。 第一步,在系统中添加一个不用传递参数的系统调用;执行这个系统调用,使用户的uid等于0。显然,这不是一个有实际意义的系统调用。我们的目的并不是实用不实用,而是通过最简单的例子,帮助熟悉对系统调用的添加过程,为下面我们添加更加复杂的系统调用打好基础。 第二步,用kernel module机制,实现系统调用gettimeofday的简化版,返回调用时刻的日期和时间。 实验指导 2.1一个简单的例子 在我们开始学习系统调用这一章之前,让我们先来看一个简单的例子。就好像哪个经典的编程书上都会使用到的例子一样: 1: int main(){ 2: printf(“Hello World!\n”); 3: } 我们也准备了一个例子给你: 1: #include /* all system calls need this header */ 2: int main(){ 3: int i = getuid(); 4: printf(“Hello World! This is my uid: %d\n”, i); 5: } 这就是一个最简单的系统调用的例子。与上面那个传统的例子相比,在这个例子中多了

2行,他们的作用分别是: 第一行:包括unistd.h这个头文件。所有用到系统调用的程序都需要包括它,因为系统调用中需要的参数(例如,本例中的“__NR_getuid”,以及_syscall0()函数)包括在unistd.h中;根据C语言的规定,include 意味着/usr/include/linux目录下整个unistd.h都属于Hello World源程序了。 第三行:进行getuid()系统调用,并将返回值赋给变量i。 好了,这就是最简单的一个使用了系统调用的程序,现在你可以在你的机器上试一试它。然后我们一起进入到系统调用的神秘世界中去。 2.2 简单系统调用的添加 在这一节中,我们将要实现一个简单的系统调用的添加。我们先给出题目: 题目:在现有的系统中添加一个不用传递参数的系统调用。 功能要求:调用这个系统调用,使用户的uid等于0。 目的:显然,这不是一个有实际意义的系统调用,我们的目的并不是有用,而是一种证明,一个对系统调用的添加过程的熟悉,为下面我们添加更加复杂 的系统调用打好基础。 怎么样?觉得困难还是觉得太简单?我们首先承认,每个人接触Linux的时间长短不一样,因此基础也会有一点差别。那么对于觉得太简单的人呢,请你迅速地合上书本,然后跑到电脑前面,开始实现这个题目。来吧,不要眼高手低,做完之后,你就可以跳过这一节,直接进入下一节的学习了。对于觉得有点困难的人呢,不用着急,这一节就是专门为你准备的。我们会列出详细的实现步骤,你一定也没有问题的。 如果你前面对整个系统调用的过程有一个清晰的理解的话,我们就顺着系统调用的流程思路,给出一个添加新的系统调用的步骤: 2.2.1决定你的系统调用的名字 这个名字就是你编写用户程序想使用的名字,比如我们取一个简单的名字:mysyscall。一旦这个名字确定下来了,那么在系统调用中的几个相关名字也就确定下来了。 ●系统调用的编号名字:__NR_mysyscall; ●内核中系统调用的实现程序的名字:sys_mysyscall; 现在在你的用户程序中出现了: #include int main() { mysyscall(); } 流程转到标准C库。 2.2.2利用标准C库进行包装吗 编译器怎么知道这个mysyscall是怎么来的呢?在前面我们分析的时候,我们知道那时标准C库给系统调用作了一层包装,给所有的系统调用做出了定义。但是显然,我们可能

8第八章Linux下的系统调用

第八章 Linux下的系统调用 8.1 系统调用介绍 8.1.1 引言 系统调用是内核提供的、功能十分强大的一系列函数。它们在内核中实现,然后通过一定的方式(库、陷入等)呈现给用户,是用户程序与内核交互的一个接口。如果没有系统调用,则不可能编写出十分强大的用户程序,因为失去了内核的支持。由此可见系统调用的地位举足轻重。内核的主体可以归结为: 系统调用的集合; 实现系统调用的算法。 8.1.2 系统调用的实现流程 这里我们通过getuid()这个简单的系统调用来分析一下系统调用的实现流程。在分析这个程序时并不考虑它的底层是如何实现的,而只需知道每一步执行的功能。 首先来看一个例子: #include /* all system call need this header*/ int main() { int i=getuid(); printf(“Hello World! This is my uid: %d\n”,i); } #include是每个系统调用都必须要的头文件,当系统执行到getuid()时,根据unistd.h中的宏定义把getuid()展开。展开后程序把系统调用号__NR_getuid(24)放入eax,然后通过执行“int $0x80”这条指令进行模式切换,进入内核。int 0x80指令由于是一条软中断指令,所以就要看系统规定的这条中断指令的处理程序是什么。 arch/i386/kernel/traps.c set_system_gate(SYSCALL_VECTOR,&system_call); 从这行程序我们可以看出,系统规定的系统调用的处理程序就是system_call。控制转移到内核之前,硬件会自动进行模式和堆栈的切换。现在控制转移到了system_call,保留系统调用号的最初拷贝之后,由SAVE_ALL来保存上下文,得到该进程结构的指针,放在ebx里面,然后检查系统调用号,如果__NR_getuid(24)是合法的,则根据这个系统调用号,索引sys_call_table,得到相应的内核处理程序:sys_getuid。执行完sys_getuid之后,保存返回值,从eax移到堆栈中的eax处,假设没有

linux系统调用

2002 年 3 月 01 日 本文列出了大部分常见的Linux系统调用,并附有简要中文说明。 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的。 按照惯例,这个列表以man pages第2节,即系统调用节为蓝本。按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释。 其中有一些函数的作用完全相同,只是参数不同。(可能很多熟悉C++朋友马上就能联想起函数重载,但是别忘了Linux核心是用C语言写的,所以只能取成不同的函数名)。还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数我会在前面标上“*”号以示区别。 一、进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtablesize 进程所能打开的最大文件数 getpgid 获取指定进程组标识号 setpgid 设置指定进程组标志号 getpgrp 获取当前进程组标识号 setpgrp 设置当前进程组标志号 getpid 获取进程标识号 getppid 获取父进程标识号 getpriority 获取调度优先级 setpriority 设置调度优先级 modify_ldt 读写进程的本地描述表 nanosleep 使进程睡眠指定的时间 nice 改变分时进程的优先级 pause 挂起进程,等待信号 personality 设置进程运行域 prctl 对进程进行特定操作 ptrace 进程跟踪 sched_get_priority 取得静态优先级的上限 _max sched_get_priority 取得静态优先级的下限 _min sched_getparam 取得进程的调度参数 sched_getscheduler 取得指定进程的调度策略 sched_rr_get_inter 取得按RR算法调度的实时进程的时间片长度 val sched_setparam 设置进程的调度参数 sched_setscheduler 设置指定进程的调度策略和参数

linux0.11系统调用原理及实验总结

Linux0.11系统调用原理及实验总结 1系统调用的原理 1.1概述 系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int 0x80,就可使用内核资源。不过,通常应用程序都是使用具有标准接口定义的C函数库间接的使用内核的系统调用,即应用程序调用C函数库中的函数,C函数库中再通过int 0x80进行系统调用。 所以,系统调用过程是这样的: 应用程序调用libc中的函数->libc中的函数引用系统调用宏->系统调用宏中使用int 0x80完成系统调用并返回。 另外一种访问内核的方式是直接添加一个系统调用,供自己的应用程序使用,这样就不再使用库函数了,变得更为直接,效率也会更高。 1.2相关的数据结构 在说具体的调用过程之前,这里先要说几个数据结构。 1.2.1 系统调用函数表 系统调用函数表sys_call_table是在sys.h中定义的,它是一个函数指针数组,每个元素是一个函数指针,它的值是各个系统提供的供上层调用的系统函数的入口地址。也就是说通过查询这个表就可以调用软中断0x80所有的系统函数处理函数。 1.2.2 函数指针偏移宏 这是一系列宏,它们的定义在unistd.h中,基本形式为#define _NR_name value,name为系统函数名字,value是一个整数值,是name所对应的系统函数指针在sys_call_table中的偏移量。 1.2.3 系统调用宏 系统调用宏_syscalln(type,name)在内核的unistd.h文件中定义的,对它展开就是: type name(参数列表) { 调用过程; }; 其中,n为参数个数,type为函数返回值类型,name为所要调用的系统函数的名字。在unistd.h 中共定义了4个这样的宏(n从0到3),也就是说,0.11核中系统调用最多可带3个参数。

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

二.掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。另编写一个应用程序,调用新增加的系统调用。 (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 239 3.修改文件 /usr/src/linux-2. 4.18-3/arch/i386/kernel/entry.S文件 在文件中相应位置加上: .long SYMBOL_NAME(sys_mycopy) 编译内核:(过程中要先后使用的命令如下,其中后两步操作为非必要,若不执行,则新内核下某些系统功能将无法实现) make mrproper make oldconfig make dep make clean make bzImage make modules make modules_install maek 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-new ln –sf /boot/System.map-new /boot/System.map 然后进入 /etc/lilo.conf(本机采用Lilo配置),添加如下代码: image=/boot/bzImage-new label=linux-new root=/dev/hda1 /* hda1为安装linux的分区 */ 然后进入 /sbin,运行lilo,完成配置。 重启系统后选择标签为linux-new的新内核进入。 在新内核下测试系统调用,其运行结果如下: [YAKUZA$root] ls copy.c test.c [YAKUZA$root] gcc mycopy_test.c –o mycopy_test [YAKUZA$root] ls mycopy_test mycopy_test.c test.c [YAKUZA$root] cat test.c #include main()

操作系统原理-实验-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(),这样就在数组中添加了新的内核函数指针。

Linux文件系统调用

Linux文件系统调用 一、实验目的: (1)掌握Linux提供的文件系统调用的使用方法。 (2)熟悉文件系统的系统调用用户接口。 (3)了解操作系统文件系统的工作原理和工作方式。 二、实验内容 编写一个文件工具filetools,使其具有以下功能: 0.退出 1.创建新文件 2.写文件 3.读文件 4.修改文件权限 5.查看当前文件权限并退出。 提示用户输入功能号,并根据用户输入的功能选择相应的功能。三、参考代码 #include #include #include #include #include #include #include #include #define MAX 128 int chmd() { int c; mode_t mode=S_IWUSR; printf("0.0700\n 1.0400\n 2.0200\n 3.0100\n");//还可以增加其他权限printf("Please input your choice(0-3):"); scanf("%d",&c); switch(c) { case 0:chmod("file1",S_IRWXU);break; case 1:chmod("file1",S_IRUSR);break; case 2:chmod("file1",S_IWUSR);break; case 3:chmod("file1",S_IXUSR);break; default:printf("You have a wrong choice!\n"); } return(0); }

为arm linux 2.6.24 添加系统调用

为arm linux 2.6.24 添加系统调用 # gedit arch/arm/kernel/sys_arm.c ----------------------------------------------------------- asmlinkage long sys_arm_fadvise64_64(int fd, int advice, loff_t offset, loff_t len) { return sys_fadvise64_64(fd, offset, len, advice); } asmlinkage int sys_kmd(unsigned int p_addr) { printk("p_addr = 0x%x\n", p_addr); return p_addr; } # gedit include/asm-arm/unistd.h ----------------------------------------------------------- #define __NR_fallocate (__NR_SYSCALL_BASE+352) #define __NR_kmd (__NR_SYSCALL_BASE+353) # gedit arch/arm/kernel/calls.S ----------------------------------------------------------- CALL(sys_fallocate) CALL(sys_kmd) 测试提供调用 ----------------------------------------------------------- #define _GNU_SOURCE /* or _BSD_SOURCE or _SVID_SOURCE */ #include #include /* For SYS_xxx definitions */ #define __NR_kmd (__NR_SYSCALL_BASE+353) int kmd (unsigned int p_addr) { syscall (__NR_kmd, p_addr); return 0; }

实验一新增系统调用

操作系统实验一: 向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. 编写应用程序以测试新的系统调用并输出测试结果

操作系统- linux系统调用

实 验 报 告 一、理论分析(分值:20%) 【从操作系统原理(理论)的角度阐述系统功能调用的过程】 1、函数声明中都有asmlinkage限定词,用于通知编译器仅从栈中提取该函数的参数。 2、系统调用getXXX()在内核中被定义为sys_getXXX()。系统调用号:在linux中,每个系统调用都赋予一个系统调用号,通过这个独一无二的号就可以关联系统调用。当用户空间的

进程执行一个系统调用的时候,这个系统调用号就被用来指明到底要执行哪个系统调用;进程不会提及系统调用的名称。系统调用号一旦分配就不能再有任何变更(否则编译好的应用程序就会崩溃),如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用。Linux有一个"未使用"系统调用sys_ni_syscall(),它除了返回-ENOSYS外不做任何其他工作,这个错误号就是专门针对无效的系统调用而设的。内核记录了系统调用表中所有已注册过的系统调用的列表,存储在sys_call_table中。它与体系结构有关,一般在entry.s中定义。这个表中为每一个有效的系统调用指定了唯一的系统调用号。 3、Makefile控制着整个内核的编译,在每个子目录下调用编译.c 文件,生成.o文件,生成新的内核。会把新编译的sys_hello内核加入到系统调用中。系统调用表gedit syscall_32.tbl 中加入354 i386 hello sys_hello,当系统调用时可以在调用表中找到系统调用的号。 4、在syscalls.h中添加定义的内容的引用函数。 5、编译执行结果。 二、设计与实现(分值:30%) 【阐述在Linux中添加系统功能调用的方法】 1、在内核目录下创建hello文件夹 mkdir hello 2、进入hello文件夹 cd hello 3、创建hello.c的文件 vim hello.c 4、加入代码 #include asmlinkage long sys_hello(void) { printk(“Hello world\n”); return 0; } 5、在hello文件夹下添加Makefile文件 vim Makefile

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

操作系统实验一: 向Linux内核增加一个系统调用 xx711103xx 2012年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.c asmlinkage int sys_mycall(int number) { printk("hello,my new kernel,xw~!"); return number; }

学会Linux添加自定义系统调用

学会Linux添加自定义系统调用 一、什么是系统调用 在Linux的世界里,我们经常会遇到系统调用这一术语,所谓系统调用,就是内核提供的、功能十分强大的一系列的函数。这些系统调用是在内核中实现的,再通过一定的方式把系统调用给用户,一般都通过门(gate)陷入(trap)实现。系统调用就是用户空间应用程序和内核提供的服务之间的一个接口。由于服务是在内核中提供的,因此无法执行直接调用;相反,您必须使用一个进程来跨越用户空间与内核之间的界限。在特定架构中实现此功能的方法会有所不同。因此,本文将着眼于最通用的架构—— i386。 二、系统调用的作用 系统调用在Linux系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了内核的支持。我们在编程时用到的很多函数,如fork、open等这些函数最终都是在系统调用里实现的,这里我们说到了两个函数,即fork和exit,这两函数都是glibc中的函数,但是如果我们跟踪函数的执行过程,看看glibc对fork和exit函数的实现就可以发现在glibc 的实现代码里都是采用软中断的方式陷入到内核中再通过系统调用实现函数的功能的。具体过程我们在系统调用的实现过程会详细的讲到。 由此可见,系统调用是用户接口在内核中的实现,如果没有系统调用,用户就不能利用内核。 三、系统调用的现实及调用过程 详细讲述系统调用的之前也讲一下Linux系统的一些保护机制。 Linux系统在CPU的保护模式下提供了四个特权级别,目前内核都只用到了其中的两个特权级别,分别为“特权级0”和“特权级3”,级别0也就是我们通常所讲的内核模式,级别3也就是我们通常所讲的用户模式。划分这两个级别主要是对系统提供保护。内核模式可以执行一些特权指令和进入用户模式,而用户模式则不能。 这里特别提出的是,内核模式与用户模式分别使用自己的堆栈,当发生模式切换的时候同时要进行堆栈的切换。每个进程都有自己的地址空间(也称为进程空间),进程的地址空

相关主题