资源描述
课程设计报告
课程名称:操作系统原理
院系:计算机科学与技术
专业班级:CS140 _
学号:U202114_姓名:__
指导教师:—_完成时间:2021年3月11日一
(4) 设备驱动程序安装
① make,调用Makefile编译设备驱动程序图 4.7make 图
编译成功,生成mydev.ko文件sudo insmod mydev.ko挂载模块,再查看设备的主设备号: cat /proc/devices
图4.8主设备号的图
可见系统为mydev生成的主设备号为248
② sudo /dev/mydev c 248 0
mydev是设备文件的名字,“c”是指创立的是字符设备文件,248是主设备 号,()是从设备号。
图4.9生成设备文件图
可见生成了正确的设备文件mydev
(5) 测试驱动程序
测试程序实现的是先从设备中读出里面初始的字符串U202114813,再把一个字符串写进去,然后再读出来,测试程序详见附件源码,测试实验结果如以下图:
先运行命令执行程序:sudo ./test图4.10结果图
可见翻开、读、写均正确。
最后执行 sudo rmmod mydev来删除模块sudo rm /dev/mydev来删除设备文件
4.4 实验四
要求理解和分析/proc文件。
4.4.1 实验要求
了解/proc文件的特点和使用方法;监控系统状态,显示系统部件的使用状态; 用图形界面实现系统监控状态,包括CPU和内存利用率、所有进程信息等〔可自己 补充、添加其他功能〕。
4.4.2 实验设计及调试
这个实验主要是对/proc文件的理解和对gtk的熟练运用。我用gtk里的笔记本 构件画了 3 个页面,分别 为 page one、page two、page threeo
page one:显示CPU利用率
计算和显示CPU直接用到的实验一第二个局部的显示CPU利用率局部,不同 的是这儿用到了笔记本控件,要把“page one”作为一个button加到notebook上, 还要把算出来的CPU利用率作为一个标签内容加到notebook上,即:
GtkWidgct *button4 = gtk_labcl_ncw("Page one");
label 1 = gtk_label_new(Hbegin");// 全局标签 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), labcll, button4);// 笔记 本容器、子控件、标题名
然后创立一个线程去计算CPU利用率,然后实时更新显示出来。
page two:显示所有进程信息
用gtk来画这个界面的逻辑是:最大的逻辑控件是笔记本notebook,把一个hbox 添加到notebook里,再把显示所有进程信息的表clist添加到一个滚动窗口 scrolled_window里,再把这个scrollcd_\vindo\v添加到hbox左边局部;hbox右边局 部包括一个vbox,这个vbox _h面是一个frame来显示进程大致情况,下面是一个 button用来刷新进程。如以下图4.11:
r 11 Hcv
scrolled_window
clist
Kp,int *q,int 这些数字 次态、优先 中的总进程 )遍历时统 显.示出来,
notebook
clist t *r,int *s)函 文件夹的 级、占用巾 数、运行E 计出来的。 通过void r
GtkWidget *burton2 = gtk_button_new_wich」abel(‘刷新g_signal_connect_s\vapped (G_OBJECT (button2), "clicked",G_C/\LLBACK (refresh), clist); 当button2上发生click事件时就调用refresh完成刷新。
page three:显示一些根本的CPU信息
这页就是简单的创立两个frame 1和血me2来显示CPU局部信息和操作系统的局部信息。
frame 1 中:CPU 名称通过 char* get_cpu_name(char xbufl)函数获得,CPU 类型通 过 char* get_cpu_type(char *buf2)函数获得,CPU 主频通过 char* get_cpu_f(char *buf3) 函数获得,这3个信息都是从/proc/cpuinfo中读出来的,其中涉及到一些简单的字 符串的判断等操作,在此不加赘述;
framc2中:操作系统名称是通过char *gct_os_t)pc(char *bufl)函数获得的,操作 系统版本是通过char *get_os_version(char *buf2)函数获得的,它们都返回一个缓冲区 指针,用以在主函数main〔〕中显示。
3个页面的详细代码见附件中源码。
编译:gcc -o lab4 lab4.c 'pkg-config —cflags —libs gtk+-2.0' 执行:./lab4
实验结果如以下图4.12、4.13、4.14:
图4.12第一个页面图图4.13第二个页面图
图4.14第三个页面图5心得体会
本次课程设计,第一个题目第一问很简单,因为之前在实验中写过文件拷贝的 程序,所以很快就顺利实现了,要注意fopcn、fread、fwrite几个函数的用法,第二 问刚开场不知怎么做,主要是因为之前没接触过gtk这种画界面的环境,在网上查 阅相关资料后发现套路都是一样的,个人觉得把握住gtk中控件的概念,实现简单 的界面都还是比较简单的,除了 gtk,在CPU利用率的计算上还卡了一段时间,主 要是没弄清到底应该怎么计算,查了大量资料后找到一种比较简单的计算方法去实 现,结果也很准确;第二题和第三题是同一类型,都是需要对内核、系统调用、设 备驱动文件有很好的理解才能很快做出来,自己还掌握得不是很好,所以也花了不 少的时间去查资料、实现要求的功能,但现在回过头来看收获很大,对课上所学的 局部内容有了更加深刻的理解,对linux系统调用和设备文件有了更深的认识;第四 题确实是花的时间最多的,因为不仅涉及到复杂的gtk运用,还包括对/proc文件的 理解,这两方面都是查了大量资料后才一点点完成的,时间花了,确实也有了成效, 看到自己画的界面和读出的进程、CPU信息,成就感瞬间爆棚,但这还远远不够, 相信以后学习工作中还会遇到更加困难的类似的问题,这次课设只是打下了个小小 的根底,任重道远!总之,这次课设受益匪浅。
6 附录〔源码〕实验一:
第一题:
#include <stdio.h>#dcfine buffer_size 1000
int main(int argc,char *argv[]){
if(argc != 3) 〃输入3个参数
{printf("input error!\n");
return 0;
}
charbuff[buffcr_sizc] = {0}; 〃缓冲区初始化为'\0'
int nrcad = 0;
FILE *fp_read = NULL;
FILE *fp_write = NULL;
if((fp_read = fbpen(argv[1],”rb”))== NULL)
{printf("can't open %s",arg\-(l]);
return 1;
}
if((fp_write = fbpen(argv[2] ,Hwb")) == NULL)
{printf("can't open %s",arg\r[2]);
return 1;
}\vhile((nrcad = frcad(l)uff»sizeof(char),buffer_size,fp_rcad))>0) //实际读到字符数 nrcad Rvritc(buff,sizcof(char),nrcad,fp_\vritc);
fclosc(fp_rcad);
fclose(fp_\vrite);
return 0;}
第二题:
//include <gtk/gtk.h>#include <time.h>
#include <unistd.h>GtkWidget*window;
GtkWidget*label;void havctimcO {
int i;
命(;计+){time_t titner = timefNUI J);
char s[l000] = {0};sprintf(s,"local time is %s”,ctimc(&timcr));〃格式化字符串写入 s
/*sleep for a second*/sleep(1);
gclk_thrcads_enter();gtk_label_set_text(G T K_L A B EL(label),s); gdk_threads_leave();
void cpu_usagc() {
FILE *fp;
char cpu[5];
char buff[1000] = {0};
char s[1000] = {0};
long int user,nice,sys,idle,iowait,irq,softirq;long int sl,s2,idlcl,idlc2; float usage;
\vhile(l){fp = fopenf*/proc/stat","rn);
if(fp == NULL){pcrrorf'fbpcn");
exit(0);}
fgets(buff,sizeof(l)uff),fp);//从文件构造体指针中读取数据sscanffbuf£"%s%d%d%d%d%d%d%d”,cpu,&user,&nice,&sys,&idl&&iowait,&irq,&softirq); si = uscr+nicc+sys+idlc+iowait+irq+softirq;
idlel = idle;rcwind(m);
sleep ⑴;//mcmsct(buff,0,sizeof(buff));
//cpu[0] = W;user = nice 二 sys = idle = iowait = irq = softirq 二 0;
fget5(buff,sizeof(buff),fp); sscanf(buff,"%s%d%d%d%d%d%d%d”,cpu,&user,&nice,&sys,&idle,&io\vait,&irq,&scFtirq); s2 = user+nice+sys+idle+iowait+irq+softirq;idlc2 = idle;
usage = (float)(s2 - si - (idle2-idlel))/(s2 - s1)*100;sprintf(s;'CPU 利用率为%f%% H,usage);
gd k_th read s_cn ter 0;gtkJabel_set_text(GTK_LABEL(label),s);
gclk_thrcads_leave();fclose(fp);
sleep(l);void add。{
int j = 1;
int sum = 0;int suml = 0; for(;j<l01;j++){ suml = sum+j; chars[1000] = {0};
sprintf(s,"%d + %d = %d",sum,j,suml); sleep(3);gdk_th read s_cn ter 0;
gtk_label_set_text(GTK_LABEL0abel) ,s);gclk_thrcads_lcave();
sum = suml;int main(int argc,char *arg\ [])
int pid_l,pid_2,pid_3;
if((pid_l = forkQ) == 0){gtk_init(&ar 穿,&argv);
window = gtk_window_new(GTI<_WIND(^W_TOPLEVEL);gtk_wi ndo\v_sct_ti tlc(GTI<_WI N DO W (window) /'child 1 progress'1);
gtk_\vi ndo\v_sct_posi tion (G1*K_WIN DOW(xvindow) ,G1K_WIN_POS_N ON E); gtk_container_set_border_width(GTK_CONTAlNER(windo\v),100);now
now
label = gtk_labcl_ncw("no\v let's begin!'1); gtk_containcr_add(GTK_CONT/\INER(window),label); gtk_widget_show_all(windo\v);g_signal_conncct(window,"destroy",G_C/\LLBACK(gtk_main_quit),NULL);
7*线程的初始化*/if(!g_thread_supported()) g_thread_init(NULL); gdk_threads_initQ;
/*创立残程*/ g_thrcad_crcatc((GThrcadFunc)havetimc, NULL, FALSE, NULL);
}else if((pid_2 = fbrkQ)二二 0)( gtk_init(&argc,&argvr);
window = gtk_window_ncw(GTK_WINDOW_TOPLEVEL); gtk_windo\v_sct_titlc(GTI<_V('INDOW(window)/'child 2 progress'1); gtk_window_set_position(GTK_WlND()W(winclow),GTK_WlN_POS_NONE); gtk_container_set_border_width(GTI<_CONT AIN ER(windo\v),l 00);label = gtk_label_new("no\v let's begin!'1); gtk_container_add(GTK-_CONTAINER(window),label); gtk_widgct_show_all(window);
g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);/*线程的初始化*/
if(!g_thrcad_supportcd0) g_thread_init(NULL);gdk_threads_initQ;
/*创立残程*/ g_threacl_create((GThreadFunc)cpu_usage, NULL, FALSE, NULL);
else if((pid_3 = fork® ==0)(gtk_init(&argc,&argv);
/*窗口初始化*/window = gtk_window_ncw(GTK_WlNDOW_TOPLEVEL); gtk_\vindow_set_tide(GTK_WIND()W(\vindow),nchild 3 progress'1); gtk_windo\v_set_posirion(GTK_WIND()W(window),GTK_WIN_POS_NONE); gtk_con tainer_set_border_wid th (GTK_CONT A IN ER (window), ! 00);
/*标签*/label = gtk_label_new("no\v let's begin!"); gtk_containcr_add(GTK_C()NT AIN ER(\vindow),label); gtk_\vidget_show_all(windo\v);
g_signal_conncct(window,"destroy",G_CAI J .BACK(gtk_main_quit),NUI.L);
/*线程的初始化*/ if(!g_thread_supportcd()) g_thrcad_init(NULL); £jclk_threacls_initO;
/*创立线程*/ g_thread_create((GThreadFunc)add, NULL, FALSE, NULL);}
gdk_th rcads_cntcr();
gtk_main 0; gdk_threads_leave(); return 0;}
实验二:
sys.c:
asmlinkage int sys_mysyscall(char* sourceFile,char* destFile) { int source=sys_open(sourceFile,O_RD(^)NLY,0);
int dest=syslopcn(destFile,O_WRONI.Y | O.CREAT 10_TRUNC,0600); char buQ4096];
mm_scgpicnt_t fs;
fs = get_fs(); set_fs(get_dsO); //设置为内核的内存访问地址范国 int i;
if(sourcc>0 && dest>0)
{do
{ i=sys_read(source,buf,4096); sys_writc(dcst,buf,i);}\vhilc(i);
} sys_close(source); sys_close(dest); set_fs(fs); return 10;}
teste:
#include <sys/syscall.h>#include <unistd.h>
int main°{ syscall(326,"textl.txt","text2.txt"); return 0;}
实验三:
mydev.c:
#includc "linux/kcrncl.h'^#include "linux/modulc.h"
#include "linux/fs.h"#include "linux/init.h"
//include "linux/typcs.h”#include "linux/errno.hH
#include "linux/uaccess.h"#include Ulinux/kdev_t.h"
#dcfine BUFFER_SIZE 1024static int my_open(struct inode *inode, struct file *file);
static int my_rclcase(struct inode *inodc, struct filestatic ssize_t my_read(struct filechar _user *user, size_t t, *0;
static ssize_t my_\vrite(struct file *file, const char _user *user, size_t t, *f);static char message[BUFFER_SIZE] = ”U202114813”;
static int device_num = 0;//static int counter = 0;//
static char* devname = "mydev";struct file_operations pstruct = (
.read = my_read,.write = my_write,
.open = my_opcn,.release = my_rclcasc
};int init_module(){
int ret;ret = register_chrdev(O,devname,&pstruct);
if(rct<0)(printkf'regist failure\n");
return -1;}
else {printkf'thc device has been registered!\n");
device_num = ret;prinrk(*'<!>the virtual device's major number %d.\n", device_num); prinrkf'<l>Or you can see it by using\n,r); printkC'vl〉more /proc/deviccs\n");
printkf'<l>To talk to the driver,create a dev file with\n,t); printkf'<l>'mknod /dev/myDevice c %d O'\n", device_num);printkf,<l>Use \"rmmode\'* to remove the module\n"); return 0;
})
void cleanup_moduleO {
unregister_chrdev(device_num,devname); printkf'unrcgistcr it success\n");}
static int my_opcn (struct inode *inode,struct file *file) ( printk("<l>main device : %d\n", M/\J()R(inode->i_rdev)); printkf'<l >slave device : %d\n", MINOR(inode->i_rdev)); prinrk(,'<l>%d times to call rhe devicc\n", ++counter); try_module_get(THIS_MODULE);return 0;
}stauc int my_rclease(struct inode *inode,struct file *file){
printk("Device rclcascd!\n"); module_put(THIS_MODl;LE); return 0;)
static ssize_t my_\vrite(struct file const char _user *user,size_t*f) {if(copy_fr()tn_user(message,user,sizeof(message))) return -EFAULT;
}return sizeof(message);
}static ssize_t my_read(srruct file * file,char _user +user,size_t*。{
if(copv_to_uscr(user,message,sizcof(messagc))){
return -EFAULT;}
return sizeof(message);}
teste:
//include <sys/typcs.h>^include <sys/stat.h>
#include <stdlib.h>#include <string.h>
#include <stdio.h>#include <fcntl.h>
#include <unistd.h>#define MAX_SIZE 1024
in( main(void){
int fH;char buf[MAX_SIZE];
char get(MAX_SIZE];char devName[20], dir[50] = "/dev/";
systcm("ls /dev/");printf("Plcasc input the device's name you wanna to use gets(devName);
srrcat(dir, devName);fd = open(dir, O_RDWR | O_NONBLOCK);
if(fd !=-1){
read(fd, buf, sizeof(buf));printff'The device was ini ted with a string: %s\n", buf);
/*测试写*/printf("Please input a string :\n");
gets(get);write(fcl, get, sizeof(get));
/*测试读*/
rcad(fd, bug sizcof(buf));
systcmf'dmcsg");
printf("\nThc string in the device now is : %s\n", buf); closc(fd);
return 0;} else
printf("Device open failed\n"); return -1;makefile:
ifeq (S(KERNELRELEASE),)KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)modules:
S(MAKE) -C S(KF.RNELDIR) M=$(PWD) modules modulcs_install:
S(MAKE) -C $(KERNEIJD1R) M=$(PWD) modulcsjnstall clean:
rm -rf *.o *~ core .depend .* d *.ko *.mcd.c .tmp_versions .PHONY: modules modulcs_install cleanelse
obj-m := mydev.oendif
实验四:
#include <gtk/gtk.h>//gcc -o lab4 lab4.c pkg-config -cflags -libs gtk+-2.0'
char *txt_pid=NULL;GtkWidget *labell;
char* get_cpu_name(char *bufl){ 〃获取 epu 名称FILE * fp;
int i = 0;char *buf_ = bufl;
fp = fopen("/proc/cpuinfo","r");for(i = 0;iv5j++){
fgets(bufl,256,fp);}
fbr(i = 0p<256p++)(if(buf_[i] == ':*) break;
}i = i+2;
buf_ = buf_ + i;buf_[31] = '\0';
fclose(fp);return buf_;
}char* get_cpu_type(char *buf2) { //epu 类型
FILE * fp;int i = 0;
char *buf_ = buf2;fj) — fopenf'/proc/cpuinfo"^^');
fbr(i = 0p<2p++){fgcts(bufl,256,fp);
}fbr(i = O;iv2560++){
if(buL[i] == ':) break;}
i = i+2;buf_ = buf_ + i;
buL[12] = 8;fclose(fj));
return bull;
char* gct_cpu_f(char *buf3) { //cpu 主频
FILE * fp;
int i = 0;
char +buf_ = buf3;
fp = fopenf 7 proc/cpuinfb',,',r'*);
for(i = 0;iv7;i++){fgcts(buL,256,fp);
}
fbr(i = 0;i<256;i++){== ':*) break;
}
i = i+2;
buf_ = buf_ + i;
buL[8] = '\0';
fclose(fp);
return buf_;}
char *get_os_type(char *bufl) {
FILE * 企;
char *buf_ = bufl;
fp = fbpenf/etc/issue","r"); fgets(buf_J3,fp); sprintf(buf_,"%s\O",bufJ;
fclose(fp);
return buj}
char *gct_os_vcrsion(char *buf2) (
FILE * fp;
char *buf_ = buf2;
fp 二 fopenf'/proc/version","r"); fgets(buf_,20,fp); sprintf(buf_,"%s\O,'.buf_);
fclose(fp);
return buf_;}
void cpu_usage() {
FILE *fp;
char cpu[5];
char bufffl000] = {0};
char s[l000] = {0};
long int user,nice,sys,idle,iowait,irq,softirq;
long int si ,s2,idlc1 ,idlc2;
float usage;
\vhile(l){
fp = fopenf 7 proc/stat","r"); if(fp == NULL){ pcrrorf'fbpcn"); exit(0);fgets(buff,sizeof(l)uff),fp);//从文件构造体指针中读取数据
sscanf(bufF,"%s%d%d%d%d%d%d%d”,cpu,&uscr,&nicc,&sys,&idle,&io\vait,&irq,&softirq); s1 = user+nice+sys+idle+iowait+irq+softirq;idld = idle;
rewind(fp);sleep(l);
//mcmset(buff,0,sizeof(buff));
//cpu[0] = 'O';
user = nice = sys = idle = iowait = irq = softirq = 0; fgcts(buff,sizcof(buff),fp);
sscanf(buff,"%s%d%d%d%d%d%d%d”,cpu,&user,&nice,&sys,&idle,&io\vait,&irq,&softirq); s2 = user+nice+sys+idle+iowair+irq+softirq;idle2 = idle;
usage = (float)(s2 - si - (idlc2-idlel))/(s2 - si)* 100;sprintf(s,"CPU 利用率为%f%% ",usage);
gclk_threads_enter();gtk Jabcl_set_text(GTK_I.ABEL(labcl 1 ),s);
gdk_thrcads_lcave();fclose(fp);
slccp(l);
}}
void select_ro\v_callback(GtkWidget *clist,gint ro\v,gint column,GdkEventButton *event,gpointer data) {
gtk_clist_gct_tcxt(GTK_CLIST(clist),row,column,&txt_pid); printf(H%s\n",txt_pid);}
void refresh(GtkWidget *clist){
DIR *dir;
struct dirent *ptr;
int i,j;
FILE *fp;
char buQ1024];
char _buffcr[1024];
char *buffer=_buffer;
char *buffer2;
char proc_pid[1024];
char proc_name[1024];
char proc_stat[1024];
char proc_pri[1024];
char proc_takeup[10241;
char text[5][1024];
gchar *txt[5];
gtk_clist_clcar(GTK_CLIST(clist)); gtk_clist_sct_column_tide(GTK_CLIST(clist),0,"PlD"); gtk_clist_set_column_titlc(GTK_CLIST(clist),l,H 名称”); gtk_clist_ser_column_tide(GTK_CLIST(clisr),2;'状态) gtk_clist_set_column_title(GTK_CLIST(clist),3,” 优先级”); gtk_clist_sct_column_titlc(GTK_CLIST(clist),4,”占用内存, gtk_clist_set_column_\vidth(GTK_CLIST(clist),0,50); gtk_clist_set_column_width(GTK_CLIST(clist),l ,100); gtk_clist_set_column_\vidth(GTK_CLIST(clist),2,50); gtk_clist_set_column_\vidth(GTK_CLIST(clist),3,50);
gtk_clist_set_column_\vidth(GTK_CLIST(clist),4,55); gtk_clist_coIumn_titlcs_sho\v(GTK_CLIST(clist)); dir=opendir('7 proc");
while(ptr=readdir(dir)) {i f((prr->d_namc) [0] >=48&&(ptr->d_name) [0] <=57) { sprintf(buf,"/proc/%s/stat",ptr->d_name);
fp=fopcn (b u f," r");
fgcts(buffcr,1024,fp); fclose(fp);
for(i=0;i<1024^++){
if(bufferO]==' *) break;
}
buffcr[i]=,\0,;
strcpy(proc_pid,buffer);
i+=2; buffcr+=i;fbr(i=0;ivl024;i++){
if(buffcr[ij==')*) break;}
buffer]]二'\0'; strcpy(proc_name,buffer);
i+=2;
buffcr2=buffcr+i; buffer2[l]='\0,;
strcpy(proc_stat,huffbr2); for(i=O,j=O;i< 1024&&j V15;i++) { if(buffer2p]==, *) j++;
) buffer2+=i;for(i=0;ivl024;i++){
if(buffer2p]==' *) break;
} buffcr2[i]=,\0,;
strcpy(proc_pri,buffer2); for(j=0;i<l 024&&j V4;i++) {
if(buffer2p]==' *) j++;
} buffcr2+=i; for(i=0;i<1024;i++){ if(bufQr2[i]二二'*) break;
} buffcr2[i]=,\0,;
strcpy(proc_takcup,buffcr2);
展开阅读全文