linux设备学习学习(一)
    linux设备学习学习(一) 
2010年08月23日
  地球人都知道LDD这书经典,但一直没时间看(貌似是借口)现在开始啃,希望自己能坚持下去。God bless me! 
  要看到内核的打印信息,可以先执行下面的语句:echo 8 >/proc/sys/kernel/printk 
  这里,有blog不错,可以学习下http://blog.chinaunix.net/u1/34474/showart_404278. html 
  由于驱动程序可能同时被不同的程序并发访问,解决并发的一些方法:1.可以在设备上实现独立于硬件功能的内存映射。 
  2. 为用户提供独立的函数库,运用同步原语。 
  3.设备文件和普通文件之间的唯一区别在于:对普通文件的访问可以前后移动访问访问位置,但对大多数字符设备文件的访问只能顺序访问。 
  4.许多网络连接是面向流的,但网络设备却围绕数据包的传输和接受而设计。网络驱动程序不需要知道各个连接的相关信息,他只要处理数据包即可。由于不是面向流的设备,因此将网络接口映射到文件系统中的节点比较困难,linux访问网络接口的方法仍然是给他们一个唯一的名字(eth0),但这个名字在文件系统中不存在对应的节点。内核和网络设备的通信,不同于字符和块设备,内核调用一套和数据包传输相关的函数,而不是read,write. 
  5.关于hello模块Makefile的写法: 
  obj-m += hello.o 
  KDIR = /lib/modules/$(shell uname -r)/build 
  PWD = $(shell pwd) 
  all: 
  make -C $(KDIR) M=$(PWD) modules 
  clean: 
  make -C $(KDIR) M=$(PWD) clean 
  如果是多个原文件编译出一个模块,则不能出现.c 文件。 
  obj-m += test.o 
  test.o := file1.o file2.o file3.o 
  KDIR = /lib/modules/$(shell uname -r)/build 
  PWD = $(shell pwd) 
  all: 
  make -C $(KDIR) M=$(PWD) modules 
  clean: 
  make -C $(KDIR) m=$(PWD) clean 
  其中KDIR为内核存放的路径,PWD当前路径,uname -r为取得当前使用的内核配置。 
  6.现代的unix系统基本提供两种保护方式:一种是特权级划分,0到6个级别,ROOT的特权级最高。另一种是分页保护机制,系统除了在启动完成设备初始化时运行在实模式下外,启动起来会开启MMU然后运行在保护模式下。 
  7.执行系统调用的内核代码运行在进程上下文中,它代表调用进行执行操作,因此可以访问进程地址空间里的所有数据,而处理硬件中断的内核代码和进程是异步的,与任何一个特定进程无关。 
  8.modprobe和insmod的区别,它会考虑要装载的模块是否引用了一些当前内核不存在的符号。如果有这类引用modprobe会在当前模块的收索路径中查找定义了这些符号的其他模块,如果找到这些依赖模块会同时将这些模块加载到内核中。如果这种情况下用insmod,则会失败。 
  9.大多数模块都必须包括的头文件: 
  #include  
  #include  
  #include  
  10.如果在发生某个特定类型的错误以后无法继续装载模块,则要将出错之前的任何注册工作撤销掉。 
  模块注册代码示例: 
  #include  
  #include  
  #include  
  struct something *item1; 
  struct somethingelse *item2; 
  int stuff_ok; 
  void my_cleanup() 
  { 
  if(item1) 
  release_thing(item1); 
  if(item2){ 
  release_thing(item2); 
  if(stuff_ok) 
  unregister_stuff; 
  } 
  static int __init my_init(void) 
  { 
  int err; 
  item1 = allocate_thing(arguments); 
  item2 = allocate_thing(arguments2); 
  if(!item1 || !item2) 
  goto fail; 
  err = register_stuff(item1,item2); 
  if(!err){ 
  stuff_ok = 1; 
  }else{ 
  goto fail;    }    return 0;  fail:     my_cleanup();     return err; } 11.include  该文件包含驱动驱动程序中使用的大部分内核API的定义,包括睡眠函数以及各种变量的声明。 
  struct task_struct *current; 
  current->pid 
  current->comm 
  获得当前进程的id和命令名 
  MAJOR(dev_t dev); 
  MINOR(dev_t dev); 
  MKDEV(int major,int minor);