Linux内核大讲堂 (一) 设备驱动的基石驱动模型(7)

Linux内核大讲堂 (设备驱动的基石驱动模型(7

终于快讲完了,这一节其实就是让上节我们所说的四大天王露下小脸。源码分析请自行完成吧。我建议大家可以试着先看一下代码,如果能看懂,那就把我写的那破玩意删掉,自已实现一遍,如果不能看懂,那马上回过去从第一小节重新看过,耐心,一定要有耐心,没耐心,啥都完了。帖上原码:

Makefile:

obj-m+=wwhs_bus.o

KERNELDIR=/opt/kernel/linux-2.6.38/linux-2.6.38.5

PWD:=$(shell pwd)

all:

make -C $(KERNELDIR) M=$(PWD) modules

clean: 

rm -rf *.o* *.ko* *.mod.c *.cmd *.symvers .tmp_versions .*.cmd

wwhs_public.h:

#include <linux/module.h>

#include <linux/device.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/stat.h>

#include <linux/slab.h>

#include <linux/kobject.h>

#include <linux/klist.h>

#include <linux/kdev_t.h>

#include <linux/fs.h>

#include <linux/major.h>

#include <linux/kprobes.h>

#define wwhs_dbg(dbgbuf) printk(KERN_ERR"wwhs:%s/n",dbgbuf);

#include "../wwhs_public.h"

#define WWHS_MAJOR 83

void wwhs_release(struct device *dev)

{

printk(KERN_ERR"wwhs:dev:%s is release/n",dev->kobj.name);

}

struct device wwhs_bus = {

.init_name = "wwhs",

.release = wwhs_release,

};

static struct device wwhs_dev = {

.init_name = "wwhsled0",

.release = wwhs_release,

};

static int wwhs_bus_match(struct device *dev, struct device_driver *drv)

{

int ret = -1;

ret = strncmp(dev->kobj.name, drv->name, strlen(drv->name));

printk(KERN_ERR"wwhs:dev->kobj.name:%s drv->name:%s ret:%d/n",dev->kobj.name,drv->name,ret);

return !ret;

}

static int wwhs_bus_probe(struct device *dev)

{

int ret = -1;

if (dev->driver->probe)

ret = dev->driver->probe(dev);

return ret;

}

static struct bus_type wwhs_bus_type = {

.name = "wwhs",

.match = wwhs_bus_match,

};

static struct class *wwhs_class;

static int wwhs_bus_register()

{

int ret = -1;

wwhs_bus.class = wwhs_class;

ret = device_register(&wwhs_bus);

if (ret) goto device_error;

ret = bus_register(&wwhs_bus_type);

  if (ret) goto bus_error;

return ret;

bus_error:

device_unregister(&wwhs_bus);

device_error:

return ret;

}

static void wwhs_bus_unregister()

{

device_unregister(&wwhs_bus);

bus_unregister(&wwhs_bus_type);

}

static int wwhs_class_register(void)

{

wwhs_class = class_create(THIS_MODULE, "wwhsclass");

if (IS_ERR(wwhs_class)){

printk(KERN_ERR"wwhs: class create error/n");

return PTR_ERR(wwhs_class);

}

printk(KERN_ERR"wwhs: class create success/n");

return 0;

}

static void wwhs_class_unregister()

{

class_destroy(wwhs_class);

}

static int wwhs_device_register(struct device *dev)

{

dev->devt = MKDEV(WWHS_MAJOR,1);

dev->bus = &wwhs_bus_type;

dev->parent = &wwhs_bus;

return device_register(dev);

}

static void wwhs_device_unregister(struct device *wwhs_dev)

{

device_unregister(wwhs_dev);

}

static struct device_driver wwhs_drv = {

.name = "wwhsled",

};

static wwhs_drv_probe(struct device *dev)

{

printk(KERN_ERR"wwhs:dev:%s is probe/n",dev->kobj.name);

return 0;

}

static wwhs_drv_remove(struct device *dev)

{

printk(KERN_ERR"wwhs:dev:%s is remove/n",dev->kobj.name);

return 0;

}

static int wwhs_driver_register(struct device_driver *wwhs_driver)

{

int ret = -1;

wwhs_driver->bus = &wwhs_bus_type;

wwhs_driver->owner = THIS_MODULE;

wwhs_driver->probe = wwhs_drv_probe;

wwhs_driver->remove = wwhs_drv_remove;

ret = driver_register(wwhs_driver);

return ret;

}

static void wwhs_driver_unregister(struct device_driver *wwhs_driver)

{

driver_unregister(wwhs_driver);

}

static int __init wwhs_init()

{

int ret = -1;

ret = wwhs_class_register();

if (ret) goto error;

ret = wwhs_bus_register();

if (ret) goto error;

ret = wwhs_device_register(&wwhs_dev);

if (ret) goto bus_error;

ret = wwhs_driver_register(&wwhs_drv);

if (ret) goto device_error;

return ret;

device_error:

wwhs_device_unregister(&wwhs_dev);

bus_error:

wwhs_bus_unregister();

class_error:

wwhs_class_unregister();

error:

return ret;

}

static void __exit wwhs_exit()

{

wwhs_device_unregister(&wwhs_dev);

wwhs_driver_unregister(&wwhs_drv);

wwhs_bus_unregister();

wwhs_class_unregister();

}

module_init(wwhs_init);

module_exit(wwhs_exit);

MODULE_AUTHOR("wwhs");

MODULE_DESCRIPTION("wwhs_bus test");

MODULE_LICENSE("GPL");

上面就是四大天王小露一下脸,至此,驱动模型的分析要告一段落了。如果根着看了的朋友,我相信肯定是有所收获的。谢谢各位。你们的支持是我前进的动力。^_^

设备驱动模型就先讲到这里了,如果大家有什么好的建议,请进:

http://blog.csdn.net/z2007b/archive/2011/05/19/6431791.aspx

这里提出来。你们想要了解的,才是我想写的,要不然我写一堆大家都不感兴趣的东西,就没有价值了。谢谢。

上面示例代码下载地址:

http://d.download.csdn.net/down/3285515/z2007b

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
买书时赠送的电子稿,代码示例丰富,非常不错!全书分三个文件打包。 linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-1.00.19-2.i386.rpm | |-- lvm2-2.00.25-1.01.i386.rpm | |-- mkinitrd-4.2.0.3.tar.tar | |-- module-init-tools-3.2.2.tar.bz2 | `-- modutils-2.4.5-1.src.rpm |-- 04 | |-- 内核模块参数范例 | | `-- book.c | |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem设备驱动 | `-- globalmem_two.c |-- 07 | `-- 含并发控制的globalmem驱动 | `-- globalmem_lock.c |-- 08 | |-- globalfifo驱动 | | `-- globalfifo.c | `-- poll应用程序范例 | `-- pollmonitor.c |-- 09 | |-- 异步通知应用程序范例 | | `-- asyncmonitor.c | `-- 支持异步通知的globalfifo | `-- globalfifo_async.c |-- 10 | |-- S3C2410实时钟驱动 | | `-- s3c2410-rtc.c | `-- 秒设备驱动与应用程序 | |-- second.c | `-- second_test.c |-- 11 | |-- DMA范例 | | |-- 3c505.c | | |-- 3c505.h | | `-- dma.h | `-- 静态映射范例 | `-- mach-smdk2440.c |-- 12 | |-- NVRAM驱动 | | `-- generic_nvram.c | |-- 触摸屏驱动 | | |-- 作为input设备 | | | |-- s3c2410_ts.c | | | `-- s3c2410_ts.h | | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd.c |-- 14 | |-- S3C2410串口驱动 | | |-- regs-gpio.h | | |-- regs-serial.h | | `-- s3c2410.c | `-- 串口核心层 | |-- serial_core.c | `-- serial_core.h |-- 15 | |-- S3C2410 I2C主机驱动 | | |-- i2c-s3c2410.c | | |-- iic.h | | |-- regs-gpio.h | | `-- regs-iic.h | `-- SAA711x I2C设备驱动 | `-- saa711x.c |-- 16 | `-- CS8900以太网设备驱动 | |-- cs89x0.c | `-- cs89x0.h |-- 17 | |-- ALSA工具及库 | | |-- alsa-driver-1.0.15.tar.bz2 | | |-- alsa-firmware-1.0.15.tar.bz2 | | |-- alsa-lib-1.0.15.tar.bz2 | | |--

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值