linux文件系统的系统分析--(十三)sysfs和设备模型--Device

      分析完了bus,接下来分析device:

      同样在driver_init-->devices_init

int __init devices_init(void)
{
	devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
	if (!devices_kset)
		return -ENOMEM;
	dev_kobj = kobject_create_and_add("dev", NULL);
	if (!dev_kobj)
		goto dev_kobj_err;
	sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
	if (!sysfs_dev_block_kobj)
		goto block_kobj_err;
	sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
	if (!sysfs_dev_char_kobj)
		goto char_kobj_err;

	return 0;

 char_kobj_err:
	kobject_put(sysfs_dev_block_kobj);
 block_kobj_err:
	kobject_put(dev_kobj);
 dev_kobj_err:
	kset_unregister(devices_kset);
	return -ENOMEM;
}

       /sys目录下有了 devices目录和 dev目录, dev下面有 blockchar两个目录


       设备的注册:

int device_register(struct device *dev)
{
	device_initialize(dev);
	return device_add(dev);
}


  1. 设备的初始化device_initialize

void device_initialize(structdevice *dev)

{

dev->kobj.kset =devices_kset; //这个device结构体内嵌的kobject代表的目录在/sys/devices

kobject_init(&dev->kobj,&device_ktype); //初始化内嵌的kobjectkobj_typedevice_ktype

INIT_LIST_HEAD(&dev->dma_pools);

init_MUTEX(&dev->sem);

spin_lock_init(&dev->devres_lock);

INIT_LIST_HEAD(&dev->devres_head);

device_init_wakeup(dev, 0);

device_pm_init(dev);

set_dev_node(dev, -1);

}

  1. 添加设备device_add

2.1、初始化devicestructdevice_private *p;指针

int device_private_init(structdevice *dev)

{

dev->p =kzalloc(sizeof(*dev->p), GFP_KERNEL);

if (!dev->p)

return -ENOMEM;

dev->p->device = dev; //指向dev

klist_init(&dev->p->klist_children,klist_children_get,

klist_children_put); //初始化klist_children链表

return 0;

}

2.2、设置device结构体内嵌的kobject的名称

2.3setup_parent(dev,parent);

根据device结构体的父子层次关系设置内嵌kobject对象的父子层次关系

2.4、在kobject层注册device内嵌的kobject对象

2.5、创建设备属性文件ueventuevent文件的读写与kobject_uevent相关

2.6、如果device结构体的devt设备号存在,那么创建devt属性文件文件,从这个属性文件中可以读出设备号;sysfs中会创建链接文件;devtmpfs会创建结点node

2.7、设备添加class的链接文件

2.8、添加设备属性文件

2.9bus_add_device(dev); 添加设备到总线

A、添加设备的总线属性:bus->dev_attrs

B、创建链接文件

C、添加设备到总线的设备链表中:

klist_add_tail(&dev->p->knode_bus,&bus->p->klist_devices);

2.10bus_probe_device(dev);device探测driver

bus_probe_device-->device_attach

如果dev的driver指针已经指向了driver结构体,那么调用device_bind_driver将device和driver绑定,否则调用

bus_for_each_drv(dev->bus, NULL, dev, __device_attach);对于bus总线klist_drivers链表上所有挂着的driver,都

来和我们的device进行匹配,负责的函数就是__device_attach


如果devdriver指针已经

static int__device_attach(struct device_driver *drv, void *data)

{

struct device *dev = data;


if (!driver_match_device(drv,dev))

return 0;


return driver_probe_device(drv,dev);

}

首先调用总线级别的match函数,然后调用driver_probe_device(drv,dev);

driver_probe_device-->really_probe-->dev->bus->probe(dev);以及drv->probe(dev);

最后调用driver_bound

klist_add_tail(&dev->p->knode_driver,&dev->driver->p->klist_devices);


                       devices的注册过程就如上所述,至于最后的bus_probe_device具体是怎么实现的?等到分析完busdevice driverclass后,再举一个实例来具体分析。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值