《冬夜读书示子聿》
(南宋)陆游
古人学问无遗力,少壮工夫老始成。
纸上得来终觉浅,绝知此事要躬行。
1:实验目的
建立对系统调用接口的深入认识;
掌握系统调用的基本过程;
能完成系统调用的全面控制;
2:实验内容
在 Linux 0.11 上添加两个系统调用,并编写两个简单的应用程序测试它们。
(1)iam()
第一个系统调用是 iam(),其原型为:
int iam(const char * name);
copy
完成的功能是将字符串参数 name 的内容拷贝到内核中保存下来。要求 name 的长度不能超过 23 个字符。返回值是拷贝的字符数。如果 name 的字符个数超过了 23,则返回 “-1”,并置 errno 为 EINVAL。
在 kernal/who.c 中实现此系统调用。
(2)whoami()
第二个系统调用是 whoami(),其原型为:
int whoami(char* name, unsigned int size);
copy
它将内核中由 iam() 保存的名字拷贝到 name 指向的用户地址空间中,同时确保不会对 name 越界访存(name 的大小由 size 说明)。返回值是拷贝的字符数。如果 size 小于需要的空间,则返回“-1”,并置 errno 为 EINVAL。
也是在 kernal/who.c 中实现。
(3)测试程序
运行添加过新系统调用的 Linux 0.11,在其环境下编写两个测试程序 iam.c 和 whoami.c。
3:实验步骤:
1:用户代码
1)测试程序
ami.c
#define __LIBRARY__
#include<stdio.h>
#include<unistd.h>
_syscall1(int,iam,const char *,name)
int main(int argc, char *argv[])
{
if(argc != 2)
printf("argc != 2\n");
if(iam(argv[1]))
printf("iam error!\n");
return 0;
}
whoiam.c
#define __LIBRARY__
#include<stdio.h>
#include<unistd.h>
_syscall2(int,whoami,char*,name,unsigned int,size);
int main(void)
{
char buf[128];
whoami(buf,128);
printf("%s\n",buf);
return 0;
}
2:内核代码
1)添加__syscall中需要传入的__NR_XX
hdc/usr/include/unistd.h
#define __NR_iam 72
#define __NR_whoami 73
注意:
由于unistd.h不能直接修改,我们要把虚拟硬盘挂载在oslab/hdc目录下,在终端输入命令:
然后进入hdc/usr/include目录,打开unistd.h
2)进入int 0x80中断,判断传入__NR_xxx的大小是否符合
nr_system_calls = 74
system_call:
cmpl $nr_system_calls-1,%eax
3)进入sys_call_table,在函数指针数组中添加相应的函数指针
call sys_call_table(,%eax,4)---->
extern int sys_iam();
extern int sys_whoami();
fn_ptr sys_call_table[] = { sys_setup,.............,sys_iam,sys_whoami};
4)实现sys_iam,sys_whoami
#include<string.h>
#include<asm/segment.h>
char name[128];
int sys_iam(const char *buf)
{
int i;
for(i = 0; i < 128; i++){
name[i] = get_fs_byte(buf+i);
if(name[i] == '\0')
break;
}
printk("%s\n",name);
return 0;
}
int sys_whoami(char *buf, int size)
{
int i;
for(i = 0; i < size; i++)
{
put_fs_byte(name[i],buf+i);
if(name[i] == '\0')
break;
}
return 0;
}
5)添加到Makefile中编译进kernel
OBJS = sched.o system_call.o traps.o asm.o fork.o \
panic.o printk.o vsprintf.o sys.o exit.o \
signal.o mktime.o who.o
### Dependencies:
who.s who.o:who.c ../include/asm/segment.h ../include/string.h