PA3.2

1.实现write系统调用,运行HelloWorld

    回顾一下实现某一种系统调用的步骤:
    ①在do_syscall函数中的选择分支结构中添加分支调用相应的系统调用处理函数。
    ②编写系统调用处理函数sys_xxx内容。
    ③设置返回值到eax。

    在3.1中我们实现的是SYS_none和SYS_exit,两者都属于比较简单的系统调用(一个是直接返回1,一个是退出)。而这里要实现的SYS_write相对较为复杂,但理解其中原理后其实也很简单,只不过函数的内容讲义没直接给出,而是要我们自己去查阅文档。
    首先是函数怎么写的问题。答案很简单,man或者百度。函数参数的意义和返回值是什么一查便知。另外要用到的_putc函数,函数原型是void _putc(char ch)(同前面的 _halt函数一样在SPEC.md文件中有说明,在SPEC.md这个文件中说明了很多框架东西),看过代码可以知道其作用是将ch的内容通过outb指令传输到串口设备(pa 2.3内容)。
    然后关于框架理解,这里涉及到如何得到参数、函数是如何被调用的问题。这里我不得不吐槽一下讲义是真的睿智,突然提到在nanos.c文件中加东西,然后半字不提这里代码要注意看,而且实际上这部分代码应当是在3.1中就需要理解的才对。
    先上图上代码
这里写图片描述
    首先看syscall函数,可以看到有四个参数,函数中使用了内联汇编将四个参数(调用类型、参数1、参数2、参数3)依次传给了eax、ebx、ecx、edx,然后将返回值即返回后eax中的值赋给ret。这样就可以理解为什么do_syscall函数中是将SYSCALL_ARG1(r)作为判断系统调用类型的依据了,并且不难想到,系统调用的其他参数就这样通过接口函数依次传入各个寄存器即可。然后看_exit函数,这里就是调用了接口函数传递了四个参数,可以看到系统调用类型是前面实现的SYS_exit。由此可以得出结论,这里的都是各种通过系统调用实现的函数,执行过程就是通过接口函数传递参数,然后统一由do_syscall函数处理(虽然框架有毒,但代码写的还是很精妙的)。
    根据讲义要求,再加上RTFSC的结果,可知实现系统调用还需第四步——在nanos.c文件中添加接口函数传递参数。但还没完,光做这一步会发现程序只输出了一行hello world就结束了,这就是没有RTFSC的坑。仔细看代码,所有未实现的函数中都默认转成了exit类型的系统调用,因此还需要注释掉这一行,不然经过一次系统调用后程序就会退出。另外这里还有一个坑,由于nanos.c文件是navy-app项目中的,所以修改它和nanos-lite的编译没有半毛钱关系,这个文件实际上是和navy-app中的应用程序的编译有关,因此修改这个文件后,需要重新编译当前要运行的项目,然后连锁的ramdisk的内容就需要更新,因此还要再make update(就是这么坑)。
    正确完成后,运行结果如下(是个死循环):
    这里写图片描述


更新ing…..

猜你喜欢

转载自blog.csdn.net/qq_21110935/article/details/80345199
3.2
今日推荐