本文参考资料:《操作系统原型——xv6 分析与实验 深圳大学 SKT 罗秋明》
搭建好xv6环境,可以练习一些外围编程操作,为后续实验做准备。
- 添加新的应用程序
- 增加新的系统调用
修改xv6启动提示信息
打开 main.c 程序, 将其中的 cprintf()函数打印的启动提示信息“cpu0: starting xv6”修改成你所希望的样子,例如 将它修改成图 2-1 所示的样子——标志着自己开始动手修改 xv6 操作系统了。
图 2-1 修改后的启动提示信息
添加新的应用程序
我们先介绍xv6磁盘文件系统是如何生成的,包括2步
- 生成各个应用程序
- 将应用程序构成文件系统映像
在Makefile里默认所用.c文件都需要通过默认编译命令生成.o文件。同时对于所有.o文件都将结合$(ULIB)生成可执行文件(_开头文件名),如下代码。
ULIB = ulib.o usys.o printf.o umalloc.o
_%: %.o $(ULIB)
//-N指出data节与text节都是可读可写、不需要在页边界对齐。
//-e main指出main为运行起始;-Ttext 0指出代码存放在0地址处
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
$(OBJDUMP) -S $@ > $*.asm
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
而Makefile创建磁盘文件系统代码如下:
UPROGS=\
_cat\
_echo\
_forktest\
_grep\
_init\
_kill\
_ln\
_ls\
_mkdir\
_rm\
_sh\
_stressfs\
_usertests\
_wc\
_zombie\
fs.img: mkfs README $(UPROGS)
//磁盘文件系统fs.img目标依赖于UPROGS变量(包含所有相关可执行文件名)
//并将他们和README文件一起通过mkfs程序转换成文件系统映像fs.img
./mkfs fs.img README $(UPROGS)
添加简单程序
//头文件均存在于目录
#include "types.h"
#include "stat.h"
#include "user.h"
int main(int argc, char *argv[])
{
printf(1,"This is my own app!\n"); //0:标准输出文件,1:标准输出文件,2:出错文件
exit();
}
程序需要编写在xv6源码目录下(需要root权限),
同时Makefile中的UPROGS变量需要添加_my-app。执行make。
为什么开下虚拟机cpu跟要炸了似的呜呜呜,我承认年轻时不小心只买了主频1.8G但不至于8核还不够用吧啊啊啊啊
新增系统调用
摘抄自《操作系统原型——xv6 分析与实验 深圳大学 SKT 罗秋明》
如果我们修改了 xv6 的代码,例如增加了调度优先级,那么就需要有设置优先级的系统调 用,并且通过应用程序调用该系统调用进行优先级设置。比如,我们希望进程能知道自己所在的处理器编号,这可以通过一个新的系统调用来实现。 下面我们先学习如何在应用程序中调用现成的系统调用,然后再学习如何实现上述的新的系 统调用。
系统调用示例
#include "types.h"
#include "stat.h"
#include "user.h"
int
main(int argc, char *argv[])
{
printf(1, "My PID is: %d\n",getpid());
exit();
}
按照前面的方法修改 Makefile (血泪史得加/)并重新生成 xv6,启动后在 shell 中执行 print-pid 并成功打 印进程号。
添加系统调用
由于系统调用涉及较多内容,分散在多个文件中——这包括系统调用号的分配、系统调用 的分发代码(依据系统调用号)修改、系统调用功能的编码实现、用户库头文件修改等。另外 还涉及验证用的样例程序——用于检验该系统调用的功能。
增加系统调用号
xv6 的系统调用都有一个唯一编号,定义在 syscall.h 中,如错误!未找到引用源。所示。我 们可以在 SYS_close 的后面,新加入一行“#define SYS_getcpuid 22”即可,这里的编号 22 可 以是其他值——只要不是前面使用过的就好。