Chinaunix首页 | 论坛 | 博客
  • 博客访问: 805014
  • 博文数量: 87
  • 博客积分: 2571
  • 博客等级: 少校
  • 技术积分: 726
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-19 15:04
个人简介

重新开始,做回自我,爱拼的男人最牛!

文章分类
文章存档

2021年(2)

2020年(3)

2019年(17)

2014年(1)

2011年(1)

2010年(63)

我的朋友

分类: LINUX

2010-01-27 10:23:24

 Linux 2.6 和 2.4 的比较我不想废话,总体来说 2.6 功能更强,但是资源消耗更多。
  由于 2.6 内核在驱动框架,底层调用上和 2.4 内核有很多差别,所以本文主要是为程序员提供 2.4 到 2.6 迁移的指导。
  2.6 和 2.4 主要的不同在于
  • 内核的 API 变化,增加了不少新功能(例如 mem pool )
  • 提供 sysfs 用于描述设备树
  • 驱动模块从 .o 变为 .ko
  移植 hello word 下面是一个最简单的 2.4 驱动:
  #define MODULE
  #include
  #include
  int init_module(void)
  {
  printk(KERN_INFO "Hello, world\n");
  return 0;
  }
  void cleanup_module(void)
  {
  printk(KERN_INFO "Goodbye cruel world\n");
  }
  2.6的hello world版本!
  #include < linux/module.h>
  #include < linux/config.h>
  #include < linux/init.h>
  MODULE_LICENSE("GPL");// 新,否则有 waring, 去掉了 #define MODULE, 自动定义
  static int hello_init(void)
  {
  printk(KERN_ALERT "Hello, world\n");
  return 0;
  }
  static void hello_exit(void)
  {
  printk(KERN_ALERT "Goodbye, cruel world\n");
  }
  module_init(hello_init);// 必须!!
  module_exit(hello_exit); // 必须!!
  注意,在 2.4 中 module_init 不是必须的,只要驱动的初始化函数以及析沟函数命名使用了缺省的 init_module 和 cleanup_module
  编译生成: 2.4
  gcc -D__KERNEL__ -DMODULE -I/usr/src/linux- 2.4.27 /include -O2 -c testmod.c
  2.6
  makefile 中要有 obj-m:= hello.o
  然后:
  make -C /usr/src/linux- 2.6.11 SUBDIRS=$PWD modules (当然简单的 make 也可以)
  哈哈够简单!!
  其他不同: 计数器: 以前 2.4 内核使用 MOD_INC_USE_COUNT 增加计数例如:
  void
  inc_mod(void)
  {
  MOD_INC_USE_COUNT;
  } /* end inc_mod */
  
  /************************************************************************
  * Calculator DEC
  ************************************************************************/
  void
  dec_mod(void)
  {
  MOD_DEC_USE_COUNT;
  } /* end dec_mod */
  现在这个也过时了 !!
  2.6 ,用户函数要加载模块,使用:
  int try_module_get(&module);
  函数卸载模块使用
  module_put()
  而驱动中不必显示定义 inc 和 dec
  没有 kdev_t 了 现在都流行用 dev_t 了 , 而且是 32 位的
  结构体初始化 老版本使用:
  static struct some_structure = {
  field1: value,
  field2: value
  };
  现在流行用:
  static struct some_structure = {
  .field1 = value,
  .field2 = value,
  ...
  };
  malloc.h 要用核态内存?用 好了,
  内存池内存管理变化不大,添加了memory pool*(#include )。(现在什么都是pool,内存 线程 ....)这是为块设备提供的,使用mempool最大的优点是分配内存不会错,也不会等待(怎么这个也和RTEMS学)。对于embed的设备还是有些用处的。标准调用方式:
  mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);
  使用mempool的函数 :
  mempool_alloc_t / mempool_free_t
  mempool_alloc_slab / mempool_free_slab
  mempool_alloc / mempool_free
  mempool_resize
  结构体赋值 以前,驱动中结构体赋值使用:
  static struct some_structure = {
  field1: value,
  field2: value
  };
  
  现在要用:
  static struct some_structure = {
  .field1 = value,
  .field2 = value,
  ...
  };
  例如 :
  static struct file_operations yourdev_file_ops = {
  .open = yourdev_open,
  .read = yourdev_read_file,
  .write = yourdev_write_file,
  };
  
  min() , max() 不少程序员定义自己的 min 和 max 宏,大家也知道宏不安全, Linux 定义了 min 和 max 函数(注意不是模板函数,需要自己制定比较类型!)
  原型变化 call_usermodehelper()
  request_module()
  函数原型变化了,用到的赶快查 !!!
  Devfs 唉,还没怎么用,就过时了的技术,这就是 linux 。不是我们落伍,是世界变化快
  
  字符设备 2.6 中主从设备编号不再局限于原来的 8bit
  register_chrdev() 可以升级为:
  int register_chrdev_region(dev_t from, // 设备号 unsigned count, // 注册号 char *name); // 名称
  该函数的动态版本(不知道主设备号时使用)
  int alloc_chrdev_region(dev_t *dev, unsigned baseminor,
  unsigned count, char *name);
  
  新的 file_operations register_chrdev_region 没有使用 register_chrdev_region 参数,因为设备现在使用 struct cdev 来定义他在 中定义。
  struct cdev {
  struct kobject kobj;
  struct module *owner;
  struct file_operations *ops;
  struct list_head list;
  dev_t dev;
  unsigned int count;
  };
  使用时首先需要分配空间: struct cdev *cdev_alloc(void);
  然后对其初始化:
  void cdev_init(struct cdev *cdev, struct file_operations *fops);
  cdev 使用 kobject_set_name 设置名称:例如:
  struct cdev *my_cdev = cdev_alloc(); kobject_set_name(&cdev->kobj, "my_cdev%d", devnum);
  此后就可以使用 int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); 将 cdev 加入到系统中。
  删除 cdev 使用
  void cdev_del(struct cdev *cdev);
  对于没有使用 cdev_add 添加的 cdev 使用 kobject_put(&cdev->kobj); 删除 也就是使用: struct kobject *cdev_get(struct cdev *cdev); void cdev_put(struct cdev *cdev);
  太极链; struct inode -> i_cdev -> cdev
  这样就从 inode 链接到 cdev
  
  驱动体系: /dev 到 /sys
  /dev 也过时了,设备文件都跑到 /sys 里了!
  # cd /sys
  # ls
  block bus class devices firmware
 
 
阅读(883) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~