给linux增加系统调用
(原创作品 转载请务必注明出处!)
在Bochs模拟器下给0.12内核的linux增加一个系统调用 sethostname2(char* hostname, int len),以实现:给系统设置主机名称并在屏幕上打印 "this system call is created by chriswang"这样的功能。
a. 修改内核代码
修改 kernel/sys.c 增加系统调用的实现 。
在 sys.c里的sethostname 函数后面添加sethostname2,我们把sethostname 函数直接复制下来,然后再修改成我们要实现的sethostname2。
命令在sethostname函数头输入:17yy,然后移动光标到函数末尾,输入命令:p
int sys_sethostname2(char *name, int len)
{
int i;
if (!suser())
return -EPERM;
if (len > MAXHOSTNAMELEN)
return -EINVAL;
for (i=0; i < len; i++)
{
if ((thisname.nodename[len – i - 1] = get_fs_byte(name+i)) == 0)
break;
}
if (thisname.nodename[i]) {
thisname.nodename[i>MAXHOSTNAMELEN ? MAXHOSTNAMELEN : i] = 0;
}
printk(“this system call is created by chriswang/n”);
return 0;
}
b. 添加系统调用功能号和原型定义
在include/unistd.h文件中添加
//新系统调用功能号
#define _NR_sethostname2 87
//新系统调用函数原型
int sethostname2(char *name, int len);
c. 添加外部函数声明
在include/linux/sys.h文件中添加
extern int sys_sethostname2();
//函数指针数组表
fn_ptr sys_call_table[] = { sys_setup, ..(省略)..
sys_lstat, sys_readlink, sys_uselib, sys_sethostname2
};
d. 修改系统调用汇编程序
修改kernel/sys_call.s程序第63行,将内核系统调用总数 nr_system_calls增1,就是将 82 改成 83
e. 增加新系统调用库函数
在 /usr/src/linux/lib 目录中新建一个文件 sethostname2.c,内容如下
#define __LIBRARY__
#include <unistd.h>_syscall2(int,sethostname2,char *,hostname,int,len);
修改 lib/Makefile 蓝色部分为增加的地方
OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o
execve.o wait.o string.o malloc.o sethostname2.o
f. 编译内核代码
make clean
make
dd if=/usr/src/linux/Image of=/dev/fd0 bs=1024
然后再重启下linux重新加载内核。
g. 调整 glibc
cp /usr/src/linux/include/unistd.h /usr/include/
ar -r /usr/lib/gcc-lib/i386-linux/2.2.2d/libc.a /usr/src/linux/lib/sethostname2.o
h. 用汇编验证
新建一个 asm.s,内容如下文本框,编译和运行用下面的命令
.text
_entry:
movl $87, %eax
movl $hostname, %ebx
movl $5, %ecx
int $0x80
movl $1, %eax
int $0x80
hostname:
.ascii "abcde"
先看看当前的主机名称
Hostname
编译代码:
as -o asm.o asm.s
ld -o asm asm.o
// 运行程序
./asm
// 再看看现在的主机名称
Hostname
i. 用 C 语言验证
新建一个 C 文件 sethostname2.c
#include <unistd.h>
int main(void)
{
sethostname2("abcde", 5);
}
// 用gcc 编译,要指定是 /usr/bin 目录中的 gcc
/usr/bin/gcc sethostname2.c -o sethostname2
// 运行
./sethostname2