参考了大佬的实验报告博客

之前一直实在Windows下使用bochs进行实验,一直各种不方便,后来辛辛苦苦在Ubuntu下安装了bochs和Linux0.11内核,操作过程真的天上地下啊,Windows的bochs要一个一个跳转文件目录,输代码也烦死人,Ubuntu下直接在文件夹下修改就该,代码文件也可以通过挂载,在Ubuntu环境中直接写好,简直美滋滋啊。话不多说,详述实验过程(其实比起Windows下的操作,Ubuntu下简直简单死了好吧)

1.直接在ubuntu文件夹oslab/linux-0.11/ include/linux  之中修改sys.h

添加iam和whoami&&添加sys_iam,sys_whoami

操作系统实验2——系统函数调用

2.同理在文件夹linux-0.11/kernel 中修改system_calls.s,把   nr_system_calls 改为 74  ,其代表了中断函数的个数

操作系统实验2——系统函数调用

3.接下来修改Makefile文件,Makefile里记录的是所有源程序文件的编译、链接规则。

我们要修改的是linux-0.11/kernel/Makefile。需要修改两处。

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

改为:

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:
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

改为:

### Dependencies:
who.s who.o: who.c ../include/linux/kernel.h ../include/unistd.h
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
 

4.注意Makefile修改后需要编译,但是我们需要先添加who.c文件不然编译会提示找不到源文件

在oslab/linux/kernel下添加who.c文件,并编写文件代码如下

#define __LIBRARY__
#include <unistd.h>
#include <errno.h>
#include <asm/segment.h>
 
 
char temp[64]={0};
 
 
int sys_iam(const char* name)
{
   int i=0;
   while(get_fs_byte(name+i)!='\0')
        i++;
   if(i>23){   
        return -EINVAL;
   } 
   printk("%d\n",i);
   i=0;
   while((temp[i]=get_fs_byte(name+i))!='\0'){
i++;
    }   
    return i;
}
 
 
int sys_whoami(char* name,unsigned int size)
{
    int i=0;
    while (temp[i]!='\0')
i++;
    if (size<i)
    return -1;
    i=0;
    while(temp[i]!='\0'){
put_fs_byte(temp[i],(name+i));
i++;
    }
    return i;
}

 

5.在ubuntu系统下进入oslab/linux-0.11目录下再次编译

先make clean再make,编译成功后进行下一步

6.对unistd.h进行修改,需要注意unistd.h 不能直接在oslab直接修改,而且在ubuntu系统下是看不到usr内部文件的,我们可以通过挂载,实现在ubuntu系统下对Linux内部文件的修改。

在oslab中有一个mount-hdc脚本

sudo ./mount-hdc

可以把虚拟机硬盘挂载在oslab/hdc 目录下。我们可以直接在hdc文件夹内看到内部文件。在hdc/usr/include 目录下修改unistd.h 代码如下

#define __NR_ssetmask	69
#define __NR_setreuid	70
#define __NR_setregid	71
#define __NR_iam   72
#define __NR_whoami  73

7.修改结束后我们只是对挂载的文件进行了修改,还需要同步到Linux内部文件中,因此我们可以通过解除挂载实现内部文件的更新(同理,内部文件更新后我们需要在外部先解除挂载,再重新挂载,此处有误,解不解除挂载没有影响,但是在内部修改文件后需要解除挂载再重新挂载才能看到更新,如果没有就等一会多试两次,怀疑系统对更新的写入比较慢。。。)

sudo umount hdc

8.最后我们需要在Linux内部文件/usr中写入whoami.c和iam.c文件,因为在挂载的hdc文件夹中似乎不能新建新文件,我们可以先运行bochs,进入/usr文件夹下

vi iam.c

vi whoami.c

在c文件中随意输入一些字符保存后退出,这样我们再次挂载后就能在hdc文件下看到我们添加的iam.c和whoami.c文件了,然后我们直接在ubuntu系统下编辑代码(比bochs下使用vi编译方便的多有没有)代码文件如下

iam.c

#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
_syscall1(int,iam,const char*,name)
 
int main(int argc,char* argv[])
{
	
    if(argc>1){
	if(iam(argv[1])<0){
		printf("SystemCall Exception!\n");
		return -1;
	}
    }
    else{
	printf("Input Exception!\n");
	return -1;
    }		
    return 0;
}

whoami.c

#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
 
_syscall2(int,whoami,char*,name,unsigned int,size)
 
int main()
{
    int counter;
	char buff[128]={0};
	
    counter=whoami(buff,128);
	if(counter < 0)
	{
	   printf("SystemCall Exception!");
	   return -1;
    	}
	else{
		printf("%s\n",buff);
    	}
    return 0;
}

修改完成后保存,然后解除挂载(不解除的话修改不会同步到Linux中)

9.最后我们运行bochs进入/usr文件夹下对whoami和iam文件进行编译

gcc -o iam iam.c

gcc -o whoami whoami.c

10.编译成功后运行效果如下

[/usr]# ./iam hello
5
[/usr]# ./whoami
hello

iam会返回字符串的字数,whoami会从系统中获得我们输入的字符串并输出

相关文章: