我想在 Pintos 中实现已经定义的系统调用(在 pintos/src/lib/user/syscall.c 中定义的 halt()、create()...etc )。pintos/src/userprog/syscall.c 中的当前系统调用处理程序不执行任何操作。如何创建进行系统调用的进程。此外,我需要自己添加一些系统调用。我该如何继续。但首先我需要实现现有的系统调用。
1 回答
pintos 中的默认实现终止调用进程。
转到此链接。有关于在何处修改代码以实现系统调用的说明。
“src/examples”目录包含一些示例用户程序。
此目录中的“Makefile”编译提供的示例,您也可以编辑它编译您自己的程序。
该程序/进程在运行时将依次进行系统调用。
使用 gdb 跟踪一个这样的程序的执行,一个简单的 printf 语句最终将调用写入系统调用到 STDOUT 文件。
给出的链接还包含有关如何在 gdb 上运行 pintos 的指示,我猜您使用的是 bochs 或 qemu。无论如何,只需使用在 pintos 上运行的简单 hello world 程序运行 gdb 一次。
这将使您了解如何进行系统调用。
static void
syscall_handler (struct intr_frame *f)// UNUSED)
{
int *p=f->esp;
switch(*p)
case *p=SYS_CREATE // NUMBER # DEFINED
const char *name=*(p+1); //extract the filename
if(name==NULL||*name==NULL)
exit(-1);
off_t size=(int32_t)*(p+2);//extract file size
f->eax=filesys_create(name,size,_FILE); //call filesys_create
//eax will have the return value
}
这是 sys_create 的伪代码。所有与文件系统相关的系统调用都非常简单,Filesys realted 系统调用如 open read write close 需要您将文件转换为相应的 fd(文件描述符)。您需要为每个进程添加一个文件表来跟踪这一点,这可以是预处理数据或全局数据。(UR 选择),
case (*p==SYS_WRITE)
{
// printf("wite syscall\n");
char *buffer=*(p+2);
unsigned size=*(p+3);
int fd=*(p+1);
// getiing the fd of specified file
struct file *fil= thread_current()->fdtable[fd];/ my per thread fdtable
if(fd==1) goto here;
if(is_directory(fil->inode)){
exit(-1);
goto done;
}
here:
if(buffer>=PHYS_BASE)exit(-1);
if(fd<0||fd>=128){exit(-1);}
if(fd==0){exit(-1);} // writing to STDIN
if(fd==1) //writing to STDOUT
{
int a=(int)size;
while(a>=100)
{
putbuf(buffer,100);
buffer=buffer+100;
a-=100;
}
putbuf(buffer,a);
f->eax=(int)size;
}
else
if(thread_current()->fdtable[fd]==NULL)
{f->eax=-1;}
else
{
f->eax=file_write(thread_current()->fdtable[fd],buffer,(off_t)size);
}
done: ;
}//printf("write");} /* Write to a file. */
打开 - 将新条目添加到 fdtable 并返回您给文件的 fd 编号,
关闭 - 从 fd 表中删除该条目
读取 - 类似于写入。
process_create ,wait 实现起来并不简单......
干杯:)