一、为版本0内核增加一个系统调用getjiffies
打开vscode
,在如图所示位置打开~/os/linux-0.11-lab/0
文件夹
(一)分析思路
1.定义getjiffies系统调用
题目中给的提示:进入到unistd.h
文件中
阅读代码,可以发现上图划线处有个系统调用名为getpid
:返回当前进程号——这与我们期望实现的功能类似:通过系统调用返回jiffies值。
于是此时希望模仿getpid
系统调用,实现getjiffies
系统调用。
在vscode
左侧搜索栏中搜索关键词getpid
,仿照即可。
主要修改下图划线的三个文件
2.在系统启动时自动调用该系统调用并输出结果
由于下图所示的任务要求
系统启动时将调用0/linux/init/main.c
文件,且其中的main
函数中下图圈出位置的if`语句中的init函数完成初始化的显示输出操作。
所以需要在main.c
的init
函数中调用getjiffies
系统调用。(也可以进入bochs虚拟机中在/etc/rc中调用getjiffies,即在文件的最后写入getjiffies,这样的话打印结果就可以符合题目要求了,二者选一做)
(二)实验过程
1.添加系统调用号
(1)unistd.h
在调用号的最后添加#define __NR_getjiffies 87
(2) 修改sys.h
的sys_call_table
和 system_call.s
的nr_system_calls
参考博文:CSDN-为Linux0.11添加系统调用(作者)-为Linux0.11添加系统调用
(注:system_call.s
在0/linux/kernel/
目录下)
这里的nr_system_calls
值为88,不能为87,因为系统调用数量为88个?不理解没有修改前的nr_system_calls
的值为什么为86,最后一个系统调用usrlib
没有用到吗。
2.定义getjiffies系统调用函数
可以看到jiffies
的变量类型为long
(1)仿照getpid
在unistd.h
中声明函数
(2)在sched.c`文件中定义函数主体
仿照getpid
系统调用
创建``getjiffies!系统调用
3.在系统启动时自动调用getjiffies
系统调用并输出结果
阅读main.c
代码,可以在文件的开始位置发现main.c
中调用的系统调用,如fork
、pause
都经过下图划线位置的__always_inline _syscall0
的操作,仿照该操作调用getjiffies系统调用。
在init
函数中打印信息。
(三)调试验证
进入~/os/linux-0.11-lab/0/linux
,
执行下列命令:
make clean;make
cd ../..
./run
得到如下图所示的输出,(虽然打印的位置在Ok.之上而非下面,但是)(如果想实现题目要求,可以在bochs中的/etc/rc文件的最后添加一行调用函数的getjiffies,而不是在main.c中调用,就可以了)
评测通过
二、在用户程序中使用新增的系统调用
(本题在完成上题的基础上(在虚拟机启动版本0内核时调用一次getjiffies
)直接操作,在文章末尾会论述如果直接开始做本题操作有何不同)
(一)初步编写mytest.c文件
根据以下“作业内容”的提示:
在vscode
中打开~/os/linux-0.11-lab
文件夹,在b
目录下,创建并编辑如下图所示的mytest.c
文件(内容并非最终正确答案,为方便演示常见错误,此处为错误代码,正确代码附在最后)
改内容为结合上述提示与上一题main.c
相关代码编写
(二)将mytest.c文件放入bochs虚拟机
注意:可以使用uemacs mytest.c
命令直接在虚拟机中创建并编写文件,则可编写完成后可直接进行(三),跳过此节
(注:启动虚拟机后,虚拟机保存启动时的b
文件夹的状态,此时物理机中编辑b
文件夹下文件,不会对已启动的虚拟机访问的b文件夹下的文件产生影响)
在~/os/linux-0.11-lab
目录下./run
启动
在虚拟机中执行下列命令:
mdir b:mytest.c
mcopy b:mytest.c .
结果如下图所示
(三)bochs 虚拟机中编译文件
执行下述命令使用gcc
编译mytest.c
文件
gcc mytest.c -o mytest
出现如下图所示的报错:
参考博文:CSDN-hjjdebug(作者)-ubutu14 下编译linux0.11内核错误记录及解决方法
进入vscode搜索__attribute__
在0/linuxinclude
的unistd.h
文件中下图右下划线位置处的__always_inline
,而上述gcc
的报错提示信息为语法错误,于是现在需要在mytest.c
文件中删除掉__always_inline
。
使用命令uemacs mytest.c
在虚拟机中修改mytest.c
文件,删除掉其中的__always_inline
,ctrl + x
+s
保存,ctrl + x
+ ctrl + c
退出。
再次编译出现新的报错:
缺少对__NR_getjiffies
的定义,而由于上一题中设置的__NR_getjiffies系统调用号为87,需要在mytest.c中添加#define __NR_getjiffies 87
。
再次使用命令uemacs mytest.c
在虚拟机中修改mytest.c
文件,添加#define __NR_getjiffies 87
,ctrl + x
+s
保存,ctrl + x
+ ctrl + c
退出。
mytest.c
文件正确代码:
#define __LIBRARY__
#include<unistd.h>
#define __NR_getjiffies 87
_syscall0(long,getjiffies)
void main()
{
printf("Getjiffies: %ld\n", getjiffies());
}
再次执行gcc
编译命令
gcc mytest.c -o mytest
ls
结果如下图所示,编译成功出现可执行文件mytest
(三)验证mytest文件正确性
(四)编辑/etc/rc文件
uemacs /ec/rc
修改器内容如下图所示。
验证/etc/rc文件正确性
注意:在虚拟机中执行过命令,未使用相关命令验证就很快退出虚拟机,重启后会发现最近执行的一条或几条命令失效,如uemacs /etc/rc
命令修改过/etc/rc
文件后,立即退出,再次进入虚拟机发现/etc/rc
文件编辑过的内容没有了,正确的做法是在编辑完/etc/rc
文件后,执行cat /etc/rc
命令,gcc命令类似,需要执行./
命令执行gcc
编译后的文件
(得到结果与上图所示打印结果不同也没有关系,共有三条就可以)
注意:重启后得到了如上图所示的输出有可能依然会报错,这可能时题目本身的问题,可以尝试多次执行下列操作:
“进入~/os/linux-0.11-lab/0/linux
,
执行下列命令:”
make clean;make
cd ../..
./run
注意如果并非做完上一题直接做本题,即在0/linux/init/main.c
中没有打印字符串"Getjiffies: %ld", getjiffies()
,那么此处/etc/rc
文件应该修改为如下图所示内容:
即本题共需要在系统启动时调用三次getjiffies
系统调用。
重启虚拟机后发现评测结果不对也没有关系,根据上上条注意条目的内容多尝试几次
另外,本题的对getjiffies
系统调用中的定义中的long均可换成int,也可以通关。
通过测试
三、第二题——极简版思路
(在未第一题的情况下)
1.在0/include/unistd.h中添加系统调用号和函数调用声明
#define __NR_getjiffies 87
long getjiffies(void);
2.将0/kernel/system.h文件中的nr_system_calls = 86改为nr_system_calls = 88
3.在0/include/linux/sys.h文件中添加extern long sys_getjiffies();并在该文件中的sys_call_table[]数组的末尾添加, sys_getjiffies
4.在0/kernel/sched.c文件中添加如下函数
long sys_getjiffies(void)
{
return jiffies;
}
5.启动虚拟机输入uemacs /etc/rc,在该文件中添加下列内容
cd /usr/root
./mytest
sync
./mytest
./mytest
ctrl+x
+s
保存,ctrl+x
+ctrl+c
退出
6.输入uemacs mytest.c在文件中输入如下下内容
#define __LIBRARY__
#include<unistd.h>
#define __NR_getjiffies 87
_syscall0(long,getjiffies)
void main()
{
printf("Getjiffies: %ld\n", getjiffies());
}
ctrl+x
+s
保存,ctrl+x
+ctrl+c
退出
7.gcc mytest.c -o mytest编译生成mytest文件,./mytest验证
在退出虚拟机前要验证文章来源:https://www.toymoban.com/news/detail-401889.html
8.退出虚拟机进入0/linux执行几次make clean;make命令(玄学)
9../run进入虚拟机,出现如下图所示的界面,开始评测,评测不成功就在虚拟机里输入几条之前输入过的命令,再次执行第8条(玄学),反复几次,就可以评测通过了
文章来源地址https://www.toymoban.com/news/detail-401889.html
到了这里,关于操作系统实验 2.3系统调用:linux-0.11-lab “为版本0内核增加一个系统调用getjiffies” 和 “在用户程序中使用新增的系统调用”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!