当前位置:文档之家› Linux设备驱动模型分析

Linux设备驱动模型分析

5/20
bus_register(&platform_bus_type) 在/sys/bus/目录下创建bus_name子目录 在/sys/bus/bus_name/目录下创建drivers子目录 在/sys/bus/bus_name/目录下创建devices子目录 在/sys/bus/bus_name/目录下创建uevent文件 在/sys/bus/bus_name/目录下创建drivers_probe文件 在/sys/bus/bus_name/目录下创建drivers_autoprobe文件
};
提醒:变量名字 platform_bus 实为 device{}
int device_add(struct device *dev) //dev:&platform_bus {
struct device *parent = NULL; parent = get_device(dev->parent); struct device_type *type = dev->type; ... ... ;
drivers_kset devices_kset
bus_register(&platform_bus_type):
int bus_register(struct bus_type *bus) //bus:platform_bus_type {
struct bus_type_private *priv; priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); priv->bus = bus; bus->p = priv; ... ... ;
... ... ; for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { //grp: &pm_attr_group; attrs: &power_attrs
sysfs_add_file_mode(... , *attr, SYSFS_KOBJ_ATTR, (*attr)->mode | mode); ... ... ; } }
sys文件系统注册挂载
start_kernel()→vfs_caches_init()→mnt_init()→sysfs_init()
int __init sysfs_init(void) {
register_filesystem(&sysfs_fs_type); kern_mount(&sysfs_fs_type); ... ...; }
};
//设置 priv->subsys.kobj 的名字为 platform
kobject_set_name(&priv->subsys.kobj, "%s", bus->name); //name: "platform"
priv->subsys.kobj.kset = bus_kset; priv->subsys.kobj.ktype = &bus_ktype;
system_bus_init()
在/sys/目录下创建system子目录
system_kset
2/20
device_register(&platform_bus) 在/sys/devices/目录下创建platform子目录 在/sys/devices/platform/目录下创建uevent文件 在/sys/devices/platform/目录下创建power子目录 在/sys/devices/platform/目录下创建control、wakeup文件
struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, ... ... ,
device_create_file(dev, &uevent_attr); static struct device_attribute uevent_attr =__ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
if (MAJOR(dev->devt)) //dev->devt 无,操作不执行 ... ... ;
3/20
//dev->class 无 且 dev->parent 无,在/sys/devices/目录下创建 platform 目录
kobject_add(&dev->kobj, dev->kobj.parent, NULL);
//在/sys/devices/platform/目录下创建 uevent 属性文件
//确定 device 在/sys/device/.../中所处位置的算法思想 设备:dev
① 设备组 父设备:dev->parent
名词定义: 设备类:dev->class
② 类组 父设备类:dev->parent->class
算法思想:dev 必有,利用 dev->parent、dev->class、dev->parent->class 来计算设备所处 sysfs 文件中的位置。
//创建/sys/bus/platform 目录
kset_register(&priv->subsys);
//创建/sys/bus/platform/uevent 属性文件
bus_create_file(bus, &bus_attr_uevent);
//创建/sys/bus/platform/devices 目录
};
static struct attribute * power_attrs[] = { &dev_attr_control.attr, &dev_attr_wakeup.attr,
};
int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) {
create_files(... , kobj, grp, ...);
4/20
... ... ; } int sysfs_create_subdir(struct kobject *kobj, const char *name, ...) {
create_dir(kobj, ... , name, ...); } static int create_files(... , struct kobject *kobj, const struct attribute_group *grp, ...) {
在/sys/dev/目录下创建char子目录
sysfs_dev_char_kobj
buses_init()
在/sys/目录下创建bus子目录
bus_kset
classes_init()
在/sys/目录下创建class子目录
class_kset
firmware_init()
在/sys/目录下创建firmware子目录
//在/sys/devices/platform/目录下创建 power 目录,并在 power 目录下创建 power_attrs 属性文件,包括 control、wakeup
sysfs_create_group(&dev->kobj, &pm_attr_group);
... ... ;
} }
static struct attribute_group pm_attr_group = { .name = "power", .attrs = power_attrs,
device_register(&platform_bus):
int device_register(struct device *dev) {
device_initialize(dev); device_add(dev); }
struct device platform_bus = { .init_name = "platform",
driver_init()
devtmpfs_init()
创建devtmpfs文件系统
devices_init()
在/sys/目录下创建devices子目录
devices_kset
在/sys/目录下创建dev子目录
dev_kobj
在/sys/dev/目录下创建block子目录
sysfs_dev_block_kobj
internal_create_group(kobj, ... , grp); }
static int internal_create_group(struct kobject *kobj, int update, const struct attribute_group *grp) {
if (grp->name) //name: "power" sysfs_create_subdir(kobj, grp->name, ...);
LK 设备驱动模型之 Base 子系统架构及 sysfs 组织结构
2013 年 1 月 10 日
※要点区:
① Linux驱动下面的base子系统的架构 ② sysfs文件系统的组织结构
相关主题