您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 这次作业的目标是修改linux的kernel
OSHomework29117020王繼偉一、目的這次作業的目標是修改linux的kernel,由我們自行新增systemcall,來操作一個printflag的開與關。並修改scheduler,在每次進行contextswitch的時候,會去檢查這個flag,如果這個flag被打開了的話,就去把剛剛正在進行的process的pid和processname印出來,否則的話就不印。然後另外寫一支userprogram,透過新增的systemcall,把這個flag打開10秒鐘後再關閉。如此一來,在flag被打開的十秒鐘內,scheduler便會在進行contextswitch時,把資訊印出來了。此外,作業還要求要計算在這段時間內,總共進行了幾次contextswitch。二、步驟0.Principle由於printflag必須給scheduler去檢查,又必須給systemcall去操作,所以必須以全域變數的方式宣告。但是要宣告在那裡呢﹖其實那裡都可以,因為是全域變數麻,我的選擇是放在myservices.h裡面。要注意的是,雖然是全域變數,但在編譯的過程中,當scheduler看到flag的時候還沒有經過宣告,所以我們需要以externintprintflag的方式來expose該flag(除非直接把flag宣告在scheduler裡面,但這樣systemcalls也一樣要以extern的方式去expose它)。為了對該flag進行操作,所以我打算新增兩個systemcall:voidsetflag(int)與intgetflag(void)除了printflag這個全域變數之外,因為要得知進行了多少次contextswitch,那一定是在進行contextswitch的scheduler裡面進行累加,而外部的userprogram勢必又要靠systemcall去得知累加的結果。所以我還需要一個全域變數count,以及一個systemcall,去取得count的值:intgetcount(void)因此全部要要增加的東西有三個systemcall以及兩個全域變數。1.Addingsystemcalls:Thefollowingstepsareperformedwithcurrentdirectory:/usr/src/linuxa)addthesethreelinesinarch/i386/kernel/entry.S:.longsys_setflag289.longsys_getflag290.longsys_getcount291b)editinclude/asm/unistd.h,addthesethreelines#define__NR_setflag289#define__NR_getflag290#define__NR_getcount291andedit#defineNR_syscallto292c)editinclude/linux/myservices.h#ifndef__MYSERVICES__#define__MYSERVICES__#includelinux/linkage.hintprintflag,count;#endifd)editkernel/myservices.casmlinkagevoidsys_setflag(intf){printflag=f;}asmlinkageintsys_getflag(void){returnprintflag;}asmlinkageintsys_getcount(void){returncount;}2.Editscheduler:editkernel/sched.ca)inthebeginning,addexternintprintflag;externintcount;b)inthebeginningofschedule(),addstaticintprevflagif(printflag){if(prevflag==0)count=0;printk(“Currentprocess’spid:%d\n”,current-pid);printk(“Currentprocess’sname:%s\n”,current-comm);count++}prevflag=printflag;3.Edituserprogram:#includelinux/unistd.h#includestdlib.h#includestdio.h_syscall0(int,getflag,int);_syscall0(int,getcount);_syscall1(void,setflag,int,f);intmain(){printf(“before:%d”,getflag());setflag(1);printf(“aftersetflag(1):%d”,getflag());sleep(10);setflag(0);printf(“Final:%d”,getflag());printf(“count:%d”,count);return0;}4.rebuildkernelandcompileuserprogram四、心得這次作業讓我了解到systemcall的運作方式與實作方法,對scheduler以及contextswitch的運作也有了一些認識。如果等以後學到更多OS方面的知識,或許可以把systemcall的功能與以加強,扁成類似工作管理的程式。比較麻煩的地方是,sched在計算count時不能單純每次進行contextswitch就把count+1,這樣就違反了”只計算十秒內”的條件,所以我用一個prevflag的staticint,紀錄之前的printflag,當printflag由0變1時(即prevflag=0且printflag=1),代表有人呼叫了setflag(1),這樣sched會把count重設成0,就達到題目要求了。
本文标题:这次作业的目标是修改linux的kernel
链接地址:https://www.777doc.com/doc-648226 .html