2006年04月05日

道格的确应该感到迷惑,杀手不是来自过去,却是来自未来。

有关虚拟与现实主题的电影似乎很多,也许主题相似的缘故,总有人将《异次元骇客》和《骇客帝国》相比,我是个《骇客帝国》迷,可以不厌其烦的看上7遍,现在看电影没有那样的激情了。这部《异次元骇客》好像又令我找到了那种感觉。不考虑影片的投资,“绝不逊色于《黑客帝国》”这句评价确不为过。

如果真的有虚拟与现实的世界,我希望我在最顶层。

2006年04月04日

#include <iostream>

using namespace std;

char msg[] = "Now is the time \n";//字符型数组

int main (){
 char *cp;//指向char的指针
 int i;//整数下标
 
 //指针访问,指针表示法
 for(cp=msg;*cp;cp++){
  cout<<*cp;
 }
 
 //下标访问,下标表示法
 for(i=0;msg[i];i++){
  cout<<msg[i];
 }
 
 //指针访问,下标表示法
 for(cp=msg;cp[0];cp++){
  cout<<cp[0];
 }
 
 //下标访问,指针表示法
 for(i=0;*(msg+i);i++){
  cout<<*(msg+i);
 }
 
 //指针和下标访问,指针表示法
 for(i=0,cp=msg;*(cp+i);i++){
  cout<<*(cp+i);
 }
 
 //指针和下标访问,下标表示法
 for(i=0,cp=msg;cp[i];i++){
  cout<<cp[i];
 }
 
 return 0;
}

本程序建立一个菜单选择程序,主要是练习函数指针数组的使用。

#include <iostream>

using namespace std;

struct Menu{

    char* neme;

    void (*ftrp)();

};

void FileFunc();

void EditFunc();

void ViewFunc();

void ExitFunc();

Menu theMenu[]={

    {"File",FileFunc};

    {"Edit",EditFunc};

    {"View",ViewFunc};

    {"Exit",ExitFunc};

};

int main(){

    int cho=0;

    while(cho!=4){

        for(int i=0;i<4;i++)

            cout<<i+1<<" : "<<theMenu[i].name<<endl;

        cout<<"You Choice :"<<endl;

        cin>>cho;

        if(cho>=5)

            cout<<"Error InPut !";

        else if(cho<5)

            (*theMenu[cho-1].ftpr)();

   }

    return 0;

}

voie FileFunc(){

    cout<<"File Function"<<endl;

}

voie EditFunc(){

    cout<<"Edit Function"<<endl;

}

voie ViewFunc(){

    cout<<"View Function"<<endl;

}

voie ExitFunc(){

    cout<<"Exit Function"<<endl;

}

2006年04月02日

1.把C++当成一门新的语言学习(和C没啥关系!真的。);

  2.看《Thinking In C++》,不要看《C++变成死相》;

  3.看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看;

  4.不要被VC、BCB、BC、MC、TC等词汇所迷惑——他们都是集成开发环境,而我们要学的是一门语言;

  5.不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可以引伸出很多知识点;

  6.会用Visual C++,并不说明你会C++;

  7.学class并不难,template、STL、generic programming也不过如此——难的是长期坚持实践和不遗余力的博览群书;

  8.如果不是天才的话,想学编程就不要想玩游戏——你以为你做到了,其实你的C++水平并没有和你通关的能力一起变高——其实可以时刻记住:学C++是为了编游戏的;

  9.看Visual C++的书,是学不了C++语言的;

  10.浮躁的人容易说:XX语言不行了,应该学YY;——是你自己不行了吧!?

  11.浮躁的人容易问:我到底该学什么;——别问,学就对了;

  12.浮躁的人容易问:XX有钱途吗;——建议你去抢银行;

  13.浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!

  14.浮躁的人容易问:XX和YY哪个好;——告诉你吧,都好——只要你学就行;

  15.浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;

  16.把时髦的技术挂在嘴边,还不如把过时的技术记在心里;

  17.C++不仅仅是支持面向对象的程序设计语言;

  18.学习编程最好的方法之一就是阅读源代码;

  19.在任何时刻都不要认为自己手中的书已经足够了;

  20.请阅读《The Standard C++ Bible》(中文版:标准C++宝典),掌握C++标准;

  21.看得懂的书,请仔细看;看不懂的书,请硬着头皮看;

  22.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;

  23.请看《Effective C++》和《More Effective C++》以及《Exceptional C++》;

  24.不要停留在集成开发环境的摇篮上,要学会控制集成开发环境,还要学会用命令行方式处理程序;

  25.和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好;

  26.请看《程序设计实践》,并严格的按照其要求去做;

  27.不要因为C和C++中有一些语法和关键字看上去相同,就认为它们的意义和作用完全一样;

  28.C++绝不是所谓的C的“扩充”——如果C++一开始就起名叫Z语言,你一定不会把C和Z语言联系得那么紧密;

  29.请不要认为学过XX语言再改学C++会有什么问题——你只不过又在学一门全新的语言而已;

  30.读完了《Inside The C++ Object Model》以后再来认定自己是不是已经学会了C++;

  31.学习编程的秘诀是:编程,编程,再编程;

  32.请留意下列书籍:《C++面向对象高效编程(C++ Effective Object-Oriented Software Construction)》《面向对象软件构造(Object-Oriented Software Construction)》《设计模式(Design Patterns)》《The Art of Computer Programming》;

  33.记住:面向对象技术不只是C++专有的;

  34.请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码;

  35.把在书中看到的有意义的例子扩充;

  36.请重视C++中的异常处理技术,并将其切实的运用到自己的程序中;

  37.经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去;

  38.不要漏掉书中任何一个练习题——请全部做完并记录下解题思路;

  39.C++语言和C++的集成开发环境要同时学习和掌握;

  40.既然决定了学C++,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设计技术,而程序设计技术是跨语言的;

  41.就让C++语言的各种平台和开发环境去激烈的竞争吧,我们要以学习C++语言本身为主;

  42.当你写C++程序写到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设计和编写(参见43);

  43.别心急,设计C++的class确实不容易;自己程序中的class和自己的class设计水平是在不断的编程实践中完善和发展的;

  44.决不要因为程序“很小”就不遵循某些你不熟练的规则——好习惯是培养出来的,而不是一次记住的;

  45.每学到一个C++难点的时候,尝试着对别人讲解这个知识点并让他理解——你能讲清楚才说明你真的理解了;

  46.记录下在和别人交流时发现的自己忽视或不理解的知识点;

  47.请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成Version 100.XX;

  48.保存好你写过的所有的程序——那是你最好的积累之一;

  49.请不要做浮躁的人;

  50.请热爱C++!

2006年03月31日

又看了个电影:《百慕大》,悬念是渲染得够味了,可给我更多的感觉却是胡扯,当茶余饭后的谈资却是不错。

2006年03月05日

Linux课程设计已经过去了,不过组成原理的就快来了,但是我还是想抽点时间来学习C++,废话少说,现在就开始吧。

2006年03月03日

今天课程设计检查,结果很是令我满意,虽然没有按照预定的忙上两个星期,但这段时间还是很辛苦的。现在可以放下一个阶段了,也该准备下个星期的组成原理课程设计了。组成课设可要抓紧时间认真对待了,不能像这次这样糊里糊涂了!哈哈,准备迎接下一个好心情了!

此文叙述了增加copy系统功能调用(本次实验同时做了p,v操作的系统功能调用,但我的那个程序的原创部分太少,不便贴出)的方法,在2.4.22内核下编译通过。可以任意使用,主要有以下几个步骤:

1,在/usr/src/linux-2.4.22/kernel/sys.c的最后添加:

asmlinkage void sys_mycopy(char * infile,char * outfile)
{
 int infiled,outfiled,count;
 char buf[256];
 mm_segment_t fs; //堆栈保护
 fs=get_fs();
 set_fs(get_ds());
 infiled=sys_open(infile,O_RDONLY,0);
 if(infiled== -1)
  printk("Opening InFile Failed !\n");
 outfiled=sys_open(outfile,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR);
 if(outfiled== -1)
  printk("Open or Creat OutFile Failed !\n");

 while((count=sys_read(infiled,buf,256))>0)
  if(sys_write(outfiled,buf,count)!=count)
   printk("Writing Failed !\n");
  if(count==-1)
   printk("Reading Failed !\n");
  sys_close(infiled);
  sys_close(outfiled);
  set_fs(fs);
}

2

/usr/include/asm/unistd.h/usr/src/linux-2.4.22/include/asm-i386/unistd.h两个unistd.h文件中添加:

#define __NR_mycopy  235

注意:末尾的号是可以修改的,但最好不要超过255,若相同的号已经被使用可以将原来的替换掉(加上注释)。

 3,在/usr/src/linux-2.4.22/arch/i386/kernel/entry.s文件中添加:

.long SYMBOL_NAME(sys_mycopy)

注意:若此文件的最后一项的有关数据是根据表长而定的则不必修改,否则修改,使其值加1(因为增加了一个系统功能)。

4,依次执行:make mrproper (若是第一次编译,此命令跳过),make xconfig ( 修改File Systems表项,将其中有关ext3文件格式都选择为 Y,根据你的CPU型号修改CPU选项( 左面由上到下第三项)等等,例如有的需要修改对usb的支持,请看各项的帮助信息),make dep,make clean ,make bzImage(若此步没有错误则基本成功),make modules ,make modules_install ,make install 。

5,修改boot/grub/grub.conf中的内容,将表下相关系统(本系统为2.4.22一行末尾)的=LABL=/改为表前几行中的硬盘号(如=/dev/hda8),重新启动系统,进入刚刚编译成的内核。

6,编写测试程序:

源码:

//testcopy.c

#include<linux/unistd.h>
_syscall2(int,mycopy,char *, infile,char * ,outfile)
int errno;
int main(int argc,char * argv[])
{
 mycopy(argv[1],argv[2]);
 return 0;
}
编译:gcc testcopy.c -o testcopy

运行:./testcopy

.long SYMBOL_NAME(sys_mycopy)

注意:若此文件的最后一项的有关数据是根据表长而定的则不必修改,否则修改,使其值加1(因为增加了一个系统功能)。

4,依次执行:make mrproper (若是第一次编译,此命令跳过),make xconfig ( 修改File Systems表项,将其中有关ext3文件格式都选择为 Y,根据你的CPU型号修改CPU选项( 左面由上到下第三项)等等,例如有的需要修改对usb的支持,请看各项的帮助信息),make dep,make clean ,make bzImage(若此步没有错误则基本成功),make modules ,make modules_install ,make install 。

5,修改boot/grub/grub.conf中的内容,将表下相关系统(本系统为2.4.22一行末尾)的=LABL=/改为表前几行中的硬盘号(如=/dev/hda8),重新启动系统,进入刚刚编译成的内核。

6,编写测试程序:

源码:

//testcopy.c

#include<linux/unistd.h>
_syscall2(int,mycopy,char *, infile,char * ,outfile)
int errno;
int main(int argc,char * argv[])
{
 mycopy(argv[1],argv[2]);
 return 0;
}
编译:gcc testcopy.c -o testcopy

运行:./testcopy

在redhat2.4.20-8下编译通过:

由于本程序窗口部分由glad工具编制,源代码不易贴出,现只给出部分回调函数的代码:

1,“退出”按钮回调函数:

void
on_button9_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
 gtk_main_quit();
}

2,“关机”按钮回调函数:

void
on_button10_clicked                    (GtkButton       *button,
                                        gpointer         user_data)
{
 system("halt");
}

3,“重新启动”按钮回调函数:

void
on_button11_clicked                    (GtkButton       *button,
                                        gpointer         user_data)
{
 system("reboot");
}

4,“主机名”字符块回调函数:

void
on_label38_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 FILE * fp;
 char buf[256];
 fp=fopen("/proc/sys/kernel/hostname","r");
 fgets(buf,256,fp);
 fclose(fp);
 gtk_label_set_text(widget,buf);
}

5,“CPU型号”字符块回调函数:

void
on_label45_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 
 FILE * fp;
 int i,j=0;
 char buf[256],buf1[256];
   fp=fopen("/proc/cpuinfo","r");
 for(i=0;i<5;i++){
  fgets(buf,256,fp);
 }
 for(i=0;i<256;i++){
  if(buf[i]==’:') break;
 }
 i+=2;
 for(;i<256;i++){
  if(buf[i]==’ ‘) break;
 }
 i+=1;
 while(i<256){
  if(buf[i]==’ ‘){
   i++;
  }
  else{
   buf1[j]=buf[i];
   j++;
   i++;
  }
 }
 fclose(fp);
  gtk_label_set_text(widget,buf1);//cpu型号
}

6,“CPU主频”回调函数:

void
on_label46_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 
 FILE * fp;
 int i,j=0;
 char buf[256],buf1[256];
   fp=fopen("/proc/cpuinfo","r");
 for(i=0;i<7;i++){
  fgets(buf,256,fp);
 }
 for(i=0;i<256;i++){
  if(buf[i]==’:') break;
 }
 i+=2;
 j=0;
 for(;i<256;i++){
  if(buf[i]==’ ‘) break;
  else{
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\0′;
 fclose(fp);
  gtk_label_set_text(widget,buf1);//cpu型号
}

7,“系统版本号”回调函数:

void
on_label39_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 FILE * fp;
 char buf[256];
 fp=fopen("/proc/sys/kernel/osrelease","r");
 fgets(buf,256,fp);
 fclose(fp);
 gtk_label_set_text(widget,buf);
}

8,“系统运行时间”回调函数:

void timeout_label40 (GtkWidget *widget,gpointer user_data){

FILE * fp;
 int i,j;
 char buf[64],buf1[64];
 fp=fopen("/proc/uptime","r");
 fgets(buf,64,fp);
 j=0;
 for(i=0;i<64;i++){
  if(buf[i]==’ ‘) break;
  else {
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\0′;
 fclose(fp);
 
 gtk_label_set_text(widget,buf1);
}

void
on_label40_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 gtk_timeout_add(200,timeout_label40,widget);
}

9,“CPU运行时间”回调函数:

void timeout_label42 (GtkWidget *widget,gpointer user_data)
{
 
 FILE * fp;
 int i,j;
 char buf[64],buf1[64];
 fp=fopen("/proc/uptime","r");
 fgets(buf,64,fp);
 for(i=0;i<64;i++){
  if (buf[i]==’ ‘) break;
 }
 i++;
 j=0;
 for(;i<64;i++){
  if(buf[i]==’ ‘) break;
  else {
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\\’;
 buf1[j+1]=’0′;
 fclose(fp);
 gtk_label_set_text(widget,buf1);
}

void
on_label42_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 gtk_timeout_add(200,timeout_label42,widget);
}

10,“内存信息”回调函数:

void
on_label51_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 FILE * fp;
 int i,j;
 char buf[256],buf1[256];
 fp=fopen("/proc/meminfo","r");
 fgets(buf,256,fp);
 fgets(buf,256,fp);
 for(i=0;i<256;i++){
  if (buf[i]==’:') break;
 }
 i++;
 for(;i<256;i++){
  if (buf[i]!=’ ‘) break;
 }
 j=0;
 for(;i<256;i++){
  if(buf[i]==’ ‘) break;
  else {
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\0′;
 fclose(fp);
 gtk_label_set_text(widget,buf1);
}

11,“SWAP信息”回调函数:

void
on_label53_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 FILE * fp;
 int i,j;
 char buf[256],buf1[256];
 fp=fopen("/proc/meminfo","r");
 fgets(buf,256,fp);
 fgets(buf,256,fp);
 fgets(buf,256,fp);
 for(i=0;i<256;i++){
  if (buf[i]==’:') break;
 }
 i++;
 for(;i<256;i++){
  if (buf[i]!=’ ‘) break;
 }
 j=0;
 for(;i<256;i++){
  if(buf[i]==’ ‘) break;
  else {
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\0′;
 fclose(fp);
 gtk_label_set_text(widget,buf1);
}

12,“内存使用信息”回调函数:

void timeout_label52 (GtkWidget  *widget,gpointer user_data)
{
 FILE * fp;
 int i,j;
 char buf[256],buf1[256];
 fp=fopen("/proc/meminfo","r");
 fgets(buf,256,fp);
 fgets(buf,256,fp);
 for(i=0;i<256;i++){
  if (buf[i]==’:') break;
 }
 i++;
 for(;i<256;i++){
  if (buf[i]!=’ ‘) break;
 }
 for(;i<256;i++){
  if (buf[i]==’ ‘) break;
 }
 for(;i<256;i++){
  if (buf[i]!=’ ‘) break;
 }
 j=0;
 for(;i<256;i++){
  if(buf[i]==’ ‘) break;
  else {
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\0′;
 fclose(fp);
 gtk_label_set_text(widget,buf1);
}
void
on_label52_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 gtk_timeout_add(200,timeout_label52,widget);
}

13,“SWAT使用信息”回调函数:

void timeout_label54 (GtkWidget *widget, gpointer user_data)
{
 FILE * fp;
 int i,j;
 char buf[256],buf1[256];
 fp=fopen("/proc/meminfo","r");
 fgets(buf,256,fp);
 fgets(buf,256,fp);
 fgets(buf,256,fp);
 for(i=0;i<256;i++){
  if (buf[i]==’:') break;
 }
 i++;
 for(;i<256;i++){
  if (buf[i]!=’ ‘) break;
 }
 for(;i<256;i++){
  if (buf[i]==’ ‘) break;
 }
 for(;i<256;i++){
  if (buf[i]!=’ ‘) break;
 }
 j=0;
 for(;i<256;i++){
  if(buf[i]==’ ‘) break;
  else {
   buf1[j]=buf[i];
   j++;
  }
 }
 buf1[j]=’\0′;
 fclose(fp);
 gtk_label_set_text(widget,buf1);
}

void
on_label54_realize                     (GtkWidget       *widget,
                                        gpointer         user_data)
{
 gtk_timeout_add(200,timeout_label54,widget);
}

14,“进程显示”函数(此函数写在main.c中):

void procc_see(GtkWidget * window)
{
  GtkWidget *widget,*view;
  GtkTextBuffer * buffer;
  FILE *fp;
  GtkTextIter p;
  int i;
  char *buf=malloc(2048*sizeof(char));

  fp=popen("ps -l -x","r");
  /*for(i=0;i<12288;i++)
  {
    fscanf(fp,"%c",&buf[i]);
    if(buf[i]==’\0′)break;
  }
  view = lookup_widget(window,"textview1");
  buffer=gtk_text_buffer_new(NULL);
  gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), buffer);
  gtk_text_buffer_set_text(buffer,buf,-1);*/

  widget=lookup_widget(window,"textview1");
  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
  buffer = gtk_text_buffer_new(gtk_text_buffer_get_tag_table(buffer));
  gtk_text_view_set_buffer(GTK_TEXT_VIEW(widget), buffer);
  g_object_unref(G_OBJECT(buffer));
  gtk_text_buffer_get_end_iter(buffer, &p);
  while((i = fread(buf, 1, sizeof(buf), fp)) > 0) {
 GError *err = NULL;
 gsize br, bw;
 gchar *text;
 if(!(text = g_locale_to_utf8(buf, i, &br, &bw, &err))) {
     g_printerr("Failed locale to UTF-8 conversion: %s\n", err->message);
     g_clear_error(&err);
     break;
 }
 gtk_text_buffer_insert(buffer, &p, text, bw);
 g_free(text);
    }
  pclose(fp);
}

15,“查看系统类型”回调函数:和前面“查看系统版本”的回调函数是一样的,只不过要用到的文件不同。

不做赘述。

最后,用命令:./autogen.sh和make install 编译。

说明:此进程管理器实现的功能较少,不过,用此模式编写的程序很容易扩充,主要是回调函数的编写,相关内容请查看有关书籍或Google!

虚拟一个简单的字符设备驱动,在Red Hat2.4.20-8下通过:(该程序采用转自网络的代码修改而成,详细情况请查看http://bbs.whnet.edu.cn/main.html :Linux版块 —–>精华区—–> 编程解疑—–> linux课设总结之字符设备驱动)

1,编写源文件:

#define  __NO_VERSION__ 
#include<linux/version.h> /*以下是本程序包含的头文件*/
#include<linux/module.h>
#include<linux/config.h>
#include<asm/uaccess.h>
#include<linux/types.h>
#include<linux/fs.h> 
#include<linux/mm.h>
#include<linux/errno.h>
#include<asm/segment.h>
#define BUFSIZE 256  /*设备中包含的最大字符数*/

char * temp;  /*该指针用于为这个虚拟的设备分配内存空间*/
unsigned int major = 0;
static ssize_t device_read(struct file * file,char * buf,size_t count,loff_t * f_pos)
{
 int i;
 if(count>BUFSIZE){  /*如果要求读出的数目多于设备固有的数目则提示并返回*/
 printk("Can’t Read , the Count is to Big !\n");
 return  -EFAULT;
 }
 for(i = 0;i < count;i++)  /*否则,进行读出操作*/
  {__put_user(temp[i],buf);
         buf++;
        }    
 return count;
}

static ssize_t device_write(struct file * file,const char * buf,size_t count,loff_t * f_pos)
{
 int i;
 if(count>BUFSIZE){  /*要求写入的数目比设备的容量大则提示并返回*/
 printk("Can’t Write , the Count is to Big\n");  
 return  -EFAULT;
 }
 for(i = 0;i < count;i++)  /*否则,进行写入操作*/
  {__get_user(temp[i],buf);
         buf++;
        }    
 return count;
}

static int device_open(struct inode * inode,struct file * file) /*打开设备函数*/
{
 temp = (char *)kmalloc(BUFSIZE,GFP_KERNEL);  /*为设备分配内存空间*/
 MOD_INC_USE_COUNT;
 return 0;
}

static int device_release(struct inode * inode,struct file * file)
{
 kfree(temp);   /*释放设备占用内存空间*/
 MOD_DEC_USE_COUNT;
 return 0;
}

struct file_operations fops = { /*填充file_operations结构*/
 read:device_read,
        write:device_write,
        open:device_open,
        release:device_release
};
   
int init_module(void)  /*登记设备函数,insmod时调用*/
{
 int num;
 num = register_chrdev(0,"mydriver",&fops); /*系统自动返回一个未被占用的设备号*/
 if(num < 0){     /*登记未成功,提示并返回*/
  printk("Can’t Got the Major Number !\n");
    return num;
 }
 if(major == 0)
 major = num;
 return 0;
}

void cleanup_module(void)  /*释放设备函数,rmmod时调用*/
{
 unregister_chrdev(major,"mydriver");
}

命名为"mydriver.c"

2,编译文件:

gcc -O2 -Wall -DMODULE -D__KERNEL__ -DLINUX -I/usr/src/linux-2.4.20-8/include -c mydriver.c

3,装载驱动:

insmod -f mydriver.o

用:lsmod可以看到mydriver.o

用:cat /proc/mydevice查看该设备的主设备号,在我的系统上为254

4,创建设备文件:mknod /dev/myDriver c 254 0 (其中myDriver为文件名,注意和下面的测试程序中打开的文件名一致,c代表此为字符设备,254位主设备号,0为从设备号,一般为0)
5,编译测试程序:test.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(void)
{
 int fd;
 int i;
  char *buf="1234567890abcdefghij\n";
  char buf1[22];
 
 fd = open("/dev/myDriver",O_RDWR); /*此处myDriver和建立设备文件时的名称一致*/
 if (fd == -1)
 {
  printf("Can’t open file \n");
  exit(-1);
 }   
 write(fd,buf,22);
 read(fd,buf1,22);
 for(i=0;i<22;i++)
    printf("%c",buf1[i]);
 close(fd);
 return 0;
}

编译并运行:gcc test.c -o test

                       ./test

注:以上只声明了增加驱动程序的步骤和给出了源代码 ,详细情况请见文首的链接。