日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

xv6实验课程--系统调用

發布時間:2023/12/9 windows 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 xv6实验课程--系统调用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文來源:

https://mp.weixin.qq.com/s/kPwvXMZ2cv8uQNZIsKcAjA

在上一個實驗中,你使用系統調用編寫了一些實用程序。在本實驗中,你將向xv6添加一些新的系統調用,這將幫助你了解它們是如何工作的,同時,讓你了解xv6內核的一些內部結構。在以后的實驗中你可能會添加更多的系統調用。?

在開始編碼之前,請閱讀xv6手冊的第2章、第4章的4.3節、4.4節以及下面所列相關源文件:

系統調用的用戶空間代碼:在user/user.h和user/usys.pl中。

內核空間代碼:在kernel/syscall.h和kernel/syscall.c中。

與進程相關的代碼:在kernel/proc.h和kernel/proc.c中。?

開始本實驗前,請切換到syscall分支:

? $ git fetch

? $ git checkout syscall

? $ make clean

1. 系統調用跟蹤?(難度:中等)?

任務:在xv6中添加一個系統調用跟蹤功能,該功能可幫助你在以后的實驗中調試程序。您將創建一個新的trace系統調用來控制跟蹤。它應該有一個參數,一個整數“mask”,其位指定要跟蹤的系統調用。例如,為了跟蹤fork系統調用,程序調用trace(1<<SYS_fork),其中SYS_fork是kernel/syscall.h中的syscall編號。如果在掩碼中設置了系統調用的編號,則必須修改xv6內核,以便在每個系統調用即將返回時輸出一行。該行應包含進程id、系統調用的名稱和返回值;不需要輸出系統調用參數。trace系統調用應啟用對調用它的進程及其隨后派生的任何子進程的跟蹤,但不應影響其他進程。

我們提供了一個跟蹤用戶級程序,該程序運行另一個啟用了跟蹤的程序(請參見user/trace.c)。完成后,您應該看到如下輸出:

例1: trace調用grep僅僅跟蹤read系統調用。32是1<<SYS_read。注:輸出的第一段是進程標識符PID,第二段是系統調用名稱,第三段是系統調用返回碼。

例2: trace跟蹤所有運行grep時調用的系統調用,其中2147583647的低31位都為1。

例3: 程序沒有被跟蹤,因此沒有打印跟蹤輸出。

例4:usertests中的forkforkfork測試的所有后代的fork系統調用都被跟蹤。

如果程序的行為如上所示,則你的實驗方案是正確的(盡管進程ID可能不同)。

提示:

●?將$U/_trace添加到Makefile的UPROGS中

●?運行make qemu,您將看到編譯器無法編譯user/trace.c,這是因為系統調用的用戶空間的存根(stubs)還不存在:將系統調用的原型添加到user/user.h,將存根添加到user/usys.pl中,并將syscall編號添加到kernel/syscall.h。Makefile調用perl腳本user/usys.pl,它生成user/usys.S,即實際的系統調用存根,它使用RISC-V ecall指令轉換到內核。一旦你修復了編譯問題,運行trace 32 grep hello README;它將失敗,因為您尚未在內核中實現系統調用。

●?在kernel/sysproc.c中添加一個sys_strace( )函數,通過在proc結構的新變量中記住其參數來實現新的系統調用(請參見kernel/proc.h)。從用戶空間檢索系統調用參數的函數在kernel/syscall.c中,您可以在kernel/sysproc.c中看到它們的使用示例。

●?修改fork( )(參見kernel/proc.c)將跟蹤掩碼從父進程復制到子進程。

●?修改kernel/syscall.c中的syscall( )函數以輸出跟蹤輸出。您需要添加一個syscall名稱數組來索引到其中。

實驗參考步驟

步驟1:用戶接口代碼的修改

(1) 在user/user.h中添加系統調用函數的定義。

(2) 在user/usys.pl中添加入口entry("trace")。

在make時會調用usys.pl生成user/usys.S匯編程序。在該匯編程序中,每個函數有五行,其中有三條指令,其功能是將系統調用號通過li(load?imm)存入a7寄存器,之后使用ecall指令進入內核態,最后返回。

make后user/usys.S中將出現下圖中.global trace開始的5行代碼。

步驟2:內核代碼的修改

(1)在kernel/syscall.h中定義系統調用號。

(2)在kernel/syscall.c的syscalls函數指針數組中添加對應的函數。

在syscall函數中,可讀取trapframe->a7獲取系統調用號,之后根據該系統調用號查找syscalls數組中的對應的處理函數并調用。

(3)在proc結構體中添加一個trace_mask字段,之后在創建子進程的fork函數中復制該字段到新進程。

kernel/proc.h

kernel/proc.c

(4)系統調用sys_trace的實現。在sysproc.c中添加函數uint64 sys_trace(void),該函數通過argint函數讀取參數賦值給mask變量,然后與trace_mask字段位或即可。

(5) 修改syscall函數,當系統調用號和trace_mask匹配時輸出相關信息。

注意上圖中的黃線處的syscall_name[num],這個需要定義。如下圖所示。

步驟3:編寫應用工具(注:源代碼中已提供)

user/trace.c

步驟4:修改Makefile,將$U/_trace添加到Makefile的UPROGS中。

步驟5:make qemu,然后測試。

2. Sysinfo (難度:中等)?

任務:增加一個sysinfo系統調用,它收集有關運行系統的信息。該系統調用有一個參數,即指向結構sysinfo的指針(參見kernel/sysinfo.h)。內核為該結構的各個字段賦值:設置freemem字段為可用內存的字節數,設置nproc字段為狀態是非UNUSED的進程數。實驗提供了一個測試程序sysinfotest,如果輸出“sysinfotest:OK”,則該任務通過。

提示:

●?將$U/_sysinfotest添加到Makefile的UPROGS中。

●?運行make qemu,user/sysinfotest.c將無法編譯。添加系統調用sysinfo,步驟與前面的trace系統調用相同。要在user/user.h中聲明sysinfo( )的原型,預先聲明struct sysinfo的存在:

struct sysinfo;

int sysinfo(struct sysinfo *);

●?修改上述編譯問題后,運行sysinfotest將會失敗,因為你尚未在內核中實現系統調用。

● sysinfo需要將struct sysinfo復制到用戶空間,請參閱sys_fstat( )(kernel/sysfile.c)和filestat( )(kernel/file.c)以獲取如何使用copyout()執行此操作的示例。

● 請在kernel/kalloc.c中添加一個函數,收集可用內存量。

●?請在kernel/proc.c中添加一個函數,收集進程數。

實驗參考步驟

步驟1:用戶接口代碼的修改

(1) 在user/user.h中聲明struct sysinfo的存在。(注:struct sysinfo在kernel/sysinfo.h中定義。

(2) 在user/user.h中添加系統調用函數的定義。

(3) 在user/usys.pl中添加入口 entry("sysinfo")。

在make時會調用usys.pl生成user/usys.S匯編程序。在該匯編程序中,每個函數有五行,其中有三條指令,其功能是將系統調用號通過li(load imm)存入a7寄存器,之后使用ecall指令進入內核態,最后返回。

make后user/usys.S中將出現下圖中.global sysinfo開始的5行代碼。

步驟2:內核代碼的修改

(1)在kernel/syscall.h中定義系統調用號。

(2)在kernel/syscall.c的syscalls函數指針數組中添加對應的函數及函數名。

(3)freemem()函數的實現。

閱讀kalloc和kfree兩個函數可知,kmem.freelist是一個保存了當前空閑內存塊的鏈表,因此只需要統計這個鏈表的長度再乘以PGSIZE就可以得到空閑內存。(注:kalloc和kfree兩個函數在kernel/kalloc.c文件中。)

在kernel/defs.h中聲明freemem函數。

在kernel/kalloc.c中添加freemem函數。

// get free memory uint64 freemem(void) {uint64 counter = 0;struct run *r;acquire(&kmem.lock); // 上鎖r = kmem.freelist; // 空閑塊鏈表while(r){ // 遍歷空閑塊鏈表,統計空閑塊塊數r = r->next;++counter;}release(&kmem.lock); // 釋放自旋鎖return counter * PGSIZE; // 返回空閑存儲空間大小,單位字節(B) }

(4)nproc()函數的實現。

閱讀procdump和相關代碼可知,xv6的進程結構體保存在proc[NPROC]數組中。而proc->state字段保存了進程的當前狀態,有UNUSED、SLEEPING、RUNNABLE、RUNNING、ZOMBIE五種狀態。因此只需要遍歷這個數組,統計state不是UNUSED狀態的就行了。

在kernel/defs.h中聲明nproc函數。

在kernel/proc.c中添加nproc函數。

// get number of proc uint64 nproc(void) {uint64 counter = 0;struct proc *p;// 遍歷進程控制塊,即OS課程中的PCBfor(p = proc; p < &proc[NPROC]; p++) { acquire(&p->lock);if(p->state != UNUSED) {++counter;}release(&p->lock);}return counter; }

(5)系統調用sys_sysinfo的實現。在sysproc.c中添加函數uint64 sys_sysinfo(void)。該函數主要通過freemem和nproc兩個函數來統計空閑內存量和進程數。首先在kernel/proc.c中添加頭文件#include "sysinfo.h"

添加sys_sysinfo(void)系統調用代碼。

?

// get sysinfo uint64 sys_sysinfo(void) {uint64 info; // user pointerstruct sysinfo kinfo;struct proc *p = myproc();if(argaddr(0, &info) < 0){return -1;}kinfo.freemem = freemem();kinfo.nproc = nproc();if(copyout(p->pagetable, info, (char*)&kinfo, sizeof(kinfo)) < 0){return -1;}return 0; }

步驟3:編寫應用工具(注:源代碼中已提供了測試程序sysinfotest)

步驟4:修改Makefile,將$U/_sysinfotest添加到Makefile的UPROGS中。

步驟5:make qemu,然后測試。

? ? ? ? ?make?grade

參考資料

[1] https://pdos.csail.mit.edu/6.828/2021/labs/syscall.html

[2] https://www.cnblogs.com/YuanZiming/p/14218997.html

總結

以上是生活随笔為你收集整理的xv6实验课程--系统调用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。