




已阅读5页,还剩16页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一共有4个部分,但最后一个代码量过大,没有写出来,不过我上传到了csdn上,叫“ubuntu下用gtk实现仿windows资源管理器”比较有借鉴意义的可能就是后3个吧。一、目的1、掌握Linux操作系统的使用方法;2、了解Linux系统内核代码结构;3、掌握实例操作系统的实现方法。二、实验内容1、掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。编一个C程序,其内容为实现文件拷贝的功能;编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库。2、掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。另编写一个应用程序,调用新增加的系统调用。实现的功能是:文件拷贝;3、掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。实现字符设备的驱动4、了解和掌握/proc文件系统的特点和使用方法了解/proc文件的特点和使用方法监控系统状态,显示系统中若干部件使用情况用图形界面实现系统监控状态。5、文件系统(选作)三、系统环境1、硬件环境:处理器:Intel(R)Core(TM)2DuoCPUT72502.00GHz2.00GHz内存(RAM):1526MB2、软件环境:操作系统:ubuntu9.10内核版本:linux2.6.32.10四、设计与实现11、文件拷贝文件拷贝函数本身并不是很难,主要是用到了一些现有的函数如fprintf等。在最开始写这个函数的时候,我只写了打开、创建和拷贝的那一部分,代码量很少,没有过多的去考虑当出现了错误时的情况。后来我在网上接触到了一些比较优秀的拷贝代码,意识到了对于拷贝失败时的情况要输出错误信息,就增加了比较多的条件判断和错误信息输出,才有了这个最终的版本。编译时使用的命令:gcc-otest1_1test1_1.c运行时使用的命令:./test1_1源代码#include #include #include #include #include #include #include #define BUFFER_SIZE 1024/缓冲区大小int main(int argc,char *argv)int from_fd,to_fd;int bytes_read,bytes_write;char bufferBUFFER_SIZE;/设定一个缓冲区char *ptr;if(argc!=3)/三个参数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);/*创建目的文件*/if(to_fd=open(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)/*一个致命的错误发生了*/if(bytes_read=-1)&(errno!=EINTR) break;else if(bytes_read0)ptr=buffer;while(bytes_write=write(to_fd,ptr,bytes_read)/*一个致命错误发生了*/if(bytes_write=-1)&(errno!=EINTR)break;/*写完了所有读的字节*/else if(bytes_write=bytes_read) break;/*只写了一部分,继续写*/else if(bytes_write0)ptr+=bytes_write;bytes_read-=bytes_write;/*写的时候发生的致命错误*/if(bytes_write=-1)break;close(from_fd);close(to_fd);return(1);1.2、多窗口的并发程序这里主要是设计了三个窗口,第一个窗口由一个进度条和“close”按钮组成,第二个窗口只有一个文本框不断地计数输出,第三个窗口是第一个窗口和第二个窗口的结合。程序一共涉及到四个源文件,分别是progress_bar.c、window_text.c、text_bar.c和test1_2.c。需要分别编译,最后运行test1_2运行的效果如下:下面分别列出四个文件的源代码和编译方式(1)progress_bar.c编译命令:gcc-oprogress_barprogress_bar.cpkg-config-cflags-libsgtk+-2.0源代码#include #includeGtkWidget *window;GtkWidget *table;GtkWidget *button;GtkWidget *progress_bar;/更新进度条,这样就能够看到进度条的移动gint progress_timeout( gpointer data )gdouble value;int v;char text20=0%;/使用在调整对象中设置的取值范围计算进度条的值value=gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR (progress_bar)+0.01;if (value1.0)value=0.0;v=(int)(value*100);strcpy(text, );sprintf(text,%d,v);strcat(text,%);/设置进度条的新值gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar),value);gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),text);/这是一个timeout函数,返回TRUE,这样它就能够继续被调用/如果想要结束,可以在进度条到100时,return 0;这样回调函数就会结束return TRUE;int main(int argc,char *argv)int timer;gpointer data;gtk_init(&argc,&argv);/在任何构件生成之前完成window=gtk_window_new(GTK_WINDOW_TOPLEVEL);/创建窗口gtk_window_set_title(GTK_WINDOW(window),窗口1);/设置窗口标题gtk_widget_set_usize(window, 200, 200);/设置窗口大小gtk_container_set_border_width(GTK_CONTAINER(window),5);/设置窗口边框宽度gtk_widget_show(window);/显示窗口gtk_signal_connect(GTK_OBJECT(window),destroy,GTK_SIGNAL_FUNC(gtk_main_quit),NULL);table=gtk_table_new(3,5,TRUE);/创建表格3行*5列gtk_widget_show(table);/显示表格gtk_container_add(GTK_CONTAINER(window),table);/将table1装进窗口/*创建进度条*/progress_bar=gtk_progress_bar_new();gtk_table_attach_defaults(GTK_TABLE(table),progress_bar,0,5,0,1);/进度条装进表格gtk_widget_show(progress_bar);/*加一个定时器(timer),以更新进度条的值*/timer=gtk_timeout_add(100,progress_timeout,data);/*添加一个按钮,用来退出应用程序*/button = gtk_button_new_with_label (close);gtk_table_attach_defaults(GTK_TABLE(table),button,0,5,2,3);/进度条装进表格gtk_widget_show (button);gtk_signal_connect(GTK_OBJECT(button),clicked,GTK_SIGNAL_FUNC(gtk_main_quit),NULL);gtk_main ();return 0;(2)window_text.c编译命令:gcc-owindow_textwindow_text.cpkg-config-cflags-libsgtk+-2.0源代码#define GTK_ENABLE_BROKEN#include#includeGtkWidget *window;GtkWidget *table;GtkWidget *label;GtkWidget *text;int i=0;gint text_timeout( gpointer data )char buf20;char temp10;sprintf(temp,%d,i);strcpy(buf,show text );strcat(buf,temp);strcat(buf,n);/将buf内容插入到文本构件中gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf,-1);i+;/这是一个timeout函数,返回TRUE,这样它就能够继续被调用/如果想要结束,可以在进度条到100时,return 0;这样回调函数就会结束return TRUE;int main(int argc,char *argv)GtkWidget *vscrollbar;int timer;gpointer data;gtk_init(&argc,&argv);/在任何构件生成之前完成window=gtk_window_new(GTK_WINDOW_TOPLEVEL);/创建窗口gtk_window_set_title(GTK_WINDOW(window),窗口2);/设置窗口标题gtk_widget_set_usize(window, 200, 200);/设置窗口大小gtk_container_set_border_width(GTK_CONTAINER(window),5);/设置窗口边框宽度gtk_widget_show(window);/显示窗口gtk_signal_connect(GTK_OBJECT(window),destroy,GTK_SIGNAL_FUNC(gtk_main_quit),NULL);table=gtk_table_new(11,10,TRUE);/创建表格11行*10列gtk_container_add(GTK_CONTAINER(window),table);/将table1装进窗口gtk_widget_show(table);/显示表格label=gtk_label_new(ShowText);gtk_table_attach_defaults(GTK_TABLE(table),label,0,10,0,1);gtk_widget_show (label);text=gtk_text_new(NULL,NULL);/创建文本构件gtk_widget_show(text);/显示文本构件/将文本构件装进表格gtk_table_attach_defaults(GTK_TABLE(table),text,0,9,1,11);/创建滚动条并设置其与文本同步vscrollbar=gtk_vscrollbar_new(GTK_TEXT(text)-vadj);gtk_widget_show (vscrollbar);/显示垂直滚动条gtk_table_attach_defaults (GTK_TABLE (table), vscrollbar,9,10,1,11);/将滚动条装进表格timer=gtk_timeout_add(1000,text_timeout,data);/调用回调函数,每隔1秒输出一行文本gtk_main ();return 0;(3)text_bar.c编译命令:gcc-otext_bartext_bar.cpkg-config-cflags-libsgtk+-2.0源代码#define GTK_ENABLE_BROKEN#include #includeGtkWidget *window;GtkWidget *table;GtkWidget *button;GtkWidget *progress_bar;GtkWidget *label;GtkWidget *text;int i=0;gint text_timeout( gpointer data )char buf20;char temp10;sprintf(temp,%d,i);strcpy(buf,show text_bar );strcat(buf,temp);strcat(buf,n);gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf,-1);i+;/这是一个timeout函数,返回TRUE,这样它就能够继续被调用/如果想要结束,可以在进度条到100时,return 0;这样回调函数就会结束return TRUE;/更新进度条,这样就能够看到进度条的移动gint progress_timeout( gpointer data )gdouble value;int v;char text20=0%;/使用在调整对象中设置的取值范围计算进度条的值value=gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress_bar)+0.01;if (value1.0)value=0.0;v=(int)(value*100);strcpy(text, );sprintf(text,%d,v);strcat(text,%);/设置进度条的新值gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar),value);gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),text);/这是一个timeout函数,返回TRUE,这样它就能够继续被调用/如果想要结束,可以在进度条到100时,return 0;这样回调函数就会结束return TRUE;int main(int argc,char *argv)GtkWidget *vscrollbar;int timer;gpointer data;gtk_init(&argc,&argv);/在任何构件生成之前完成window=gtk_window_new(GTK_WINDOW_TOPLEVEL);/创建窗口gtk_window_set_title(GTK_WINDOW(window),窗口3);/设置窗口标题gtk_widget_set_usize(window, 400, 400);/设置窗口大小gtk_container_set_border_width(GTK_CONTAINER(window),5);/设置窗口边框宽度gtk_widget_show(window);/显示窗口gtk_signal_connect(GTK_OBJECT(window),destroy,GTK_SIGNAL_FUNC(gtk_main_quit),NULL);table=gtk_table_new(10,8,TRUE);/创建表格10行*8列gtk_widget_show(table);/显示表格gtk_container_add(GTK_CONTAINER(window),table);/将table1装进窗口label=gtk_label_new(ShowText);gtk_table_attach_defaults(GTK_TABLE(table),label,0,8,1,2);gtk_widget_show (label);text=gtk_text_new(NULL,NULL);/创建文本构件gtk_widget_show(text);/显示文本构件/将文本构件装进表格gtk_table_attach_defaults(GTK_TABLE(table),text,0,7,2,9);/创建滚动条并设置其与文本同步vscrollbar=gtk_vscrollbar_new(GTK_TEXT(text)-vadj);gtk_widget_show (vscrollbar);/显示垂直滚动条gtk_table_attach_defaults (GTK_TABLE (table), vscrollbar,7,8,2,9);/将滚动条装进表格timer=gtk_timeout_add(1000,text_timeout,data);/*创建进度条*/progress_bar=gtk_progress_bar_new();gtk_table_attach_defaults(GTK_TABLE(table),progress_bar,0,8,0,1);/进度条装进表格gtk_widget_show(progress_bar);/*加一个定时器(timer),以更新进度条的值*/timer=gtk_timeout_add(100,progress_timeout,data);/*添加一个按钮,用来退出应用程序*/button = gtk_button_new_with_label (close);gtk_table_attach_defaults(GTK_TABLE(table),button,3,5,9,10);/进度条装进表格gtk_widget_show (button);gtk_signal_connect(GTK_OBJECT(button),clicked,GTK_SIGNAL_FUNC(gtk_main_quit),NULL);gtk_main ();return 0;(3)test1_2.c编译命令:gcc-otest1_2test1_2.c源代码#include #include #include #include #include int semid;char *finish;int p1,p2;int main (void)if(p1=fork()=0)/创建新进程execv(./progress_bar,NULL);elseif(p2=fork()=0)execv(./window_text,NULL);elseexecv(./text_bar,NULL);return 0;2、系统调用(文件拷贝)这个部分是整个课程设计中比较耗时的一个部分,但是准备的比较充分的话,也是很快就能完成的。首先要了解系统调用的原理,接着就是写一个正确的系统调用函数,需要特别注意的地方是,在系统调用函数里,很多我们之前很熟悉的函数都不能再使用了,转而要使用系统里的一些函数,比如open要换成sys_open等等。另外,系统调用函数需要使用这样的代码段:mm_segment_tfs;fs = get_fs();set_fs(get_ds();set_fs(fs);这是对内存地址的保护,如果没有这样的代码段的话,很难保证添加系统调用会成功。之后需要将你的函数加到系统调用里,这里需要修改文件:/usr/src/linux-2.6.32.10/kernel/sys.c将你的系统调用函数添加到这个函数的最后面。然后还要修改两个文件,分别是:/usr/src/linux-2.6.32.10/arch/x86/include/asm/unistd.h/usr/src/linux-2.6.32.10/arch/x86/kernel/syscall_table_32.S修改如下:当然,在对以上文件进行操作的时候,你可能需要修改用户权限,命令为:sudochmod777/当这些都做完之后,就可以进行编译了,步骤如下:sudomakemrpropersudomakemenuconfig(这里直接选择最后面的save,然后ok,再exit就可以了)sudomake之后就是漫长的一个半小时,如果你的代码和设置有什么问题的话,一般在前十分钟就会报错并停止,所以如果十分钟后你的系统还在编译的话,一般就是可以编译通过了。不过仅仅只是编译通过而已,并不能保证你的系统调用能成功。编译成功之后,还要进行下面两条命令sudomakemodules_installsudomakeinstall成功后需要在/boot下生成一个initrd.img的镜像文件,命令是:sudomkinitramfsinitrd.img-linux-2.6.32.102.6.32.10之后还要修改/boot/grub下的grub文件,在其中添加一个新的系统启动引导项,具体格式可参照其他的引导项。最后就可以重新启动机器了,在载入grub之后选择新的内核也就是linux-2.6.32.10,就进入了自己编译的内核里了。然后写一个简单的测试程序来测试系统调用是否成功。(1)系统调用函数asmlinkage int sys_mysyscall(char* sourceFile,char* destFile)int source=sys_open(sourceFile,O_RDONLY,0);int dest=sys_open(destFile,O_WRONLY|O_CREAT|O_TRUNC,0600);char buf4096;mm_segment_t fs;fs = get_fs();set_fs(get_ds();int i;if(source0 & dest0)doi=sys_read(source,buf,4096);sys_write(dest,buf,i);while(i);elseprintk(Error!);sys_close(source);sys_close(dest);set_fs(fs);return 10;(2)测试程序#include #include #include int main(int argc,char*argv)int i=syscall(338,argv1,argv2);printf(successfully!rn);printf(%d,i);return 1;3、字符设备驱动要实现一个字符设别驱动,首先就是要编写一个字符设备驱动程序和用来make它的makefile文件。之后将这个设备驱动加入到linux的系统中就可以了,整个过程比较简单,命令如下:sudomakesudoinsmodchardev.ko(此处可用sudolsmod看看是否成功)sudomknod/dev/chardev0 c 255 0(chardev0是设备名,c代表字符设备,255是主设备号,0是从设备号)然后在写一个测试程序测试就可以了。这里我只给了这个设备一个字符的缓冲区大小。我的读写测试程序是分开的,就是有一个程序读,另一个程序写。源代码(1)字符驱动设备程序#include #include #include #include #include MODULE_LICENSE(GPL);MODULE_AUTHOR(SH);#define DP_MAJOR 255#define DP_MINOR 0/*具体的操作函数声明*/static ssize_t char_read(struct file *, char *, size_t, loff_t*);static ssize_t char_write(struct file *, const char *, size_t, loff_t*);static ssize_t char_open(struct inode *,struct file *);static ssize_t char_release(struct inode *,struct file *);/* file_operations结构体*/struct file_operations char_ops = .read = char_read,.write = char_write,.open = char_open,.release = char_release,;/*字符设备的缓冲区*/static char buffer = c;static int dev_open;/*初始化*/static int _init char_init(void)int ret;ret = register_chrdev(DP_MAJOR,chardev,&char_ops);/注册设备if(ret)printk(chardev register failure);elseprintk(chardev register success);return ret;/*退出*/static void _exit char_exit(void)printk(unregister.);unregister_chrdev(DP_MAJOR,chardev);/注销/*打开一个设备*/static ssize_t char_open(struct inode *inode,struct file *file)if(dev_open=0)dev_open+;elseprintk(KERN_ALERTAnother process open the char devicen);return -1;try_module_get(THIS_MODULE);return 0;/*关闭一个设备*/static ssize_t char_release(struct inode *inode,struct file *file)if(dev_open=1)dev_open-;module_put(THIS_MODULE);return 0;/*读取缓冲区内容*/static ssize_t char_read(struct file *filp, char *buf, size_t len, loff_t *off)if(copy_to_user(buf,&buffer,sizeof(int)return - EFAULT;return sizeof(int);/*向缓冲区中写入内容*/static ssize_t char_write(struct file *filp, const char *buf, size_t len, loff_t *off)if(copy_from_user(&buffer,buf,sizeof(int)return - EFAULT;return sizeof(int);module_init(char_init);module_exit(char_exit);(2)makefile文件ifeq ($(KERNELRELEASE),)KERNELDIR ?=/usr/src/linux-2.6.32.10/PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD)modules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD)modules_installclean:rm -rf *.o *core .depend .*.cmd *.ko *.mod.c tmp_versions.PHONY:modules modules_install cleanelseobj-m := chardev.oendif(3)测试程序test_read.c#include #include #include #include #include #include #include int main(void)int testdev;int i;char buf;testdev = open(/dev/chardev0,O_RDWR);if ( testdev = -1 )printf(Cannt open file n%dn,testdev);exit(0);memset(&buf, 0, sizeof(char);read(testdev,&buf,sizeof(char);printf(%cn,buf);close(testdev);return 0;(4)测试程序test_write.c#include #include #include #include #include #include #include int main(void)int testdev;int i;char buf;testdev = open(/dev/chardev0,O_RDWR);if ( testdev = -1 )printf(Cannt open file n%dn,testdev);exit(0);printf(please input the number writtenn);scanf(%c,&buf);write(testdev,&buf,sizeof(char);close(testdev);return 0;4、任务管理器这个程序基本上是参照了windows下的任务管理器来写的,所以基本上就叫做任务管理器了。整个管理器的图形部分是由GTK编写的,用到了一些常用构件和容器比如label、progress_bar、notebook等,还用到了一些其他构件比如GtkListStore、GtkTreeViewColumn、GtkTreeIter等。整个程序还是有一定的复杂性的,但总的来说终点主要是在两个方面,一个是从/proc文件夹下读取所需要的系统信息并进行加工利用,另一个就是是用GTK完成整个界面的设计。由于代码量还是有一点大,这里无法详细的进行解释,所以请参照代码的注释和程序运行的结果理解。本程序的源代码经过了一定的整理,在结构上还是比较清晰的,而且在关键的地方都有注释,包括相应的信息是从哪个文件读取的等等。程序运行的结果如下:袁节膅薂羄肅蒃薁蚃芀荿薀螆肃芅蕿袈芈膁蚈羀肁蒀蚇蚀袄莆蚇螂肀莂蚆羅袂芈蚅蚄膈膄蚄螇羁蒂蚃衿膆莈蚂羁罿芄螁蚁膄膀螁螃羇葿螀袅膃蒅蝿肈羆莁螈螇芁芇莄袀肄膃莄羂艿蒂莃蚂肂莈蒂螄芈芄蒁袆肀膀蒀罿袃薈葿螈聿蒄葿袁羁莀蒈羃膇芆蒇蚃羀膂蒆螅膅蒁薅袇羈莇薄罿膄芃薃虿羆艿薃袁节膅薂羄肅蒃薁蚃芀荿薀螆肃芅蕿袈芈膁蚈羀肁蒀蚇蚀袄莆蚇螂肀莂蚆羅袂芈蚅蚄膈膄蚄螇羁蒂蚃衿膆莈蚂羁罿芄螁蚁膄膀螁螃羇葿螀袅膃蒅蝿肈羆莁螈螇芁芇莄袀肄膃莄羂艿蒂莃蚂肂莈蒂螄芈芄蒁袆肀膀蒀罿袃薈葿螈聿蒄葿袁羁莀蒈羃膇芆蒇蚃羀膂蒆螅膅蒁薅袇羈莇袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈肀肁芀蚁羆肁莃袆袂肀薅虿袈聿蚇蒂膇肈莇螇肃肇葿薀罿肆薂螆袅肅芁薈螁膅莃螄聿膄蒆薇羅膃蚈螂羁膂莈蚅袇膁蒀袀螃膀薂蚃肂腿节衿羈腿莄蚂袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 低压电工考试题库全集及答案
- 填埋场安规考试题及答案
- 天津食品生产考试试题及答案
- 2025年高级财务会计考试题库及答案
- 2025年高层次会计人才考试题库(附答案)
- 会计材料采购题库及答案
- 行业招标投标管理办法
- 下属企业资产管理办法
- 个人业务会规管理办法
- 上海物业招标管理办法
- 中国凸轮式自动车床行业市场规模及投资前景预测分析报告
- 数据标注教学课件
- 2025至2030中国HTCC陶瓷基板市场销售模式及竞争前景分析报告
- 房屋过户买卖合同贷款事宜范本
- 幕墙施工安全课件
- 子宫腺肌症教学护理查房
- 2025至2030年中国肌肽行业市场调查研究及未来趋势预测报告
- 中国可见光通信项目创业计划书
- 生物●广东卷丨2023年广东省普通高中学业水平选择性考试生物试卷及答案
- 恒瑞医药基础管理制度
- 化肥质量安全管理制度
评论
0/150
提交评论