xv6 syscall实验
Syscall
文章目錄
- Syscall
- 一、實驗要求
- Part One: System call tracing
- Part Two: Date system call
- 二、實驗操作
- Part one
- Part Two
request
一、實驗要求
Part One: System call tracing
Your first task is to modify the xv6 kernel to print out a line for each system call invocation. It is enough to print the name of the system call and the return value; you don’t need to print the system call arguments.
When you’re done, you should see output like this when booting xv6:
That’s init forking and execing sh, sh making sure only two file descriptors are open, and sh writing the $ prompt. (Note: the output of the shell and the system call trace are intermixed, because the shell uses the write syscall to print its output.)
Hint: modify the syscall() function in syscall.c.
Optional challenge: print the system call arguments.
Part Two: Date system call
Your second task is to add a new system call to xv6. The main point of the exercise is for you to see some of the different pieces of the system call machinery. Your new system call will get the current UTC time and return it to the user program. You may want to use the helper function, cmostime() (defined in lapic.c), to read the real time clock. date.h contains the definition of the struct rtcdate struct, which you will provide as an argument to cmostime() as a pointer.
You should create a user-level program that calls your new date system call; here’s some source you should put in date.c:
#include "types.h" #include "user.h" #include "date.h"int main(int argc, char *argv[]) {struct rtcdate r;if (date(&r)) {printf(2, "date failed\n");exit();}// your code to print the time in any format you like...exit(); }In order to make your new date program available to run from the xv6 shell, add _date to the UPROGS definition in Makefile.
Your strategy for making a date system call should be to clone all of the pieces of code that are specific to some existing system call, for example the “uptime” system call. You should grep for uptime in all the source files, using *grep -n uptime .[chS].
When you’re done, typing date to an xv6 shell prompt should print the current UTC time.
Write down a few words of explanation for each of the files you had to modify in the process of creating your date system call.
Optional challenge: add a dup2() system call and modify the shell to use it.
*syscall.h:
二、實驗操作
Part one
要實現系統調調用時打印系統調用的名稱和參數,我們需要修改syscall.c 和syscalll.h文件
然后我們先看一下syscall.c的代碼
// System call numbers #define SYS_fork 1 #define SYS_exit 2 #define SYS_wait 3 #define SYS_pipe 4 #define SYS_read 5 #define SYS_kill 6 #define SYS_exec 7 #define SYS_fstat 8 #define SYS_chdir 9 #define SYS_dup 10 #define SYS_getpid 11 #define SYS_sbrk 12 #define SYS_sleep 13 #define SYS_uptime 14 #define SYS_open 15 #define SYS_write 16 #define SYS_mknod 17 #define SYS_unlink 18 #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21不難看出,這段代碼是對xv6 21個常見系統調用的宏定義,我們要想實現打印調用名稱和參數,可以在syscall.c設置和系統調用的相同的編號和名稱相對應的數組
#include "x86.h" #include "syscall.h"// 以下為添加的內容 static char SYS_call_names[][6] = {[SYS_fork] "fork",[SYS_exit] "exit",[SYS_wait] "wait",[SYS_pipe] "pipe",[SYS_read] "read",[SYS_kill] "kill",[SYS_exec] "exec",[SYS_fstat] "fstat",[SYS_chdir] "chdir",[SYS_dup] "dup",[SYS_getpid] "getpid",[SYS_sbrk] "sbrk",[SYS_sleep] "sleep",[SYS_uptime] "uptime",[SYS_open] "open",[SYS_write] "write",[SYS_mknod] "mknod",[SYS_unlink] "unlink",[SYS_link] "link",[SYS_mkdir] "mkdir",[SYS_close] "close"}; // 以上為添加的內容然后除此之外還需要修改syscall()函數,使其實現當系統調用時打印對應的名稱和編號
$make qemu (或make qemu-nox) //make qemu-nox是將qemu固定在linux下,在串口終端中啟動Qemu運行結果如下圖
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-C5kxiRPK-1571208580659)(partone.png)]
到這里第一個小部分就完成了,這部分其實很簡單就是在syscall調用函數是加入了一句打印代碼使其實現功能
-
在這沒學過c語言的可能會疑惑是printf的基本語法,我在下面簡單介紹一下:
printf("%5d\n",1000); //默認右對齊,左邊補空格output: ` `1000
首先在這里的**cprintf()我認為和printf()**的基本用法是一樣的。
printf()函數調用格式:printf(“格式化字符串”,輸出表列)。格式化字符串包含三種對象,為:
(1)字符串常量
(2)格式化控制字符串
(3)轉義字符
字符串常量原樣輸出,在顯示中起提示作用。輸出表列中給出了各個輸出項,要求格式控制字符串和各輸出項在數量和類型上應該一一對應。其中格式控制字符串是以%開頭的字符串,在%后面跟有各種格式控制符,以說明輸出數據的類型、寬度、精度等。
格式化控制字符串:
%[標志][最小寬度][.精度][類型長度]類型
示例:常用轉義字符:
\n :回車符
\t :橫向制表符
\v:縱向制表符
Part Two
-
在各種文件里添加第22個系統調用sys_date
#define SYS_date 22
1.syscall.h:2.syscall.c:
[SYS_date] " date" };··· extern int sys_date(void);··· [SYS_date] sys_date3.user.h文件添加用戶態函數
int sleep(int); int uptime(void); // 以下為添加內容 int date(struct rtcdate*); // 以上為添加內容4.usys.S添加用戶態函數的實現
SYSCALL(date)5.sysproc.c添加系統調用函數
int sys_date(struct rtcdate *r) {if (argptr(0, (void *)&r, sizeof(*r)) < 0)return -1;cmostime(r); //從cmos中獲取時間return 0;}
至此,就完成了添加系統調用函數 date()
最后,我們需要添加使用這個系統調用函數的方法
新建文件 date.c ,并添加一下內容
6.最后不要忘了在MakeFile添加UPROGS對應的命令:
_big\ # 以下為添加內容_date\ # 以上為添加內容- 到此就完成了所有程序的修改,然后我們運行
- 但是結果卻并不和預期一樣
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-y0R4MoKv-1571208580662)(parttwo.png)]
然后我們發現其實這是之前第一部分系統調用造成的,雖然沒有達到我們的預期但是卻能夠清晰的顯現每個輸出的系統調用命令
然后我們把第一部分的系統調用注釋掉就好了
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dCvkrWaf-1571208580664)(partthree.png)]
最后成功的實現了我們的預期!
總結
以上是生活随笔為你收集整理的xv6 syscall实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 多数据源访问_通过Sprin
- 下一篇: 来谈谈JAVA面向对象 - 鲁班即将五杀