lwgg太棒了!
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。最终的运行结果是:
$ ./iam lizhijun
$ ./whoami
lizhijun
copy
按照格式添加
(1)按照格式,增加iam和whoami,并编号为72和73,这里的编号即为第2步提及的%eax
#define __NR_iam 72
#define __NR_whoami 73
copy
链接描述
(2) 头文件末尾的地方增加函数声明,原型即为
int iam(const char * name);
int whoami(char* name, unsigned int size);
copy
_syscall1(int, iam, const char*, name)
_syscall2(int, whoami,char*,name,unsigned int,size)
copy
###修改 修改 /include/linux/sys.h
添加
extern int sys_iam();
extern int sys_whoami();
copy
在sys_call_table[]中添加
sys_iam,sys_whoami
copy
###修改/kernel/system_call.s
把nr_system_call的值从72改成74
###修改/kernel/Makefile
(1)第一处
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
copy
改为
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
copy
就是在末尾添加who.o (2)第二处
### Dependencies:
exit.s exit.o: exit.c ../include/errno.h ../include/signal.h \
../include/sys/types.h ../include/sys/wait.h ../include/linux/sched.h \
../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \
../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \
../include/asm/segment.h
copy
在段首添加
who.s who.o: who.c ../include/linux/kernel.h ../include/unistd.h
copy
#define __LIBRARY__
#include <asm/segment.h>
#include <errno.h>
#include <unistd.h>
#include<linux/kernel.h>
char username[64] = {0};
int sys_iam(char *name)
{
int i;
for(i=0; get_fs_byte(name+i)!='\0'; i++);
if(i>23)
return -EINVAL;
for(i=0; (username[i]=get_fs_byte(name+i))!='\0'; i++);
return i;
}
int sys_whoami(char *name, unsigned int size)
{
int i;
for(i=0; username[i] != '\0'; i++);
if(i>size)
return -EINVAL;
for(i=0; username[i] != '\0'; i++)
put_fs_byte(username[i], name+i);
return i;
}
copy
cp /home/teacher/testlab2.c .
cp /home/teacher/testlab2.sh .
chmod +x testlab2.sh
copy
#define __LIBRARY__
#include <unistd.h>
_syscall1(int,iam,const char *,name)
int main(int argc, char *argv[])
{
if(argc<=1)
return -1;
if(iam(argv[1])==-1)
return -1;
return 0;
}
copy
#define __LIBRARY__
#include <unistd.h>
#include <stdio.h>
_syscall2(int,whoami,char *,name,unsigned int,size)
int main(int argc, char *argv[])
{
char name[1024];
if(whoami(name, 23)==-1)
return -1;
printf("%s\n", name);
return 0;
}
copy
cp /home/teacher/testlab2.c .
cp /home/teacher/testlab2.sh .
chmod +x testlab2.sh
copy
cd ~/oslab
sudo umount hdc
copy
cd linux-0.11
make
../run
copy
从 Linux 0.11 现在的机制看,它的系统调用最多能传递几个参数?你能想出办法来扩大这个限制吗?
无序列表
无序列表
无序列表
有序列表
有序列表
有序列表
最多能传递3个参数,将需要传递的多个参数保存在特定结构的区间中,变成该用户态地址空间的这个区间的首地址作为一个参数传递给系统调用。
用文字简要描述向 Linux 0.11 添加一个系统调用 foo() 的步骤。
学习时间 632分钟
操作时间 130分钟
按键次数 3503次
实验次数 35次
报告字数 4636字
是否完成 完成