国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MIT6.S081 - Lab2: system calls

這篇具有很好參考價(jià)值的文章主要介紹了MIT6.S081 - Lab2: system calls。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Lab2: system calls

預(yù)備知識(shí)

執(zhí)行一次系統(tǒng)調(diào)用的流程:

USER MODE

step1:系統(tǒng)調(diào)用聲明

  • user/user.h:系統(tǒng)調(diào)用函數(shù)(如 int fork(void))

step2:ecall 進(jìn)入內(nèi)核態(tài)

  • user/usys.S(該文件由 user/usys.pl 生成,后續(xù)添加函數(shù)可以在這里添加):執(zhí)行如下命令
 .global fork
 fork:
   li a7, SYS_fork
   ecall
   ret
  • 將系統(tǒng)調(diào)用的編號(hào)(在kernel/syscall.h中定義)寫(xiě)入a7寄存器
  • ecall進(jìn)入中斷處理函數(shù)

KERNEL MODE

step3:保存數(shù)據(jù)并跳轉(zhuǎn)到中斷判斷函數(shù)

  • kernel/trampoline.S:在uservec中保存寄存器、切換到內(nèi)核棧、切換棧指針SP等,最后跳轉(zhuǎn)到內(nèi)核指定的中斷判斷函數(shù)usertrap(在kernel/trap.c中)
    • 每一個(gè)進(jìn)程都對(duì)應(yīng)一個(gè)狀態(tài)結(jié)構(gòu)體proc(在kernel/proc.h中定義這個(gè)結(jié)構(gòu)體),將數(shù)據(jù)存儲(chǔ)在這里

step4:中斷判斷函數(shù)

  • kernel/trap.c:中斷判斷函數(shù)usertrap用于處理來(lái)自用戶態(tài)的中斷、異?;蛳到y(tǒng)調(diào)用,在此處判斷是否是系統(tǒng)調(diào)用,如果是,則執(zhí)行響應(yīng)函數(shù)syscall

step5:執(zhí)行對(duì)應(yīng)的系統(tǒng)調(diào)用

  • kernel/syscall.c:響應(yīng)函數(shù)syscall用于對(duì)號(hào)入座,根據(jù)給出的syscalls表(將系統(tǒng)調(diào)用編號(hào)與執(zhí)行函數(shù)相對(duì)應(yīng))獲取系統(tǒng)調(diào)用類(lèi)型(系統(tǒng)調(diào)用編號(hào)從a7寄存器中讀取),執(zhí)行相應(yīng)的函數(shù)(進(jìn)入kernel/sysproc.c中);系統(tǒng)調(diào)用的返回值傳遞給了a0,后續(xù)會(huì)回傳給用戶態(tài)

step6:系統(tǒng)調(diào)用函數(shù)

  • kernel/sysproc.c:保存著系統(tǒng)調(diào)用的執(zhí)行函數(shù),如果系統(tǒng)調(diào)用有參數(shù),需要用argraw(讀取參數(shù)本質(zhì)上是從內(nèi)存中恢復(fù),見(jiàn)kernel/syscall.c)取出保存的寄存器數(shù)據(jù),然后函數(shù)最終都將調(diào)用相對(duì)應(yīng)的執(zhí)行函數(shù)(在kernel/proc.c中)

step7:系統(tǒng)調(diào)用核心功能

  • kernel/proc.c:這里的函數(shù)用于執(zhí)行核心功能,如創(chuàng)建進(jìn)程等

添加系統(tǒng)調(diào)用需要考慮的地方

  1. user/user.h中添加系統(tǒng)調(diào)用的函數(shù)聲明,并在user中創(chuàng)建相應(yīng)的系統(tǒng)調(diào)用(*.c文件)(和lab1類(lèi)似)

  2. user/usys.pl中添加系統(tǒng)調(diào)用項(xiàng)

  3. kernel/syscall.h添加系統(tǒng)調(diào)用的編號(hào)

  4. kernel/syscall.c中的syscalls表中添加映射關(guān)系,指出需要執(zhí)行的函數(shù)

  5. kernel/sysproc.ckernel/proc.c中實(shí)現(xiàn)系統(tǒng)調(diào)用的執(zhí)行函數(shù)

Part1:System call tracing

實(shí)現(xiàn)功能

  1. 添加一個(gè)系統(tǒng)調(diào)用的trace功能,在命令前輸入trace <mask>,能夠打印出該命令使用的系統(tǒng)調(diào)用

  2. mask = 1 << SYS_name為一個(gè)整數(shù),它能夠指定跟蹤哪個(gè)系統(tǒng)調(diào)用,SYS_name是來(lái)自kernel/syscall.h的一個(gè)系統(tǒng)調(diào)用號(hào),mask可以等于1 << SYS_name | 1 << SYS_other_name

  3. 如果在輸入命令時(shí)使用trace <mask>,則在使用指定系統(tǒng)調(diào)用后應(yīng)該返回一行包括進(jìn)程id、系統(tǒng)調(diào)用名稱和返回值的打印信息

  4. trace要求能夠跟蹤進(jìn)程以及進(jìn)程派生出的子進(jìn)程,且不影響其他進(jìn)程

實(shí)驗(yàn)提示

  1. user/user.huser/usys.pl、kernel/syscall.h添加系統(tǒng)調(diào)用以及編號(hào)

  2. kernel/sysproc.c添加一個(gè)sys_trace函數(shù)實(shí)現(xiàn)新的系統(tǒng)調(diào)用,并在狀態(tài)結(jié)構(gòu)體proc中插入一個(gè)新的變量(對(duì)該進(jìn)程進(jìn)行跟蹤的mask掩碼),系統(tǒng)調(diào)用的執(zhí)行函數(shù)參考kernel/sysproc.c

  3. 此外需要對(duì)kernel/proc.cfork函數(shù)進(jìn)行修改,因?yàn)檎{(diào)用了trace系統(tǒng)調(diào)用,會(huì)在當(dāng)前進(jìn)程狀態(tài)proc(在kernel/proc.h中)中修改mask掩碼的設(shè)置,同時(shí)每次fork時(shí)也需要對(duì)相關(guān)的子進(jìn)程同步相關(guān)的設(shè)置

  4. 需要修改kernel/syscall.c下的syscall使其打印追蹤信息;為了打印系統(tǒng)調(diào)用名稱,需要額外創(chuàng)建字符串?dāng)?shù)組

實(shí)驗(yàn)代碼

  1. user/user.h中添加int trace(int);的聲明(trace接受一個(gè)整型的參數(shù)mask

  2. user/usys.pl中添加entry("trace");,這是進(jìn)入內(nèi)核態(tài)的入口

  3. Makefile中的UPROGS添加_trace

  4. 進(jìn)入內(nèi)核態(tài),在kernel/syscall.h添加系統(tǒng)調(diào)用的編號(hào)#define SYS_trace 22

  5. kernel/syscall.c中添加系統(tǒng)調(diào)用的映射extern uint64 sys_trace(void);[SYS_trace] sys_trace

  6. kernel/proc.h中的proc中添加int mask

  7. kernel/sysproc.c中添加進(jìn)入系統(tǒng)調(diào)用的函數(shù)

uint64
sys_trace(void){   // 參考sys_wait函數(shù)
  uint64 p;
  if(argaddr(0, &p) < 0)   // 獲取trace的參數(shù)(只有一個(gè))
    return -1;    
  return trace(p);  // 系統(tǒng)調(diào)用的執(zhí)行函數(shù)
}
  1. kernel/proc.c 實(shí)現(xiàn) trace 的系統(tǒng)調(diào)用執(zhí)行函數(shù)(僅僅是進(jìn)行一個(gè)掩碼的賦值)
int 
trace(int mask){
  struct proc *p = myproc();
  p->mask = mask;     // 將掩碼賦值給結(jié)構(gòu)體的mask 
  return 0;
}
  1. kernel/defs.h(這個(gè)里面包含了 kernel 中常用函數(shù)的原型聲明)中加入函數(shù)的聲明 int trace(int)
  2. kernel/proc.c 中的 fork 函數(shù)中加一行代碼 np->mask = p->mask;,將父進(jìn)程的 mask 賦值給子進(jìn)程的 mask
  3. kernel/syscall.c 中對(duì) syscall 進(jìn)行修改,打印追蹤信息;并且為了打印系統(tǒng)調(diào)用的名稱,創(chuàng)建一個(gè)字符串?dāng)?shù)組
char 
*sys_name[] = {
"",      "fork",  "exit",   "wait",   "pipe",  "read",  "kill",   "exec",
"fstat", "chdir", "dup",    "getpid", "sbrk",  "sleep", "uptime", "open",
"write", "mknod", "unlink", "link",   "mkdir", "close", "trace"
};   

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

  num = p->trapframe->a7;
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
    p->trapframe->a0 = syscalls[num]();  // 返回值
    if(p->mask >> num & 1){   // 判斷是否有mask輸入
      // 打印進(jìn)程id、系統(tǒng)調(diào)用的名稱和返回值
      printf("%d: syscall %s -> %d", p->pid, sys_name[num], p->trapframe->a0);   // 這里注意使用的prinrf是因?yàn)閤v6的kernel中專(zhuān)門(mén)定義了一個(gè)printf的函數(shù),在Linux內(nèi)核中只能使用prinrk打印
    }
  } else {
    printf("%d %s: unknown sys call %d\n",
            p->pid, p->name, num);
    p->trapframe->a0 = -1;
  }
}

p->mask >> num & 1:p->mask 為 1<<SYS_read,num 為從 a7 寄存器中讀出來(lái)的 SYS_read,p->mask >> num 能夠?qū)?mask 還原為 SYS_read,如果沒(méi)有 mask,則不打印

實(shí)驗(yàn)感悟

  1. 在閱讀源碼的過(guò)程中,看到有些地方涉及到匯編語(yǔ)言,之后要把這塊給學(xué)習(xí)一下,要不然很影響閱讀體驗(yàn)
  2. 雖然按照系統(tǒng)調(diào)用的步驟能把整個(gè)流程走下來(lái),但是每個(gè)函數(shù)以及它們之間的關(guān)系實(shí)際上還沒(méi)有特別清楚,需要再進(jìn)行梳理(將每個(gè)函數(shù)的作用都搞清楚)
  3. 在進(jìn)行 proc 修改的時(shí)候,要考慮到 fork 函數(shù)的子進(jìn)程是否需要復(fù)制參數(shù)

Part2: Sysinfo

實(shí)現(xiàn)功能

  1. 添加一個(gè)系統(tǒng)調(diào)用 sysinfo,通過(guò)系統(tǒng)調(diào)用將收集正在運(yùn)行的程序的信息
  2. 在這個(gè)系統(tǒng)調(diào)用中將傳入一個(gè)結(jié)構(gòu)體指針 sysinfo,結(jié)構(gòu)體定義在 kernel/sysinfo.h 中,其中 freemem 應(yīng)該設(shè)置為空閑內(nèi)存的字節(jié)數(shù),nproc 應(yīng)該設(shè)置為進(jìn)程狀態(tài)不為 UNUSED 的進(jìn)程數(shù)

實(shí)驗(yàn)提示

  1. user/user.h 中聲明 sysinfo() 的原型,你需要預(yù)先聲明結(jié)構(gòu)體 sysinfo 的存在:struct sysinfo;、int sysinfo(struct sysinfo *);
  2. sysinfo 需要將 struct sysinfo 復(fù)制回用戶空間;參考 sys_fstat() (kernel/sysfile.c)filestat() (kernel/file.c) 學(xué)習(xí)使用 copyout()
  3. 要收集空閑內(nèi)存量,可以在 kernel/kalloc.c 中添加一個(gè)函數(shù)
  4. 要收集進(jìn)程數(shù),請(qǐng)?jiān)?kernel/proc.c 中添加一個(gè)函數(shù)

實(shí)驗(yàn)代碼

  1. user/user.h 添加 sysinfo 結(jié)構(gòu)體和函數(shù)的聲明 struct sysinfo;、int sysinfo(struct sysinfo *);
  2. 分別在 user/usys.plMakefile、kernel/syscall.hkernel/syscall.c 執(zhí)行與上一個(gè)實(shí)驗(yàn)一樣的步驟
  3. kernel/kalloc.c 中實(shí)現(xiàn)空閑內(nèi)存大小的查找
uint64 
getfreemen(void){    // 獲取空閑內(nèi)存數(shù)量
  struct run *rp;
  uint64 result = 0;
  acquire(&kmem.lock);  // 考慮到并發(fā)問(wèn)題,上鎖
  rp = kmem.freelist;
  while(rp){
    result += 1;
    rp = rp->next;
  }
  release(&kmem.lock);
  return result * PGSIZE;   //一個(gè)內(nèi)存頁(yè)的大小為PGSIZE(4096)
}
  1. kernel/proc.c 中實(shí)現(xiàn)進(jìn)程數(shù)的統(tǒng)計(jì)
int 
getproc(void){
  struct proc *p;
  int result = 0;
  for(p = proc; p < &proc[NPROC]; p++){
    acquire(&p->lock);   //上鎖
    if(p->state != UNUSED){
      result += 1;
    }
    release(&p->lock);
  }
  return result;
}

上述兩個(gè)步驟都需要在 kernel/defs.h 中添加函數(shù)聲明文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-856345.html

  1. kernel/sysproc.c 中實(shí)現(xiàn)執(zhí)行函數(shù) sys_sysinfo 的功能,記得添加 #include "sysinfo.h" 來(lái)使用 sysinfo 結(jié)構(gòu)體
uint64   
sys_sysinfo(void){   
  struct sysinfo info;
  struct proc *p;
  uint64 addr;
  if(argaddr(0, &addr) < 0)    // 獲取系統(tǒng)的指針參數(shù)
    return -1;
  p = myproc();
  info.freemem = getfreemen();
  info.nproc = getproc();
  // 從內(nèi)核copy到用戶
  if(copyout(p->pagetable, addr, (char *)&info, sizeof(info)) < 0)  //參考sys_fstat(在kernel/sysfile.c中)
    return -1;                
  return 0;
}

實(shí)驗(yàn)感悟

  1. 這個(gè)實(shí)驗(yàn)實(shí)現(xiàn)的內(nèi)存大小和進(jìn)程數(shù)的統(tǒng)計(jì)函數(shù)需要了解了 kalloc.c 和 proc.c 的函數(shù)后才能寫(xiě)出來(lái),我兩個(gè)文件看的還不太完全,之后需要再看看
  2. 這個(gè)實(shí)驗(yàn)中也使用了指針,這一塊使用還不太熟練,C 語(yǔ)言還需要精進(jìn)

到了這里,關(guān)于MIT6.S081 - Lab2: system calls的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • MIT6.S081學(xué)習(xí)筆記--lec 1

    MIT6.S081學(xué)習(xí)筆記--lec 1

    abstract H/W 抽象化硬件 multiplex 多路復(fù)用 isolation 隔離性 sharing 共享(進(jìn)程通信,數(shù)據(jù)共享) security / access control 安全性/權(quán)限控制 performance 性能/內(nèi)核開(kāi)銷(xiāo) range of applications 多應(yīng)用場(chǎng)景 操作系統(tǒng)應(yīng)該提供的功能:1. 多進(jìn)程支持 2. 進(jìn)程間隔離 3. 受控制的進(jìn)程間通信 xv6 :一種在本

    2024年02月16日
    瀏覽(19)
  • MIT6.S081 - Lecture1: Introduction and Examples

    MIT6.S081 - Lecture1: Introduction and Examples

    理解操作系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn) 通過(guò) XV6 操作系統(tǒng)動(dòng)手實(shí)驗(yàn),可以擴(kuò)展或改進(jìn)操作系統(tǒng) Abstraction: 對(duì)硬件進(jìn)行抽象 Multiplex: 在多個(gè)應(yīng)用程序之間共用硬件資源 Isolation: 隔離性,程序出現(xiàn)故障時(shí),不同程序之間不能相互干擾 Sharing: 實(shí)現(xiàn)共享,如數(shù)據(jù)交互或協(xié)同完成任務(wù) Securi

    2024年04月15日
    瀏覽(21)
  • mit6.828 - lab5筆記(上)

    unix的文件系統(tǒng)相關(guān)知識(shí) unix將可用的磁盤(pán)空間劃分為兩種主要類(lèi)型的區(qū)域: inode區(qū)域 和 數(shù)據(jù)區(qū)域 。 unix為每個(gè)文件分配一個(gè)inode,其中保存文件的 關(guān)鍵元數(shù)據(jù) ,如文件的stat屬性和指向文件數(shù)據(jù)塊的指針。 數(shù)據(jù)區(qū)域中的空間會(huì)被分成大小相同的數(shù)據(jù)塊(就像內(nèi)存管理中的分

    2024年02月02日
    瀏覽(46)
  • mit s0681 lab2 Trace系統(tǒng)調(diào)用實(shí)現(xiàn)

    mit s0681 lab2 Trace系統(tǒng)調(diào)用實(shí)現(xiàn)

    實(shí)驗(yàn)一 實(shí)現(xiàn)一個(gè)用戶級(jí)別的程序,功能為,指定系統(tǒng)調(diào)用后,跟蹤程序的系統(tǒng)調(diào)用情況 分析實(shí)驗(yàn) 實(shí)驗(yàn)?zāi)繕?biāo)為實(shí)現(xiàn)一個(gè)程序去跟蹤指定程序的系統(tǒng)調(diào)用。因此目標(biāo)有兩個(gè) 實(shí)現(xiàn)一個(gè)程序 跟蹤目標(biāo)程序的系統(tǒng)調(diào)用 實(shí)現(xiàn)1,就需要在用戶這邊實(shí)現(xiàn)一個(gè)trace的相關(guān)程序,接收監(jiān)控的

    2024年02月11日
    瀏覽(19)
  • MIT 6.S081 Lab Three

    MIT 6.S081 Lab Three

    本文為 MIT 6.S081 2020 操作系統(tǒng) 實(shí)驗(yàn)三解析。 MIT 6.S081課程前置基礎(chǔ)參考: 基于RISC-V搭建操作系統(tǒng)系列 在本實(shí)驗(yàn)中,您將探索頁(yè)表并對(duì)其進(jìn)行修改,以簡(jiǎn)化將數(shù)據(jù)從用戶空間復(fù)制到內(nèi)核空間的函數(shù)。 開(kāi)始編碼之前,請(qǐng)閱讀xv6手冊(cè)的第3章和相關(guān)文件: * kernel/memlayout.h* ,它捕獲了

    2024年02月09日
    瀏覽(20)
  • MIT6.828/6.S081 Mac OS下搭建xv6和risc-v

    MIT6.828/6.S081 Mac OS下搭建xv6和risc-v

    題外話: 其實(shí)我是一名非計(jì)算機(jī)專(zhuān)業(yè)的在校生,因?yàn)閷?duì)軟件開(kāi)發(fā)和服務(wù)器開(kāi)發(fā)很感興趣,并且這方面的就業(yè)相對(duì)我來(lái)說(shuō)資源比較充沛,所以就學(xué)習(xí)了mit6.828的實(shí)驗(yàn) 課程的學(xué)習(xí)直接跟著官網(wǎng)的schedule走就行,先看Lecture下提供的講義和手冊(cè),然后完成相應(yīng)的Lab,Lab共計(jì)10個(gè),主要

    2024年03月09日
    瀏覽(23)
  • 【MIT 6.S081】Lab7: Multithreading

    本Lab比較簡(jiǎn)單,就是為xv6添加一個(gè)用戶級(jí)的多線程功能,然后熟悉一下Linux下多線程編程。 筆者用時(shí)約2h 這一部分的代碼不涉及內(nèi)核代碼,所以也比較簡(jiǎn)單,根據(jù)提示修改 user/uthread.c 中的代碼即可。仿照內(nèi)核中進(jìn)程轉(zhuǎn)換函數(shù) swtch 的實(shí)現(xiàn)即可。首先,添加一個(gè) context 上下文結(jié)

    2023年04月09日
    瀏覽(28)
  • MIT6.5830 Lab1-GoDB實(shí)驗(yàn)記錄(四)

    標(biāo)簽:Golang 讀寫(xiě)緩沖區(qū)我是一點(diǎn)思路都沒(méi)有,所以得單獨(dú)開(kāi)篇文章記錄。 實(shí)驗(yàn)補(bǔ)充 了解buffer、序列化與反序列化 這里的序列化,簡(jiǎn)單來(lái)說(shuō)類(lèi)似于把一個(gè)很長(zhǎng)的字符串拆成一個(gè)個(gè)字符;反序列化就是把這一個(gè)個(gè)字符拼回成完整的字符串。此處我們需要根據(jù)所給的Tuple,轉(zhuǎn)換為

    2024年02月06日
    瀏覽(19)
  • MIT6.5830 Lab1-GoDB實(shí)驗(yàn)記錄(五)

    完成了Exercise 1,還有四個(gè)Exercise在等著我,慢慢來(lái)吧。 實(shí)驗(yàn)準(zhǔn)備 了解緩沖池 緩沖池,俗稱BP。相關(guān)的概念還有數(shù)據(jù)頁(yè)和緩存頁(yè)。頁(yè)(Pages)的概念和操作系統(tǒng)中“分頁(yè)”的概念是一樣的,指的都是把邏輯地址空間分為若干同等大小的頁(yè),并從0開(kāi)始編號(hào)。 而緩沖池(Buffer Po

    2024年02月05日
    瀏覽(23)
  • 「實(shí)驗(yàn)記錄」MIT 6.824 Raft Lab2C Persist

    MIT-6.824 2020 課程官網(wǎng) Lab2: Raft 實(shí)驗(yàn)主頁(yè) simviso 精品付費(fèi)翻譯 MIT 6.824 課程 Paper - Raft extended version source code 的 Gitee 地址 Lab2C: Persist 的 Gitee 地址 課程官網(wǎng)提供的 Lab 代碼下載地址,我沒(méi)有訪問(wèn)成功,于是我從 Github 其他用戶那里 clone 到干凈的源碼,有需要可以訪問(wèn)我的 Gitee 獲取

    2024年02月08日
    瀏覽(44)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包