




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、課程設(shè)計(jì)報(bào)告 課程名稱:計(jì)算機(jī)操作系統(tǒng) 專業(yè)班級(jí): 信安1302班 學(xué) 號(hào): 姓 名: 指導(dǎo)教師: 報(bào)告日期: 2016.3.13 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院目 錄一、 實(shí)驗(yàn)?zāi)康?二、 實(shí)驗(yàn)環(huán)境1三、 實(shí)驗(yàn)內(nèi)容1四、 設(shè)計(jì)與實(shí)現(xiàn)24.1 實(shí)驗(yàn)一24.1.1 實(shí)驗(yàn)要求24.1.2 設(shè)計(jì)思路24.1.3 具體過(guò)程和結(jié)果34.1.3 源代碼34.2實(shí)驗(yàn)二54.2.1 實(shí)驗(yàn)要求54.2.2 具體實(shí)現(xiàn)54.2.3 源代碼74.3 實(shí)驗(yàn)三84.3.1 實(shí)驗(yàn)要求84.3.2 具體實(shí)現(xiàn)84.3.3 源程序104.4 實(shí)驗(yàn)四134.4.1 實(shí)驗(yàn)要求134.4.2 設(shè)計(jì)思路134.4.3程序效果顯示174.4.4源代碼
2、19五、 實(shí)驗(yàn)總結(jié)321、 實(shí)驗(yàn)?zāi)康?1) 掌握Linux操作系統(tǒng)的使用方法;(2) 了解Linux系統(tǒng)內(nèi)核代碼結(jié)構(gòu);(3) 掌握實(shí)例操作系統(tǒng)的實(shí)現(xiàn)方法。2、 實(shí)驗(yàn)環(huán)境本次課程設(shè)計(jì)采用的操作系統(tǒng)環(huán)境是Ubuntu系統(tǒng),Ubuntu系統(tǒng)版本號(hào)為14.04,內(nèi)核版本號(hào)為linux 3.18.27;采用的編程環(huán)境為gcc編譯器和QtCreator。3、 實(shí)驗(yàn)內(nèi)容實(shí)驗(yàn)一:掌握Linux操作系統(tǒng)的使用方法,包括鍵盤命令、系統(tǒng)調(diào)用;掌握在Linux下的編程環(huán)境。 (1) 編寫一個(gè)C程序,其內(nèi)容為實(shí)現(xiàn)文件拷貝的功能。 (2) 編寫一個(gè)C程序,其內(nèi)容為分窗口同時(shí)顯示三個(gè)并發(fā)進(jìn)程的運(yùn)行結(jié)果。要求用到Linux下
3、的圖形庫(kù)(GTK/Qt)。實(shí)驗(yàn)二:掌握系統(tǒng)調(diào)用的實(shí)現(xiàn)過(guò)程,通過(guò)編譯內(nèi)核方法,增加一個(gè)新的系統(tǒng)調(diào)用。另編寫一個(gè)應(yīng)用程序,使用新增加的系統(tǒng)調(diào)用。(1) 內(nèi)核編譯、生成,用新內(nèi)核啟動(dòng);(2) 新增系統(tǒng)調(diào)用實(shí)現(xiàn):文件拷貝或P、V操作。實(shí)驗(yàn)三:掌握增加設(shè)備驅(qū)動(dòng)程序的方法。通過(guò)模塊方法,增加一個(gè)新的設(shè)備驅(qū)動(dòng)程序,其功能可以簡(jiǎn)單。實(shí)現(xiàn)字符設(shè)備的驅(qū)動(dòng)。實(shí)驗(yàn)四:使用GTK/QT實(shí)現(xiàn)系統(tǒng)監(jiān)控器(1) 了解/proc文件的特點(diǎn)和使用方法;(2) 監(jiān)控系統(tǒng)狀態(tài),顯示系統(tǒng)中若干部件使用情況;(3) 用圖形界面實(shí)現(xiàn)系統(tǒng)監(jiān)控狀態(tài)。4、 設(shè)計(jì)與實(shí)現(xiàn)4.1 實(shí)驗(yàn)一4.1.1 實(shí)驗(yàn)要求掌握Linux操作系統(tǒng)的使用方法,包括鍵盤命
4、令、系統(tǒng)調(diào)用;掌握在Linux下的編程環(huán)境。4.1.2 設(shè)計(jì)思路(1)要求編寫一個(gè)C程序,其內(nèi)容為實(shí)現(xiàn)文件拷貝的功能。在windows操作系統(tǒng)上實(shí)現(xiàn)的文件拷貝功能一般使用fopen、fread、fwrite三個(gè)來(lái)自標(biāo)準(zhǔn)C函數(shù)庫(kù)的函數(shù)執(zhí)行對(duì)文件的打開、讀、寫操作,而本次實(shí)驗(yàn)要求使用Linux系統(tǒng)的系統(tǒng)調(diào)用open、read、write實(shí)現(xiàn)上述三個(gè)操作。用到的主要頭文件如下:stdio.h標(biāo)準(zhǔn)輸入輸出頭文件string.h字符串處理相關(guān)頭文件unistd.hLinux系統(tǒng)調(diào)用頭文件,比如read、writefcntl.h包含open系統(tǒng)調(diào)用errno.h包含一些調(diào)試錯(cuò)誤時(shí)用到的變量具體實(shí)現(xiàn)思路:打
5、開兩個(gè)文件(分別是源文件和目標(biāo)文件,可以是任意字符流形式存儲(chǔ)的文件,包括文本文件、照片等),調(diào)用read函數(shù)讀取源文件的內(nèi)容,將read的返回值作為while循環(huán)的判斷條件,當(dāng)返回值大于0(即還未讀取完畢源文件中的內(nèi)容)時(shí),調(diào)用write執(zhí)行向目標(biāo)文件寫的操作,否則跳出循環(huán),表示源文件已經(jīng)被拷貝到目標(biāo)文件,然后調(diào)用close關(guān)閉源文件和目標(biāo)文件。(2) 編寫一個(gè)C程序,其內(nèi)容為分窗口同時(shí)顯示三個(gè)并發(fā)進(jìn)程的運(yùn)行結(jié)果。要求用到Linux下的圖形庫(kù)(GTK/Qt)。本次實(shí)驗(yàn)使用的圖形庫(kù)是跨平臺(tái)的開發(fā)工具Qt。首先下載Qt的安裝包并安裝。Qt安裝完之后,先新建一個(gè)Qt控制臺(tái)應(yīng)用MAIN作為主進(jìn)程,用于
6、調(diào)用三個(gè)并發(fā)的子進(jìn)程。在主進(jìn)程的main函數(shù)中,使用fork創(chuàng)建三個(gè)子進(jìn)程,若進(jìn)程創(chuàng)建成功(即fork函數(shù)返回值等于0),則使用execv函數(shù)進(jìn)入對(duì)應(yīng)的子進(jìn)程(window1、window2、window3)主進(jìn)程程序編寫完成后,再新建三個(gè)Qt Widgets Application,分別作為三個(gè)子進(jìn)程,三個(gè)窗口顯示了自己的進(jìn)程號(hào)和父進(jìn)程號(hào)。4.1.3 具體過(guò)程和結(jié)果(1) 代碼完成后用保存為.c文件用gcc編譯后./運(yùn)行即可,實(shí)現(xiàn)的功能為復(fù)制文件1.txt為2.txt,如圖4.1、4.2所示:圖 4.1圖 4.2(2) 主進(jìn)程和三個(gè)子進(jìn)程的程序全部編寫完后,直接在Qt上編譯運(yùn)行。程序運(yùn)行結(jié)果
7、如圖4.3所示:圖 4.34.1.3 源代碼#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #define BUFFER_SIZE 1024 /緩沖區(qū)大小int main(int argc,char *argv) int from_fd,to_fd; int bytes_read
8、,bytes_write; char bufferBUFFER_SIZE; /設(shè)定一個(gè)緩沖區(qū) char *ptr; if(argc!=3) /三個(gè)參數(shù) fprintf(stderr,"Usage:%s fromfile tofilena",argv0);return(-1); /*打開源文件*/ if(from_fd=open(argv1,O_RDONLY)=-1) fprintf(stderr,"Open %s Error:%sn",argv1,strerror(errno); return(-1); /* 創(chuàng)建目的文件 */ if(to_fd=ope
9、n(argv2,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)=-1) fprintf(stderr,"Open %s Error:%sn",argv2,strerror(errno); return(-1); while(bytes_read=read(from_fd,buffer,BUFFER_SIZE) /* 出錯(cuò)*/ if(bytes_read=-1)&&(errno!=EINTR) break; else if(bytes_read>0) ptr=buffer; while(bytes_write=write(to_fd,
10、ptr,bytes_read) /* 出錯(cuò)*/ if(bytes_write=-1)&&(errno!=EINTR)break; /* 寫完了所有讀的字節(jié) */else if(bytes_write=bytes_read) break; /* 只寫了一部分,繼續(xù)寫 */ else if(bytes_write>0) ptr+=bytes_write; bytes_read-=bytes_write; /* 寫的時(shí)候出錯(cuò)*/ if(bytes_write=-1)break; close(from_fd); close(to_fd); return(1);4.2實(shí)驗(yàn)二4.2.
11、1 實(shí)驗(yàn)要求掌握系統(tǒng)調(diào)用的實(shí)現(xiàn)過(guò)程,通過(guò)編譯內(nèi)核方法,增加一個(gè)新的系統(tǒng)調(diào)用,另編寫一個(gè)應(yīng)用程序,調(diào)用新增加的系統(tǒng)調(diào)用。4.2.2 具體實(shí)現(xiàn)(1) 系統(tǒng)調(diào)用的原理用戶進(jìn)程不能訪問(wèn)內(nèi)核所占內(nèi)存空間,也不能調(diào)用內(nèi)核函數(shù)。進(jìn)程調(diào)用一個(gè)特殊的指令,這個(gè)指令會(huì)跳到一個(gè)事先定義的內(nèi)核中的一個(gè)位置。在Intel CPU中,由中斷INT 0x80實(shí)現(xiàn)。 (與DOS功能調(diào)用int0x21很相似)跳轉(zhuǎn)到的內(nèi)核位置叫做sysem_call。檢查系統(tǒng)調(diào)用號(hào),這個(gè)號(hào)碼代表進(jìn)程請(qǐng)求哪種服務(wù)。然后,它查看系統(tǒng)調(diào)用表(sys_call_table)找到所調(diào)用的內(nèi)核函數(shù)入口地址。接著,就調(diào)用函數(shù),等返回后,做一些系統(tǒng)檢查,最后返
12、回到進(jìn)程(如果這個(gè)進(jìn)程時(shí)間用盡,就返回到其他進(jìn)程)。(2) 編寫新的系統(tǒng)調(diào)用程序新的系統(tǒng)調(diào)用程序?qū)崿F(xiàn)的功能是:將一個(gè)文件中的內(nèi)容拷貝到另一個(gè)文件中。這個(gè)系統(tǒng)調(diào)用的參數(shù)是兩個(gè)char*型的字符指針SourceFile、GoalFile,分別表示源文件和目標(biāo)文件的路徑名。用戶進(jìn)程中的open、read、write、close函數(shù)此時(shí)對(duì)應(yīng)內(nèi)核函數(shù) sys_open、 sys_read、 sys_write、 sys_close函數(shù)。循環(huán)拷貝的判斷條件還是 sys_read的返回值,當(dāng)其大于0的時(shí)候執(zhí)行循環(huán),否則表示源文件已拷貝到了目標(biāo)文件。 mm_segment_t類型的變量fs的作用是在讀寫文件前
13、得到當(dāng)前fs,避免使用的緩沖區(qū)超過(guò)了用戶空間的地址范圍而報(bào)錯(cuò)。(3) 編譯內(nèi)核下載并解壓內(nèi)核先到Linux官方網(wǎng)站下載內(nèi)核linux-3.18.27.tar.xz。打開終端,使用sudo su獲取root權(quán)限,然后使用cp linux-3.18.27.tar.xz /usr/src命令將linux-3.18.27tar.xz復(fù)制到文件夾/usr/src下,復(fù)制完畢之后將其解壓,用到的命令為:xz -d linux-3.18.27.tar.xz和tar xvf linux-3.18.27.tar。修改內(nèi)核新的內(nèi)核解壓完畢后,使用 cd /usr/src/linux-3.18.27命令進(jìn)入目錄 /
14、usr/src/linux-3.18.27。然后使用命令sudo gedit kernel/sys.c打開sys.c,將新的系統(tǒng)調(diào)用程序復(fù)制到該文件的文件末尾,保存退出,系統(tǒng)調(diào)用程序詳細(xì)代碼見源程序。系統(tǒng)調(diào)用號(hào)。在該文件中添加一行內(nèi)容358 common mycall sys_mycall,其中系統(tǒng)調(diào)用號(hào)359不是固定的,只要該文件中沒(méi)有出現(xiàn)的數(shù)字都可以使用。添加之后保存退出。使用命令sudo gedit include/asm-generic/syscalls.h打開syscalls.h,在“#endif /* _ASM_GENERIC_SYSCALLS_H */ 這一行的上面一行添加新的系
15、統(tǒng)調(diào)用程序的函數(shù)定義,即:#ifndef sys_mycallShrinkage int sys_mycall(char* sourceFile,char* destFile);#endif然后保存退出。#make menuconfig存盤退出,生成內(nèi)核配置文件#make bzImage #make modules#make modules_install重啟電腦選擇高級(jí)選項(xiàng)選擇新內(nèi)核3.18.27進(jìn)入,打開終端輸入unmae -a,如圖4.4表示,表示內(nèi)核已編譯成功:圖 4.4(4) 編寫系統(tǒng)調(diào)用測(cè)試程序需要用到的頭文件是syscall.h、unistd.h、stdlib.h。在main函數(shù)
16、中直接調(diào)用頭文件syscall.h中定義的函數(shù)syscall,該函數(shù)有三個(gè)參數(shù),第一個(gè)參數(shù)是系統(tǒng)調(diào)用號(hào)(358),第二個(gè)參數(shù)是源文件(1.txt),第三個(gè)參數(shù)是目標(biāo)文件。程序運(yùn)行結(jié)果為:在2.c所在目錄下新建了一個(gè)1.txt文件,并將main.c中的代碼拷貝到了2.txt中,如圖4.5所示:圖 4.54.2.3 源代碼(1) 系統(tǒng)調(diào)用程序asmlinkage int sys_mycall(char* SourceFile,char* GoalFile) int source=sys_open(SourceFile,O_RDONLY,0); int goal=sys_open(GoalFile,
17、O_WRONLY|O_CREAT|O_TRUNC,0600); char buff4096; mm_segment_t fs; fs = get_fs(); set_fs(get_ds(); int i; if(source>0 && goal>0) do i=sys_read(source,buff,4096); sys_write(goal,buff,i); while(i); else printk("Error!"); sys_close(source); sys_close(goal); set_fs(fs); return 10;(2
18、) 測(cè)試程序#include <syscall.h>#include <unistd.h>#include <stdlib.h>int main() syscall(359,"1.txt","2.text");return 0;4.3 實(shí)驗(yàn)三4.3.1 實(shí)驗(yàn)要求掌握增加設(shè)備驅(qū)動(dòng)程序的方法。通過(guò)模塊方法,增加一個(gè)新的設(shè)備驅(qū)動(dòng)程序,其功能可以簡(jiǎn)單。(實(shí)現(xiàn)字符設(shè)備的驅(qū)動(dòng))4.3.2 具體實(shí)現(xiàn)(1)Linux核心是一種monolithic類型的內(nèi)核,即單一的大核心,另外一種形式是MicroKernel,核心的所有功能部件都被拆
19、成獨(dú)立部分, 這些部分之間通過(guò)嚴(yán)格的通訊機(jī)制進(jìn)行聯(lián)系。Linux內(nèi)核是一個(gè)整體結(jié)構(gòu),因此向內(nèi)核添加任何東西.或者刪除某些功能,都十分困難 。為了解決這個(gè)問(wèn)題,引入了模塊機(jī)制,從而可以動(dòng)態(tài)的在內(nèi)核中添加或者刪除模塊。模塊一旦被插入內(nèi)核,就和內(nèi)核其他部分一樣。Linux內(nèi)核中的設(shè)備驅(qū)動(dòng)程序是一組常駐內(nèi)存的具有特權(quán)的共享庫(kù),是低級(jí)硬件處理例程。對(duì)用戶程序而言,設(shè)備驅(qū)動(dòng)程序隱藏了設(shè)備的具體細(xì)節(jié), 對(duì)各種不同設(shè)備提供了一致的接口,一般來(lái)說(shuō)是把設(shè)備映射為一個(gè)特殊的設(shè)備文 件,用戶程序可以像對(duì)其它文件一樣對(duì)此設(shè)備文件進(jìn)行操作。Linux支持3種設(shè)備:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備。設(shè)備由一個(gè)主設(shè)備號(hào)和一個(gè)次設(shè)備
20、號(hào)標(biāo)識(shí)。主設(shè)備號(hào)唯一標(biāo)識(shí)了設(shè)備類型, 即設(shè)備驅(qū)動(dòng)程序類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項(xiàng)的索引。次設(shè)備號(hào)僅由設(shè)備驅(qū)動(dòng)程序解釋 ,一般用于識(shí)別在若干可能的硬件設(shè)備中,I/O請(qǐng)求所涉及到的那個(gè)設(shè)備。典型的Linux模塊實(shí)現(xiàn)機(jī)制有如下幾步:注冊(cè)設(shè)備:在系統(tǒng)初啟或者加載模塊的時(shí)候,必須將設(shè)備登記到相應(yīng)的設(shè)備數(shù)組,并返回主設(shè)備號(hào)。定義功能函數(shù):對(duì)于每一個(gè)驅(qū)動(dòng)函數(shù)來(lái)說(shuō),都有一些和此設(shè)備密切相關(guān)的功能函數(shù)。以最常用的塊設(shè)備或者字符設(shè)備來(lái)說(shuō),都存在著諸如 open()、read()這一類的操作。當(dāng)系統(tǒng)調(diào)用這些調(diào)用時(shí),將自動(dòng)的使用驅(qū)動(dòng)函數(shù)中特定的模塊來(lái)實(shí)現(xiàn)具體的操作。卸載設(shè)備:在不用這個(gè)設(shè)備時(shí),可以將它卸載
21、,主要是從/proc 中取消這個(gè)設(shè)備的特殊文件。(2) 編寫Makefile文件Makefile文件用于編譯設(shè)備驅(qū)動(dòng)程序,其內(nèi)容如下:ifneq ($(KERNELRELEASE),) #kbuild syntax.#模塊的文件組成mymodule-objs :=MyDeviceDriver.o #生成的模塊文件名 obj-m := MyDeviceDriver.o elsePWD :=$(shell pwd)KVER :=$(shell uname -r)KDIR :=/lib/modules/$(KVER)/buildall:$(MAKE) -C $(KDIR) M=$(PWD)clean
22、:#rm -f *.cmd *.o *.mod *.korm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions#$(MAKE) -C $(KDIR) M=$(PWD) cleanendif(3) 編寫設(shè)備功能函數(shù)編寫設(shè)備驅(qū)動(dòng)程序的主要工作就是編寫子功能函數(shù),并填充file_operations的各個(gè)域 。結(jié)構(gòu)體file_operations的具體定義如下:struct file_operations struct module *owner;/擁有該結(jié)構(gòu)的模塊的指針,一般為THIS_MODULES
23、 loff_t (*llseek) (struct file *, loff_t, int);/用來(lái)修改文件當(dāng)前的讀寫位置 ssize_t (*read) (struct file *, char _user *, size_t, loff_t *);/從設(shè)備中同步讀取數(shù)據(jù) ssize_t (*write) (struct file *, const char _user *, size_t, loff_t *);/向設(shè)備發(fā)送數(shù)據(jù)ssize_t (*aio_read) (struct kiocb *, co
24、nst struct iovec *, unsigned long, loff_t);/初始化一個(gè)異步的讀取操作 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);/初始化一個(gè)異步的寫入操作 int (*readdir) (struct file *, void *, filldir_t);/僅用于讀取目錄,對(duì)于設(shè)備文件,該字段為NULL unsigned int (
25、*poll) (struct file *, struct poll_table_struct *); /輪詢函數(shù),判斷目前是否可以進(jìn)行非阻塞的讀寫或?qū)懭? int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); /執(zhí)行設(shè)備I/O控制命令 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); /不使用BLK文件系統(tǒng),將使用此種函數(shù)指針代替ioct
26、l long (*compat_ioctl) (struct file *, unsigned int, unsigned long); /在64位系統(tǒng)上,32位的ioctl調(diào)用將使用此函數(shù)指針代替 int (*mmap) (struct file *, struct vm_area_struct *); /用于請(qǐng)求將設(shè)備內(nèi)存映射到進(jìn)程地址空間 int (*open) (struct inode *, struct file *); /打開 i
27、nt (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); /關(guān)閉 int (*fsync) (struct file *, struct dentry *, int datasync); /刷新待處理的數(shù)據(jù) int (*aio_fsync) (struct kiocb *, int datasync); /異步刷新待處理的數(shù)據(jù)
28、60; int (*fasync) (int, struct file *, int); /通知設(shè)備FASYNC標(biāo)志發(fā)生變化 int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file
29、 *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
30、 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock *); ;(4) 設(shè)備驅(qū)動(dòng)程序安裝 make clean,清除make產(chǎn)生的殘留 make,重新調(diào)用Makefile編譯設(shè)備驅(qū)動(dòng)程序 insmod -f MyDeviceDriver.ko,加載生成的 MyDeviceDr
31、iver.ko模塊 cat /proc/devices,獲取設(shè)備驅(qū)動(dòng)程序的主設(shè)備號(hào)mknod /dev/MyDeviceDriver c 147 0,創(chuàng)建設(shè)備文件,147為主設(shè)備號(hào),0為從設(shè)備號(hào)(5) 測(cè)試驅(qū)動(dòng)程序此設(shè)備驅(qū)動(dòng)程序?qū)崿F(xiàn)的功能是將一個(gè)字符串中內(nèi)容拷貝到另外一個(gè)字符串中。測(cè)試程序編寫完成后,在終端輸入gcc test.c -o test進(jìn)行編譯。測(cè)試結(jié)果如下:圖 4.64.3.3 源程序(1) 設(shè)備驅(qū)動(dòng)程序:#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#i
32、nclude <asm/uaccess.h>MODULE_LICENSE("GPL");#define MAJOR_NUM 147static ssize_t d_read(struct file *, char *, size_t, loff_t*);static ssize_t d_write(struct file *, const char *, size_t, loff_t*);static ssize_t d_open(struct inode *,struct file *);static ssize_t d_release(struct inod
33、e *,struct file *);struct file_operations d_fops= .read=d_read, .write=d_write, .open=d_open, .release=d_release,;static char var1024="Device test:"int counter=12;static int _init device_init(void) int result; result = register_chrdev(MAJOR_NUM, "device", &d_fops); if(result)
34、 printk("device register failure"); else printk("device register success"); return result;static void _exit device_exit(void) unregister_chrdev(MAJOR_NUM, "device"); printk("unloading the device.");static ssize_t d_read(struct file *filp, char *buf, size_t len
35、, loff_t *off) if(copy_to_user(buf,var,1024*sizeof(char) return - EFAULT; return sizeof(char);static ssize_t d_write(struct file *filp,const char *buf,size_t len,loff_t *off) if(copy_from_user(var+counter,buf,len*sizeof(char) return - EFAULT; counter+=len; return sizeof(char);static ssize_t d_open(s
36、truct inode *inode,struct file *file) printk(KERN_INFO "open it!n"); return 0;static ssize_t d_release(struct inode *inode,struct file *file) printk(KERN_INFO "close itn"); return 0; module_init(device_init);module_exit(device_exit);(2) 測(cè)試程序:#include <sys/types.h>#include &
37、lt;sys/stat.h>#include <stdio.h>#include <fcntl.h>#include <string.h>main() int fd; char buffer1024; int num; fd=open("/dev/3",O_RDWR,S_IRUSR|S_IWUSR); if(fd!=-1) read(fd,buffer,1024*sizeof(char); printf("The device is %sn",buffer); printf("Please input
38、the characters written to device:n"); fgets(buffer,1024,stdin); num=strlen(buffer)-1; write(fd,buffer,num*sizeof(char); read(fd,buffer,1024*sizeof(char); printf("The device is %sn",buffer); close(fd); else printf("Device open failuren"); 4.4 實(shí)驗(yàn)四4.4.1 實(shí)驗(yàn)要求了解/proc文件的特點(diǎn)和使用方法;監(jiān)控
39、系統(tǒng)狀態(tài),顯示系統(tǒng)中若干部件使用狀態(tài);用圖形界面實(shí)現(xiàn)系統(tǒng)監(jiān)控狀態(tài)。4.4.2 設(shè)計(jì)思路(1)/proc文件系統(tǒng)的特點(diǎn)Linux的PROC文件系統(tǒng)是進(jìn)程文件系統(tǒng)和內(nèi)核文件系統(tǒng)的組成的復(fù)合體,是將內(nèi)核數(shù)據(jù)對(duì)象化為文件形式進(jìn)行存取的一種內(nèi)存文件系統(tǒng),是監(jiān)控內(nèi)核的一種用戶接口。它擁有一些特殊的文件(純文本),從中可以獲取系統(tǒng)狀態(tài)信息。(2)功能清單獲取并顯示主機(jī)名,與之相關(guān)的proc文件為/proc/sys/kernel/hostname;獲取并顯示系統(tǒng)啟動(dòng)的時(shí)間,與之相關(guān)的proc文件為/proc/uptime;顯示系統(tǒng)到目前為止持續(xù)運(yùn)行的時(shí)間,與之相關(guān)的proc文件為/proc/uptime;顯示
40、系統(tǒng)的版本號(hào),與之相關(guān)的proc文件為/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease; 顯示CPU的型號(hào)和主頻大小,與之相關(guān)的proc文件為/proc/cpuinfo;通過(guò)pid或者進(jìn)程名查詢一個(gè)進(jìn)程,并顯示該進(jìn)程的詳細(xì)信息,提供殺掉該進(jìn)程的功能,與之相關(guān)的proc文件為/proc/(pid)/stat;顯示系統(tǒng)所有進(jìn)程的一些信息,包括pid、ppid、占用內(nèi)存大小、優(yōu)先級(jí)等,與之相關(guān)的proc文件為/proc/(pid)/stat, /proc/(pid)/statm;CPU使用率的圖形化顯示(2分鐘內(nèi)的歷史記錄曲線),與之相關(guān)的proc
41、文件為/proc/stat;內(nèi)存和交換分區(qū)的使用率的圖形化顯示(2分鐘內(nèi)的歷史曲線),與之有關(guān)的proc文件為/proc/meminfo;在狀態(tài)欄顯示當(dāng)前時(shí)間,未使用到/proc中的文件;在狀態(tài)欄顯示當(dāng)前CPU使用率,與之相關(guān)的proc文件為/proc/stat;在狀態(tài)欄顯示當(dāng)前內(nèi)存使用情況,與之相關(guān)的proc文件為/proc/meminfo;用新線程運(yùn)行一個(gè)其他程序,未使用到/proc中的文件;關(guān)機(jī)功能,未使用到/proc中的文件;(3)功能實(shí)現(xiàn)獲取并顯示主機(jī)名用file.open函數(shù)打開/proc/sys/kernel/hostname文件,然后以文件指針為輸入流,從其中讀出一行字符包含主
42、機(jī)名,然后直接輸出在label上,即主機(jī)名。獲取并顯示系統(tǒng)啟動(dòng)的時(shí)間從文件/proc/uptime中獲取系統(tǒng)啟動(dòng)到現(xiàn)在的運(yùn)行時(shí)間(單位是s),直接獲取當(dāng)前時(shí)間addSecs(-runtime),然后用timetostring以時(shí)間日期的格式顯示出來(lái)。顯示系統(tǒng)到目前為止持續(xù)運(yùn)行的時(shí)間打開/proc/uptime文件,然后以文件指針為輸入流讀出一行數(shù)據(jù)輸出在label上即可。顯示系統(tǒng)的版本號(hào)從/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease中讀取系統(tǒng)類型(比如linux)和系統(tǒng)內(nèi)核版本號(hào),處理方法和獲取系統(tǒng)運(yùn)行時(shí)間的方法一樣。得到系統(tǒng)類型和系統(tǒng)內(nèi)
43、核版本號(hào)之后,調(diào)用QString類的方法arg將兩個(gè)字符串連接起來(lái),再輸出顯示即可。顯示CPU的型號(hào)和主頻大小打開/proc/cpuinfo文件后讀取任一CPU型號(hào)和頻率即可。通過(guò)pid或者進(jìn)程名查詢一個(gè)進(jìn)程,并顯示該進(jìn)程的詳細(xì)信息,提供殺掉該進(jìn)程的功能在獲取所有進(jìn)程信息的時(shí)候,獲取到的所有信息已經(jīng)被存儲(chǔ)在一個(gè)全局結(jié)構(gòu)體數(shù)組變量中了,所以查詢的時(shí)候,先獲取輸入lineEdit中的文本(QString類型),然后將文本與全局結(jié)構(gòu)體數(shù)組變量的每一個(gè)數(shù)組元素的name成員和pid成員作比較,若相等,說(shuō)明待查詢的進(jìn)程存在,將該進(jìn)程的詳細(xì)信息輸出即可。殺死進(jìn)程前先要獲取將要被殺死進(jìn)程的名稱或者pid,而
44、且該進(jìn)程必須存在于/proc目錄下,即先查詢一次待殺死的進(jìn)程,處理方法如上所述。Linux系統(tǒng)提供了kill、pkill等殺死進(jìn)程的命令,pkill通過(guò)pid殺死進(jìn)程,kill通過(guò)進(jìn)程名稱殺死進(jìn)程。通過(guò)將lineEdit中的內(nèi)容和kill或pkill組成終端命令,然后調(diào)用system函數(shù)執(zhí)行這些命令即可殺死相應(yīng)的進(jìn)程。顯示系統(tǒng)所有進(jìn)程的一些信息,包括pid、ppid、占用內(nèi)存大小、優(yōu)先級(jí)等系統(tǒng)的進(jìn)程眾多,本次實(shí)驗(yàn)我采用的是Linux中對(duì)目錄進(jìn)行操作的函數(shù)opendir(),readdir()。實(shí)現(xiàn)思路為:聲明一個(gè)DIR類型的指針dir,用opendir函數(shù)打開/proc目錄,返回值賦值給dir
45、,然后將dir作為函數(shù)readdir的參數(shù),readdir函數(shù)返回值復(fù)制給dirent結(jié)構(gòu)體指針ptr。ptr指向的結(jié)構(gòu)體包含d_name char數(shù)組成員,即文件或者目錄名,將d_name數(shù)組的0號(hào)元素分別和字符1、9比較,若處于這兩者之間,則表明該文件或者目錄是進(jìn)程目錄,以該目錄名為參數(shù)調(diào)用獲取進(jìn)程詳細(xì)信息的函數(shù)read_proc。在read_proc函數(shù)中,使用格式化輸出函數(shù)sprintf將參數(shù)目錄名c_pid對(duì)應(yīng)目錄下的文件stat的路徑輸出到char數(shù)組filename中,再調(diào)用C+的類ifstream,聲明一個(gè)ifstream類性的變量meminfo,用filename初始化mem
46、info,然后用析取器(>>)從meminfo中輸入數(shù)據(jù)到結(jié)構(gòu)體數(shù)組procInfo的每個(gè)元素的成員變量中,析取器(>>)會(huì)自動(dòng)忽略空字符。所需要的進(jìn)程信息并不是連續(xù)存放在stat文件中的,中間包含有其他不需要顯示的進(jìn)程信息,解決方法是定義一個(gè)string類型的變量temp,根據(jù)stat文件中的信息存放順序,將所有不需要的進(jìn)程信息全部輸入到temp中。此外還要注意一個(gè)問(wèn)題,進(jìn)程名稱帶有括號(hào)“()”,所以需要將括號(hào)去掉,解決方法是使用string類的方法substr,該函數(shù)的參數(shù)有兩個(gè),一個(gè)是想截取的字符串首字符在原字符串中的位置,第二個(gè)參數(shù)是想截取的字符串末尾字符后面一
47、個(gè)字符,在這里就是“)”。處理完畢之后,所需要的關(guān)于進(jìn)程c_pid的詳細(xì)信息都存儲(chǔ)在全局結(jié)構(gòu)體數(shù)組procInfo的元素中了。循環(huán)采用上述思路,直到所有進(jìn)程目錄都被處理完畢,所有的進(jìn)程信息就都存儲(chǔ)在了全局結(jié)構(gòu)體數(shù)組procInfo中,然后用定時(shí)器觸發(fā)定時(shí)更新全局結(jié)構(gòu)體數(shù)組procInfo中的內(nèi)容。CPU使用率的圖形化顯示使用qcustomplot插件畫圖即可,數(shù)據(jù)用一個(gè)120大小的數(shù)組存儲(chǔ)即可內(nèi)存和交換分區(qū)的使用率的圖形化顯示同CPU使用率的圖像相似用數(shù)組存好數(shù)據(jù)后調(diào)用即可。在狀態(tài)欄顯示當(dāng)前時(shí)間調(diào)用QDateTime的方法currentDateTime獲取當(dāng)前時(shí)間time,time是一個(gè)QDa
48、teTime類型的變量,然后調(diào)用QDateTime的方法toString把time轉(zhuǎn)化成格式為yyyy-MM-dd hh:mm:ss dddd的QString字符串,再在主窗口的狀態(tài)欄顯示輸出即可。在狀態(tài)欄顯示當(dāng)前CPU使用率CPU的使用率是指CPU的使用時(shí)間和CPU總時(shí)間的比值。因?yàn)?proc/stat文件中的所有值都是從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻,所以計(jì)算CPU使用率時(shí)需要取兩個(gè)采樣點(diǎn),利用兩個(gè)點(diǎn)的差值計(jì)算CPU使用率,此次實(shí)驗(yàn)采樣方法是每隔1秒采樣一次。CPU使用率的計(jì)算公式為cpuRate=100.0-(idle2-idle1)*100.0/(total2-total1)。定義一個(gè)全局
49、結(jié)構(gòu)體CPU_USE,具體定義如下:typedef struct CPU_USE char name16;/cpu unsigned int user; unsigned int nice; unsigned int system; unsigned int idle; unsigned int iowait;unsigned int irq; unsigned int softirq;cpu_use;CPU總時(shí)間的值等于結(jié)構(gòu)體CPU_USE中7個(gè)unsigned int類型的成員值之和。計(jì)算之前,調(diào)用get_cpu_use_stat函數(shù)獲取一個(gè)CPU狀態(tài),sleep一秒后再調(diào)用該函數(shù)獲取第二
50、個(gè)CPU狀態(tài),然后用上述CPU使用率計(jì)算公式計(jì)算即可。在狀態(tài)欄顯示當(dāng)前內(nèi)存使用情況內(nèi)存使用率是指已使用的內(nèi)存和總內(nèi)存的比值。內(nèi)存使用率的計(jì)算公式為:memRate=(total (free+buffers+cached)*100.0/total。定義一個(gè)全局結(jié)構(gòu)體MEM_USE,具體定義如下:typedef struct MEM_USE unsigned long total; unsigned long free; unsigned long buffers; unsigned long cached;mem_use;該結(jié)構(gòu)體中的成員的值都來(lái)自文件/proc/meminfo, 聲明一個(gè)ifs
51、tream類性的變量meminfo,用/proc/meminfo初始化meminfo, 然后用析取器(>>)從meminfo中輸入數(shù)據(jù)到結(jié)構(gòu)體mem_use 的成員變量中,析取器(>>)會(huì)自動(dòng)忽略空字符。所需要的內(nèi)存數(shù)據(jù)信息并不是連續(xù)存放在/proc/meminfo文件中的,中間包含有其他不需要的內(nèi)存數(shù)據(jù)信息,解決方法是定義一個(gè)string類型的變量str,根據(jù)/proc/meminfo文件中的信息存放順序,將所有不需要的內(nèi)存數(shù)據(jù)信息全部輸入到str中。得到內(nèi)存使用的數(shù)據(jù)信息之后,使用上述內(nèi)存使用率計(jì)算公式計(jì)算即可。用新線程運(yùn)行一個(gè)其他程序在主窗口中添加一個(gè)lineEd
52、it控件,獲取該控件中輸入的程序名稱,然后調(diào)用QProcess類的start方法運(yùn)行該程序。關(guān)機(jī)功能由于關(guān)機(jī)功能需要輸入密碼獲取root權(quán)限,所以需要想方法在點(diǎn)擊關(guān)機(jī)按鈕后輸入密碼。定義一個(gè)QString類型的變量passWord,調(diào)用類QInputDialog的方法getText,會(huì)彈出一個(gè)對(duì)話框提示輸入密碼,該方法的返回值即為密碼,將返回值賦值給passWord變量;當(dāng)對(duì)話框的OK按鈕被點(diǎn)擊時(shí),用QString("echo %1 | sudo -S shutdown -h now").arg(passWord)初始化QString類型的變量sudo,再把sudo轉(zhuǎn)換成c
53、har*類型,然后調(diào)用system函數(shù)執(zhí)行關(guān)機(jī)命令。(4)界面設(shè)計(jì)實(shí)驗(yàn)四用QT寫界面,較為簡(jiǎn)便,將主界面分為四頁(yè),第一頁(yè)是系統(tǒng)信息,第二頁(yè)是進(jìn)程信息,第三頁(yè)提供殺進(jìn)程和創(chuàng)建進(jìn)程,第四頁(yè)是歷史圖像,至于CPU使用率和內(nèi)存使用率用一個(gè)Bar顯示。4.4.3程序效果顯示4.4.4源代碼Mainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include<QLabel>#include<QPushButton>class QTabWidget;namespace Ui c
54、lass MainWindow;class MainWindow : public QMainWindow Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); MainWindow();private: Ui:MainWindow *ui; private: void HostName(); void BootTime(); void OSType(); void add_point(float cpuRate); void UpdateCPULine(); void CPUInfo();private slots: void N
55、owTime(); void CPURate(); void MemRate(); void run_time(); void ProcessInfo(); void QueryProcess(); void KillProcess(); void CreateProcess(); void on_reboot_clicked();#endif / MAINWINDOW_HCPU.H#ifndef CPU_H#define CPU_H#include <stdio.h>#include <stdlib.h>#include <QString>#include <QFile>#include <QTextStream>typedef struct CPU_USE char name16; unsigned
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 一年級(jí)道德與法治上冊(cè)第16課新年的禮物備
- 2025年廣東省高考物理試題(含答案解析)
- RCS及LFP客服培訓(xùn)系列高壓保護(hù)部分
- 加油站危險(xiǎn)性作業(yè)管理制度及操作規(guī)程
- 藍(lán)綠商務(wù)責(zé)任心塑造培訓(xùn)
- 領(lǐng)導(dǎo)力的挑戰(zhàn)與機(jī)遇培訓(xùn)工程師視角
- 顧客體驗(yàn)設(shè)計(jì)在新零售中的挑戰(zhàn)與機(jī)遇
- 顧客情感反饋在新零售中的運(yùn)用
- 項(xiàng)目管理中如何運(yùn)用數(shù)據(jù)分析優(yōu)化流程
- 非洲制造業(yè)的投資機(jī)遇與挑戰(zhàn)
- 長(zhǎng)短款管理制度
- 洪災(zāi)后衛(wèi)生防疫知識(shí)講座
- 試卷+答案初三語(yǔ)文中考模擬試卷試卷
- 大學(xué)英語(yǔ)四六級(jí)詞匯表
- 【2025高考專題沖刺-語(yǔ)病真題】辨析并修改病句七年真題匯編(2018-2024年)
- 湖北省武漢市江岸區(qū)2024-2025學(xué)年上學(xué)期元調(diào)九年級(jí)物理試題(含答案)
- 熔鹽爐拼接爐拱施工方案
- 2025年全國(guó)國(guó)家版圖知識(shí)競(jìng)賽題庫(kù)及答案(中小學(xué)組)
- 長(zhǎng)安售后工作計(jì)劃
- 特殊教育崗前培訓(xùn)
- 2023年遺傳學(xué)考試題庫(kù)(含答案)
評(píng)論
0/150
提交評(píng)論