惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
V
V2EX
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Y
Y Combinator Blog
小众软件
小众软件
Jina AI
Jina AI
V2EX - 技术
V2EX - 技术
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
博客园 - 三生石上(FineUI控件)
T
Threatpost
博客园 - 聂微东
Scott Helme
Scott Helme
IT之家
IT之家
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
MongoDB | Blog
MongoDB | Blog
T
Tor Project blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
About on SuperTechFans
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Check Point Blog
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
Attack and Defense Labs
Attack and Defense Labs
T
Tailwind CSS Blog
罗磊的独立博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Webroot Blog
Webroot Blog
Help Net Security
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest

博客园 - 中土

strcpy和memcpy的标准实现 Linux 命令缩写部分解释 Eclipse RCP 的一些有用的资源及应用案例 分析Linux和windows动态库 C/C++中的函数参数传递机制(zz) LDD3 笔记: 第3章 字符设备的驱动 2008年看书计划 H.264学习建议(zz) - 中土 - 博客园 几种常用的视频接口(端子) U-boot 移植到FS2410 NandFlash和NorFlash的区别 A simple tourial for Linux 2.6.24 kernel module Linux basic use Kernel resource list Linux 2.6.x 内核模块入门(LKM) C++中无处不在的临时变量 类中引用成员的初始化 C++初始化与赋值 C异常处理实现: setjmp和longjmp
Linux2.6 驱动设计―从 2.4.x 到 2.6.x
中土 · 2008-10-11 · via 博客园 - 中土

LKMPG-2.6.x(中文): http://dirac.org/linux/writing/lkmpg/2.6/chinese/lkmpg_chs/

LKMPG-2.6.x(英文): http://dirac.org/linux/writing/lkmpg/2.6/lkmpg-2.6.0.html

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 <linux/module.h>
#include <linux/kernel.h>
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

要用核态内存?用 <linux/slab.h> 好了,

内存池

内存管理变化不大,添加了memory pool*(#include<linux/mempool.h> )。(现在什么都是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 来定义他在 <linux/cdev.h> 中定义。

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 kernel module power

哈哈,看上去清晰多了。