(原創作品 轉載請務必注明出處!)
在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