1. 程式人生 > >哈工大作業系統試驗2 系統呼叫

哈工大作業系統試驗2 系統呼叫

由於一時疏忽,導致who.c的程式碼不能通過部分測試資料,現已經改正。

今天整理了一下實驗報告

在unistd.h中可以看到現在Linux 0.11 支援3個引數的傳遞。新增引數的方法大概有3條

               1.可以採用ESI,EDI,EBP,ESP這幾個暫存器傳遞引數。

               2.可以採用《Linux 0.11註釋》中提到的系統呼叫門的辦法。

               3.可以開闢一塊使用者態的空間,允許核心態訪問,傳遞引數時,只需傳遞此空間的首地址指標即可。

向linux 0.11新增一個系統呼叫foo()的步驟:

               首先。在核心中編寫系統呼叫處理函式。
              其次。在include/unistd.h中新增系統呼叫的功能號(#define   __NR_foo   **)
                        並且相應的在include/linux/sys.h中宣告新的系統呼叫處理函式以及新增系統
                        呼叫處理程式指標陣列表中該項的索引值。在make file中新增新系統呼叫所在
                        檔案的編譯、連結規則(依賴關係)。修改system_call.s中系統呼叫總數。
              最後。在應用程式中提供介面,呼叫系統呼叫。

這次試驗,需要用c來寫,比上次要簡單一些。

需要改寫unistd.h       sys.h           system_call.s     makefile  4個檔案

而且需要自己寫出 who.c   iam.c    whoami.c   3個檔案

sys.h在     linux-0.11/include/linux  之中,原始檔關鍵處如下

extern int sys_ssetmask();
extern int sys_setreuid();
extern int sys_setregid();

fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
sys_setreuid,sys_setregid };

只需要把 iam與whoami兩個函式加到全域性變數,和中斷函式表中就可以了,中斷被呼叫的時候,先查詢中斷向量表,

找到相應的函式名,呼叫其函式。

extern int sys_ssetmask();
extern int sys_setreuid();
extern int sys_setregid();
extern int sys_iam();
extern int sys_whoami();

fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
sys_setreuid,sys_setregid,sys_iam,sys_whoami };
system_call.s 在    linux-0.11/kernel 中
# offsets within sigaction
sa_handler = 0
sa_mask = 4
sa_flags = 8
sa_restorer = 12

nr_system_calls = 72
只需要把   nr_system_calls 改為 74 就好 ,其代表了中斷函式的個數。修改後是這樣。
# offsets within sigaction
sa_handler = 0
sa_mask = 4
sa_flags = 8
sa_restorer = 12

nr_system_calls = 74

Makefile  試驗指導書上講得很詳細

修改Makefile

要想讓我們新增的kernel/who.c可以和其它Linux程式碼編譯連結到一起,必須要修改Makefile檔案。Makefile裡記錄的是所有源程式檔案的編譯、連結規則,《註釋》3.6節有簡略介紹。我們之所以簡單地執行make就可以編譯整個程式碼樹,是因為make完全按照Makefile裡的指示工作。

Makefile在程式碼樹中有很多,分別負責不同模組的編譯工作。我們要修改的是kernel/Makefile。需要修改兩處。一處是:

OBJS  = sched.o system_call.o traps.o asm.o fork.o \
        panic.o printk.o vsprintf.o sys.o exit.o \
        signal.o mktime.o

改為:

OBJS  = sched.o system_call.o traps.o asm.o fork.o \
        panic.o printk.o vsprintf.o sys.o exit.o \
        signal.o mktime.o who.o

另一處:

### Dependencies:
exit.s exit.o: exit.c ../include/errno.h ../include/signal.h \
  ../include/sys/types.h ../include/sys/wait.h ../include/linux/sched.h \
  ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \
  ../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \
  ../include/asm/segment.h

改為:

### Dependencies:
who.s who.o: who.c ../include/linux/kernel.h ../include/unistd.h
exit.s exit.o: exit.c ../include/errno.h ../include/signal.h \
  ../include/sys/types.h ../include/sys/wait.h ../include/linux/sched.h \
  ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \
  ../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \
  ../include/asm/segment.h

Makefile修改後,和往常一樣“make all”就能自動把who.c加入到核心中了。如果編譯時提示who.c有錯誤,就說明修改生效了。所以,有意或無意地製造一兩個錯誤也不完全是壞事,至少能證明Makefile是對的。

unistd.h 不能直接在oslab直接直接修改,而需要在虛擬機器中修改,在oslab中有一個mount-hdc指令碼

執行sudo ./mount-hdc 可以把虛擬機器硬碟掛載在oslab/hdc 目錄下。

在hdc/usr/include 目錄下修改unistd.h 

關鍵原始碼為

#define __NR_ssetmask	69
#define __NR_setreuid	70
#define __NR_setregid	71
只需要把兩個自定義函式的巨集定義在這裡就好。

修改後為

#define __NR_ssetmask	69
#define __NR_setreuid	70
#define __NR_setregid	71
#define __NR_iam   72
#define __NR_whoami  73

這樣修改工作就完成了成了

who.c 的程式碼如下

#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;
}
寫完後吧 who.c 放到linux-0.01/kernel   目錄下   執行make all    who.c 就會被編譯到核心裡了

iam.c 與 whoami.c 兩個檔案是測試用的,可以在本地寫好,通過掛載的hdc傳到linux下,也可以通過vi在linux下寫好(如果你蛋疼的話)

一定要在linux 執行編譯 ,然後執行sync確保緩衝區資料寫入磁碟就可以了。

程式碼如下 

iam.c

#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
_syscall1(int,iam,const char*,name)

int main(int argc,char* argv[])
{
	
    if(argc>1){
	if(iam(argv[1])<0){
		printf("SystemCall Exception!\n");
		return -1;
	}
    }
    else{
	printf("Input Exception!\n");
	return -1;
    }		
    return 0;
}

whoami.c
#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

_syscall2(int,whoami,char*,name,unsigned int,size)

int main()
{
    int counter;
	char buff[128]={0};
	
    counter=whoami(buff,128);
	if(counter < 0)
	{
	   printf("SystemCall Exception!");
	   return -1;
    	}
	else{
		printf("%s\n",buff);
    	}
    return 0;
}

最後需要用指令碼測試一下,程式的正確性,把指令碼放到iam.c   whoami.c同目錄下 執行就好

指令碼程式碼如下

經過分析它不會檢查你的的  erron是不是正確,只會檢查whoami返回的的字串正不正確。

最後一個數據很陰險,注意字串過長的時候,不要覆蓋之前儲存的字串,就是說所儲存的字串是之前存的字串就好。

#/bin/sh

string1="Sunner"
string2="Richard Stallman"
string3="This is a very very long string!"

score1=10
score2=10
score3=10

expected1="Sunner"
expected2="Richard Stallman"
expected3="Richard Stallman"

echo Testing string:$string1
./iam "$string1"
result=`./whoami`
if [ "$result" = "$expected1" ]; then
	echo PASS.
else
	score1=0
	echo FAILED.
fi
score=$score1

echo Testing string:$string2
./iam "$string2"
result=`./whoami`
if [ "$result" = "$expected2" ]; then
	echo PASS.
else
	score2=0
	echo FAILED.
fi
score=$score+$score2

echo Testing string:$string3
./iam "$string3"
result=`./whoami`
if [ "$result" = "$expected3" ]; then
	echo PASS.
else
	score3=0
	echo FAILED.
fi
score=$score+$score3

let "totalscore=$score"
echo Score: $score = $totalscore%

另外一個測試程式testlab2.c會檢查你的返回值是否正確。


相關推薦

哈工大作業系統試驗2 系統呼叫

由於一時疏忽,導致who.c的程式碼不能通過部分測試資料,現已經改正。 今天整理了一下實驗報告 在unistd.h中可以看到現在Linux 0.11 支援3個引數的傳遞。新增引數的方法大概有3條                1.可以採用ESI,EDI,EBP,ESP這幾

作業系統實驗——增加系統呼叫(詳細圖文解釋)

Linux新增系統呼叫 注意:請提前安裝好Vmware,並準備好Ubuntu映象檔案以及Linux核心(我用的是Ubuntu10.0.4版本,核心版本是Linux-2.6.32.65.xz) 操作步驟: 1.點選建立一個新的虛擬機器 1)選擇自定義,點選下一步,接下來選擇預設配置,進入虛擬機器嚮導 2

作業系統基礎之系統呼叫

1.使用者態和核心態 使用者程式是如何呼叫核心程式的呢?考慮實現下面的一個whoami的系統呼叫: 在核心中100地址處有一個使用者“lizhijun”,whoami函式的功能是要打印出這個使用者名稱,那可以直接打印出100地址處的內容嗎?答案當然是否定

作業系統實驗之系統呼叫

1。今天整理了一下實驗報告 在unistd.h中可以看到現在Linux 0.11 支援3個引數的傳遞。新增引數的方法大概有3條 1.可以採用ESI,EDI,EBP,ESP這幾個暫存器傳遞引數。 2.可以採用《Lin

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

.net pre ron 例如 中修改 TP segment val 命令 實驗環境是 實驗樓的 地址https://www.shiyanlou.com/courses/115 參考博客:https://blog.csdn.net/wangyi_lin/arti

作業系統實驗一:linux核心編譯及新增系統呼叫

編譯環境 VMWare Ubuntu Desktop Ubuntu 18.04.1映象下載地址:點我下載 裝ubuntu很簡單,網上教程一大堆,記憶體分配多點。 新增系統呼叫步驟 解壓linux核心 想辦法,把上面的linux核心弄到ubuntu裡面,可

作業系統課程設計(一):linux核心編譯及新增系統呼叫

1.實驗目的 通過實驗,熟悉Linux作業系統的使用,掌握構建與啟動Linux核心的方法;掌握使用者程式如何利用系統呼叫與作業系統核心實現通訊的方法,加深對系統呼叫機制的理解;進一步掌握如何向作業系統核心增加新的系統呼叫的方法,以擴充套件作業系統的功能。 2.實

哈工大LTP:Windows系統Python本地呼叫

本文實驗環境為64位win10系統,python3.6.2,LTP專案檔案和模型檔案使用的3.3.1版本 1.LTP下載 (1)LTP專案檔案ltp-3.3.1-win-x86.zip(下載連結) (2)LTP模型檔案3.3.1(下載連結) Windows系統直接下載

android4.2系統,實現應用層呼叫乙太網/3G網絡卡

        android開發的SDK中,沒有提供3G網絡卡和乙太網的操作方法,但是有些裝置(包括平板和手機)可以在設定中開啟“乙太網”功能,就可以利用usb介面轉網線,或者3G網絡卡連線上網。也就是說系統中提供了Ethern

現代作業系統學習筆記——核心態與使用者態、系統呼叫

本文為學習《現代作業系統》時遇到的疑問,為網上查詢資料的總和。核心態與使用者態作業系統需要CPU的兩種狀態,即核心態與使用者態,兩種狀態的不同主要體現在所能使用的指令範圍上。核心態:可以執行任何指令,對所有硬體具有完全訪問權,作業系統就執行在核心態。使用者態:只能使用計算機指

Linux open系統呼叫流程(2)

1. 書結上文,繼續分析do_filp_open函式,其傳入4個引數: dfd:相對目錄 tmp:檔案路徑名,例如要開啟/usr/src/kernels/linux-2.6.30 flags:開啟標誌 mode:開啟模式 /* * Note that while the

Linux編譯核心(4.2.6)並新增系統呼叫

1. 檢視系統核心版本(ubuntu 12.04) uname –a 或者 cat /proc/version 將壓縮包linux-4.2.6.tar.gz 放至 /usr/src中後解壓: sudo cp linux-4.2.6.tar.gz /usr/src

作業系統實驗一(核心編譯,系統呼叫)

作業系統實驗一 ——-系統呼叫 注:  實驗前的準備工作就不一一敘述了。 Ubuntu執行環境:mac osx10.9.1 +VMware Fusion 6.0.2 Ubuntu 版本: 12.10   64位 具體實驗流程如下: 1.安裝有關編譯程式。(這是第二次重

Linux核心2.6.34.14新增系統呼叫及編譯方法(CentOS-6.4-x86_64)

<?xml version="1.0" encoding="UTF-8"?> //我新增系統呼叫步驟,僅供參考,尤其是系統呼叫的實現部分,建議大家自己寫,除了我這種好像還可以用sys_open系列來寫 #define 核心版本 linux-2.6.34.14

作業系統中最基本的概念——庫呼叫系統呼叫

Unix作業系統設計上的陳述: 理解庫函式的區別和系統呼叫,首先要裡理解Unix的kernel mode和user mode。考慮下面的函式段: int main() {     int fd = create("filename",0666);     exit(0);

作業系統作業:給linux系統增加一個系統呼叫

前不久開了一門《作業系統》,老師上課留下了一個作業——給Linux系統新增一個系統呼叫。剛開始只能用一臉懵逼來形容,只能硬著頭皮做下去。由於剛的新電腦,所以就沒敢裝雙系統。所以我選擇了虛擬機器,虛擬機器剛開始配置的過程不算特別複雜,網上也有很多教程,於是我看著虛擬機器也是一臉懵逼,不知道從何下手,百度得知快捷

《Linux作業系統分析》之使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫

本篇文章分析的是使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫,來說明在Linux系統中,系統呼叫的實現機制。 相關知識 首先關於這篇文章會介紹一些用到的知識。 一、什麼是核心態,什麼又是使用者態。 核心態:在高執行級別下,程式碼可以執行特權指令,

《Linux作業系統分析》之分析系統呼叫system_call的處理過程

本篇文章通過將上篇文章中使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式設計的系統呼叫新增到系統menu中,來說明在Linux系統中,系統呼叫的實現的時機以及具體執行,以及一般的中斷處理過程。 相關知識 首先關於這篇文章會介紹一些用到的知識。 一、將系統呼叫號與相應的服務

Windows核心情景分析-系統呼叫2

x86後來加入的快速系統呼叫硬體支援,windows則也跟著做了改動,此時如果cpu支援sysenter,則會採用快速系統呼叫的系統呼叫形式。  快速系統呼叫 sysenter 形式的系統呼叫例項 此時工具生成的NtReadFile為: 此時與int 0

我是如何學習寫一個作業系統(四):作業系統系統呼叫

前言 最近有點事情,馬上要開學了,所以學習的腳步就慢下來了。這一篇主要是來說作業系統的系統呼叫的,像C語言的printf深入到內部就是一個有關螢幕輸出的系統呼叫 什麼是系統呼叫 之前提過作業系統是對硬體的抽象,也是軟硬體之間的一層。之前比如如果我們想要在螢幕上輸出一些字元,就需要一些指令操作,然後把資料放到視