系統調用 -- 哈工大李治軍操做系統實驗2

 
 
實驗環境是 實驗樓的 地址 https://www.shiyanlou.com/courses/115
 
 
首先解壓oslab下的壓縮包 執行 tar zxvf +壓縮包名字
 
1.首先修改oslab/linux-0.11/include下的linux文件
 
  添加兩個extern:
extern int sys_iaml
extern int sys_whoami

  添加sys_call_table表項:java

sys_iam,sys_whoami

  

注:fn_ptr是函數類型指針
在include/linux/sched.h中定義
typedef int (fn_ptr*)();

  sys_call_table是中斷服務程序調用系統調用要查的表。表項是函數指針,長度爲4字節。中斷服務程序執行call來調用系統調用:linux

call _sys_call_table(,%eax,4) //a(,%eax,4)=a+4*eax , 每一個表項4字節因此第i個系統調用的偏移是i*4

  2.linux-0.11/kernel下的system_call.s,將nr_system_calls修改成74(添加了兩個系統調用)vim

3.修改kernel下的makefile文件,修改兩處
     1)添加who.o

     2)添加一行函數

 

who.s who.o: who.c ../include/linux/kernel.h ../include/unistd.h

//圖錯了!!!!
//圖中who.o後面少了個冒號!!!!

  

4.系統調用編號使用的宏定義,例如在unistd.g中 :.net

 

#define NR_CLOSE 6   //close是sys_call_table第7個

  添加系統調用須要修改unistd.h文件,不能直接在機器中修改而是在虛擬機文件系統中修改指針

 

oslab下的hdc-0.11-new.img是0.11內核啓動後的根文件系統鏡像文件,至關於在bochs虛擬機裏裝載的硬盤。在Ubuntu上訪問其內容的方法是
$ sudo ./mount-hdc
以後,hdc目錄下就是和0.11內核如出一轍的文件系統了,能夠讀寫任何文件(可能有些文件要用sudo才能訪問),卸載這個文件系統:
$ sudo umount hdc
 
因此切換到oslab目錄下執行sudo ./mount-hdc,而後切換到hdc下就會看到和linux同樣的文件目錄結構了。
 
切換到hdc/usr/include下,vim unistd.h
Tip:
1.命令模式下/__NR ---->命令模式下  /+要查找的字符能夠快速定位,n是下一個,N是上一個
2.'  __NR  '的_是shift加-,這裏有兩個'_'

  而後添加:code

 

#define __NR_iam 72
#define __NR_whoami  73

  

而後在linux-0.11/kernel下添加who.c,包含兩個 系統調用blog

 

#define __LIBRARY__
#include <unistd.h>
#include <errno.h>
#include <asm/segment.h> char temp[64]={0}; int sys_iam(const char* name) { int i=0; while(get_fs_byte(name+i)!='\0') i++; if(i>23){ return -EINVAL; } printk("%d\n",i); i=0; while((temp[i]=get_fs_byte(name+i))!='\0'){ i++; } return i; }
int sys_whoami(char* name,unsigned int size) { int i=0; while (temp[i]!='\0') i++; if (size<i) return -1; i=0; while(temp[i]!='\0'){ put_fs_byte(temp[i],(name+i)); i++; } return i; }

  

5.而後編寫iam.c和whoami.c 放在 hdc下的任意位置
     1)whoami.c:

 

     2)iam.cip

 

而後執行  sudo umount hdc 解除掛載

 

最後切換到oslab下執行make
切換到oslab下執行./run運行虛擬機
切換到iam.c和whoami.c的目錄執行
gcc iam.c -o iam
gcc whoami.c -o whoami

  

總結:
 

 

main將eax寄存器置72(系統調用編號),觸發int 0x80中斷 (實際是在庫函數中作的)
 
int 0x80指令查IDT表(中斷向量表,由內核初始化)發現DPL=3 ,而CPL = 3(用戶態)能夠執行
 
因而將這個IDT表項的段選擇子CS  給CS寄存器(例如段選擇子爲8H=1000,後兩位爲CPL,特權級別CPL置0),入口函數偏移給IP寄存器
 
而後執行中斷服務程序,中斷服務程序調用sys_whoami
 
sys_whoami裏此時能夠訪問內核態數據(訪問100地址的數據)
相關文章
相關標籤/搜索