MIT 6.828 Homework: Xv6 System Calls

来源:https://www.cnblogs.com/tea-in-the-snow/archive/2022/11/11/16879391.html
-Advertisement-
Play Games

Part One: System call tracing 任務:修改Xv6內核的代碼來列印出每個系統調用以及返回值 根據提示,應該在syscall.c中修改syscall()。 首先在syscall.c中增加對應系統調用名稱的數組: static char *syscalls_name[] = { ...


Part One: System call tracing

任務:修改Xv6內核的代碼來列印出每個系統調用以及返回值

根據提示,應該在syscall.c中修改syscall()。
首先在syscall.c中增加對應系統調用名稱的數組:

static char *syscalls_name[] = {
[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()中添加列印命令:

void
syscall(void)
{
  int num;
  struct proc *curproc = myproc();

  num = curproc->tf->eax;
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
    curproc->tf->eax = syscalls[num]();
    cprintf("%s -> %d\n", syscalls_name[num], curproc->tf->eax);
  } else {
    cprintf("%d %s: unknown sys call %d\n", curproc->pid, curproc->name, num);
    curproc->tf->eax = -1;
  }
}

最終執行結果如下:

xv6...
cpu0: starting 0
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
exec -> 0
open -> 0
dup -> 1
dup -> 2
iwrite -> 1
nwrite -> 1
iwrite -> 1
twrite -> 1
:write -> 1
 write -> 1
swrite -> 1
twrite -> 1
awrite -> 1
rwrite -> 1
twrite -> 1
iwrite -> 1
nwrite -> 1
gwrite -> 1
 write -> 1
swrite -> 1
hwrite -> 1

write -> 1
fork -> 2
exec -> 0
open -> 3
close -> 0
$write -> 1
 write -> 1

註:shell的輸出和系統調用的調用路徑混在了一起,原因是shell是通過系統調用write來列印輸出的

Part Two: Date System Call

任務: 在Xv6中新增一個系統調用date。使用定義於lapic.c中的函數cmostime(),以系統調用uptime為例,觀察如何添加一個系統調用。並且在用戶層添加一個調用系統調用date的程式。

  1. 首先使用grep - n uptime *.[chS]命令在源碼中查找uptime相關的代碼,接下來逐個查看搜索到的位置,模仿寫出date系統調用所需要的代碼
❯ grep -n uptime *.[chS]
syscall.c:105:extern int sys_uptime(void);
syscall.c:121:[SYS_uptime]  sys_uptime,
syscall.h:15:#define SYS_uptime 14
sysproc.c:83:sys_uptime(void)
user.h:25:int uptime(void);
usys.S:31:SYSCALL(uptime)
  1. 在syscall.c的對應位置添加代碼後如下:
extern int sys_chdir(void);
extern int sys_close(void);
extern int sys_dup(void);
extern int sys_exec(void);
extern int sys_exit(void);
extern int sys_fork(void);
extern int sys_fstat(void);
extern int sys_getpid(void);
extern int sys_kill(void);
extern int sys_link(void);
extern int sys_mkdir(void);
extern int sys_mknod(void);
extern int sys_open(void);
extern int sys_pipe(void);
extern int sys_read(void);
extern int sys_sbrk(void);
extern int sys_sleep(void);
extern int sys_unlink(void);
extern int sys_wait(void);
extern int sys_write(void);
extern int sys_uptime(void);
extern int sys_date(void); // 新添加

static int (*syscalls[])(void) = {
[SYS_fork]    sys_fork,
[SYS_exit]    sys_exit,
[SYS_wait]    sys_wait,
[SYS_pipe]    sys_pipe,
[SYS_read]    sys_read,
[SYS_kill]    sys_kill,
[SYS_exec]    sys_exec,
[SYS_fstat]   sys_fstat,
[SYS_chdir]   sys_chdir,
[SYS_dup]     sys_dup,
[SYS_getpid]  sys_getpid,
[SYS_sbrk]    sys_sbrk,
[SYS_sleep]   sys_sleep,
[SYS_uptime]  sys_uptime,
[SYS_open]    sys_open,
[SYS_write]   sys_write,
[SYS_mknod]   sys_mknod,
[SYS_unlink]  sys_unlink,
[SYS_link]    sys_link,
[SYS_mkdir]   sys_mkdir,
[SYS_close]   sys_close,
[SYS_date]    sys_date, // 新添加
};
  1. 在syscall.h中添加代碼:
#define SYS_date   22
  1. 在user.h中添加代碼:
int date(struct rtcdate*);
  1. 在usys.S中添加代碼:
SYSCALL(date)
  1. 在sysproc.c中添加代碼:
int sys_date(void) {
    struct rtcdate* r = 0;
    if (argptr(0, (char**)&r, sizeof(*r) < 0)) {
        return -1;
    }
    cmostime(r);
    return 0;
}
  1. 以上在操作系統中添加了一個系統調用,下麵編寫一個執行該系統調用的命令,編寫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();
  }

  printf(1, "%d-%d-%d %d:%d:%d\n", r.year, r.month, r.day, r.hour, r.minute, r.second);

  exit();
}
  1. 在Makefile中的UPROG中添加
_date\

在完成以上步驟後,成功添加了系統調用date以及調用它的命令date,測試結果如下:

xv6...
cpu0: starting 0
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
init: starting sh
$ date
2022-11-10 18:19:21
$

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介: 命令模式,又稱之為動作模式或者事務模式,屬於行為型的設計模式。 將不同的請求封裝成不同的請求對象,以便使用不同的請求; 角色都會用飯館來舉例子: 命令下達者:顧客 命令接受者:服務員 命令本身: 菜單 命令執行者:廚師 適用場景: Laravel的事件調度機制有用到了命令模式。 想要解耦服務 ...
  • Java 基礎一 【註釋】 comment 對代碼進行解釋說明1.Java規範的註釋有3種單行註釋://多行註釋:/* */文檔註釋(java特有)2.單行註釋和多行註釋的作用:對所寫的程式進行解釋說明,增強可讀性。方便自己,方便別人。可以調試所寫的代碼3.特點單行註釋和多行註釋,註釋了的內容不參與 ...
  • RPC(Remote Procedure Call) 是 Hadoop 服務通信的關鍵庫,支撐上層分散式環境下複雜的進程間(Inter-Process Communication, IPC)通信邏輯,是分散式系統的基礎。允許運行於一臺電腦上的程式像調用本地方法一樣,調用另一臺電腦的子程式。由於 ...
  • 作為緩存系列專欄的第四篇文章,我們將在上一篇的基礎之上進行升華,一起思考如何構建一個完整且通用的本地緩存框架,併在過程中體會緩存實現的關鍵點與架構設計的思路。 ...
  • 2022年11月8日.NET 7正式發佈 .NET仍然是最快、最受歡迎、最值得信賴的平臺之一,其龐大的.NET軟體包生態系統包括33萬多個軟體包。 .NET 7為您的應用程式帶來了更高的性能和C# 11/F# 7、.NET MAUI、ASP.NET Core/Blazor、Web APIs、WinF ...
  • 一:背景 1.講故事 有朋友咨詢個問題,他每次在調試 WinDbg 的時候,進程初始化斷點之前都會有一些 dll 載入到進程中,比如下麵這樣: Microsoft (R) Windows Debugger Version 10.0.25200.1003 X86 Copyright (c) Micro ...
  • 依賴管理是 NuGet 的核心功能。Nuget管理單個項目的依賴關係很容易。管理多項目解決方案的依賴關係可能會變得很困難,因為它們的規模和複雜性開始擴大。 在您管理許多不同項目的公共依賴項的情況下,您可以利用 NuGet 的中央包管理功能從一個位置輕鬆完成所有這些工作。 要開始使用中央包管理,您可以 ...
  • 前言 之前想用Markdown來寫框架文檔,找來找去發現還是Jekyll的多,但又感覺不是很合我的需求 於是打算自己簡單弄一個展示Markdown文檔的網站工具,要支持多版本、多語言、導航、頁內導航等,並且支持Github Pages免費站點 組件選擇 我自己呢比較喜歡C#,恰好現在ASP.Net ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...