chapter 14 the linux device model 潘仁義 ccu ee&comm
Post on 19-Dec-2015
254 views
TRANSCRIPT
![Page 1: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/1.jpg)
Chapter 14Chapter 14The Linux Device ModelThe Linux Device Model
潘仁義CCU EE&COMM
![Page 2: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/2.jpg)
The 2.6 device modelThe 2.6 device model
The model provides abstraction, which supports:Power management and system shutdown
Understanding of the system’s structure
Right order to shutdown
Communication with user spaceSysfs
Knobs for changing operating parameters
Hot-pluggable devices
Device classesDescribe devices at a functional level
Object lifecyclesReference count
![Page 3: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/3.jpg)
Device model treeDevice model tree
Sysfs ( 跑個 tree /sys 吧 ?)/proc, /dev, /sysfs
Authors can ignore the model, and trust itUnderstanding device model is good, if struct leaks
Ex. the generic DMA code works with struct device
Advanced material that need not be read
![Page 4: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/4.jpg)
Object oriented programming (Object oriented programming ( 插個花插個花 ))
Abstract Data typingInformation hiding
Encapsulation
InheritanceDerive more specialized classes from a common class
PolymorphismRefers to the object's ability to respond in an individual manner to the same message
Dynamic bindingRefers to the mechanism that resolves a virtual function call at runtime
You can derive modified action that override the old one even after the code is compiled .
Kobject, KseKobject, Ksett
Bus, driver, Bus, driver, device, device,
partition…partition…
hotplug(), match(), hotplug(), match(), probe(), kobj_type probe(), kobj_type
![Page 5: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/5.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
![Page 6: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/6.jpg)
Kobject, Ksets, and SubsystemsKobject, Ksets, and Subsystems
struct kobject supportsReference counting of objects
Tracking the lifecycle
Sysfs representationA visible representation
Data structure glueMade up of multiple hierarchies with numerous links
Hotplug event handlingNotify user space about the comings and goings of hardware
$(KERNELDIR)/lib/kobject*.c
![Page 7: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/7.jpg)
Kobject basics (0/3)Kobject basics (0/3)
1. struct kobject {2. const char * k_name;3. char name[KOBJ_NAME_LEN];4. struct kref kref;5. struct list_head entry;6. struct kobject * parent;7. struct kset * kset;8. struct kobj_type * ktype;9. struct dentry * dentry;10. };
11. struct kset {12. struct subsystem * subsys;13. struct kobj_type * ktype;14. struct list_head list;15. spinlock_t list_lock;16. struct kobject kobj;17. struct kset_hotplug_ops * hotplug_ops;18. };
Directory entry, maybe for sysfs
![Page 8: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/8.jpg)
Kobject basics (1/3)Kobject basics (1/3)
Embedded kobjectsA common type embedded in other structures
A top-level, abstract class from which other classes are derived
Ex. in ch3,struct cdev {
struct kobject kobj;
struct module *owner;
struct file_operations *ops;
dev_t dev;
};
struct kobject *kp = …;
struct cdev *device = container_of(kp, struct cdev, kobj);
![Page 9: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/9.jpg)
Kobject basics (2/3)Kobject basics (2/3)
InitializationSet the entire kobject to 0, memset()
Set up some of fields with kobject_init(), ex. reference count to 1
Set the name by kobject_set_name(kobj, char *format, …)
Set up the other field, such as ktype, kset and parent
Reference countstruct kobject *kobject_get(struct kobject *kobj); //++
void kobject_put(struct kobject *kobj); //--, 0 to cleanup
“struct module *owner” in struct cdev?The existence of a kobject require the existence of module that created that kobject. ex. cdev_get()
![Page 10: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/10.jpg)
Kobject basics (3/3)Kobject basics (3/3)
Release functionsEven predictable object life cycles become more complicated when sysfs is brought in; user-space programs can keep a reference for an arbitrary period of time.Every kobject must have a release method.The release method is not stored in the kobject itself
kobject types – kobj_typestruct kobj_type { void (*release)(struct kobject *); struct sysfs_ops * sysfs_ops; struct attribute ** default_attrs;};
The kobject contains a field, pointer ktypeIf kobject is a member of kset, the pointer provided by ksetstruct kobj_type *get_ktype(struct kobject*kobj);
跟 sysfs 有關
也許因為 擴充或 overload 方便
![Page 11: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/11.jpg)
Kobject hierarchies, ksetKobject hierarchies, kset
The parent pointer and ksets“parent” points to another kobject, representing the next level up
“kset” is a collection of kobjects
kset are always represented in sysfs
Every kobject that is a member of a kset is represented in sysfs
![Page 12: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/12.jpg)
ksetsksets
Adding a kobject to a ksetkobject’s kset must be pointed at the kset of interest
Call kobject_add(struct kobject *kobj); // reference count ++
kobject_init( ) + kobject_add( ) kobject_register( )
Removing from the ksetkobject_del( )
kobject_del( ) + kobject_put( ) kobject_unregister( )
Operation on ksetsvoid kset_init(struct kset *kset);
int kset_add(struct kset *kset);
int kset_register(struct kset *kset);
void kset_unregister(struct kset *kset);
struct kset *kset_get(struct kset *kset);
void kset_put(struct kset *kset);
ktype, is used in preference to the ktype in a kobject
![Page 13: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/13.jpg)
Kobjects’ hierarchy of block subsystemKobjects’ hierarchy of block subsystem
![Page 14: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/14.jpg)
Subsystems Subsystems
Representation for a high-level portion of the kernel
Usually show up at the top of the sysfsBlock devices, block_subsys, /sys/block
Core device hierarchy, devices_subsys, /sys/devices
Every bus type known to the kernel…
Driver authors almost never needs to create oneProbably want is to add a new “class”
Subsystem is really just a wrapper around a ksetstruct subsystem {
struct kset kset;
struct rw_semaphore rwsem; // used to serialize access
};
![Page 15: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/15.jpg)
SubsystemsSubsystems
fs/char_dev.c, line 442subsystem_init(&cdev_subsys); //not public in sysfsdrivers/firmware/efivars.c, line 689subsystem_register(&vars_subsys); // Extensible Firmware Interface (EFI)drivers/pci/hotplug/pci_hotplug_core.c, line 672 subsystem_register(&pci_hotplug_slots_subsys);drivers/base/sys.c, line 392 subsystem_register(&system_subsys);//pseudo-bus for cpus, PICs, timers, etc…drivers/base/core.c, line 423 subsystem_register(&devices_subsys);drivers/base/bus.c: line 697 subsystem_register(&bus->subsys);drivers/base/bus.c: line 745 subsystem_register(&bus_subsys);drivers/block/genhd.c, line 307 subsystem_register(&block_subsys);
drivers/base/class.c: line 148 subsystem_register(&cls->subsys);drivers/base/class.c: line 567 subsystem_register(&class_subsys);fs/debugfs/inode.c, line 308 subsystem_register(&debug_subsys);kernel/power/main.c, line 259 subsystem_register(&power_subsys);kernel/params.c, line 690 subsystem_register(&module_subsys);kernel/ksysfs.c, line 49 subsystem_register(&kernel_subsys); //kernel sysfs attrsecurity/seclvl.c, line 655 subsystem_register(&seclvl_subsys)// BSD Secure Levels LSMdrivers/base/firmware.c: line 20 subsystem_register(s);drivers/base/firmware.c: line 30 subsystem_register(&firmware_subsys);
![Page 16: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/16.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
![Page 17: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/17.jpg)
Low-level sysfs operationsLow-level sysfs operations
Every kobject exports attributes, in that its sysfs dir
#include <linux/sysfs.h>
Call kobject_add( ) to show up in sysfs
Default attributesstruct attribute {
char *name;
struct module *owner;
mode_t mode;
};
struct sysfs_ops {
ssize_t (*show)(*kobj, struct attribute *attr, char *buffer);
ssize_t (*store)(*kobj, struct attribute *attr, const char *buffer, size_t size);
};
(*release)( )
*sysfs_ops
**default_attrs
{ kfree();}
kobj_typekobj_type
PAGE_SIZE
*(show)
*(store)
sysfs_opssysfs_ops
{ snprintf();}
attributeattribute“version”
*S_IRUGO
![Page 18: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/18.jpg)
Low-level sysfs operationsLow-level sysfs operations
Non default attributesAttributes can be added and removed at will
int sysfs_create_file(struct kobject *kobj, struct attribute *attr);int sysfs_remove_file(struct kobject *kobj, struct attribute *attr);
The same show() and store() are calledBinary attributes
e.g., when a device is hot-plugged, a user-space program can be started via hot-plug mechanism and then passes the firmware code
struct bin_attribute { struct attribute attr; size_t size; ssize_t (*read)(struct kobject *kobj, char *buffer, loff_t pos, size_t size); ssize_t (*write)(struct kobject *kobj, char *buffer, loff_t pos, size_t size);};
int sysfs_create_bin_file(*kobj, struct bin_attribute *attr);int sysfs_remove_bin_file(*kobj, struct bin_attribute *attr);
Symbolic linksint sysfs_create_link(*kobj, struct kobject *target, char *name);void sysfs_remove_link(*kobj, char *name);
![Page 19: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/19.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
![Page 20: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/20.jpg)
Hotplug event generationHotplug event generation
Hotplug event a notification to user space from the kernel that something has changed in the system’s configurationis generated whenever a kobject is created (kobject_add) or destroyed (kobject_del)e.g., a camera is plugged in USB cable, disk is repartitioned…
To invoke /sbin/hotplug/proc/sys/kernel/hotplug specifies hotplug program path
Operations in “hotplug_ops” of ksetSearch up via parent until finding a kset(*filter): to suppress hotplug event generation (*name): to pass the name of relevant subsystem for a parameter(*hotplug): to add useful environment variables for hotplug script
詳細運作容後再述
![Page 21: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/21.jpg)
Hotplug operations’ sample codeHotplug operations’ sample code
Filter exampleUser space may want to react to the addition of a disk or a partition, but it does not normally care about request queues.
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype = = &ktype_block) || (ktype = = &ktype_part));
}
The generation of hotplug events is usually handled by logic at the bus driver level
配著前面的block subsystem
圖
![Page 22: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/22.jpg)
kobject_hotplug( )kobject_hotplug( )
Called by kobject_register( )kobject_hotplug( )
努力的往爸爸方向找 kset
呼叫 kset/subsystem 的 filter()
呼叫 kset/subsystem 的 name() 作為 /sbin/hotplug 參數 $1
return
呼叫 kset/subsystem 的 hotplug()建構環境變數
call_usermodehelper( )Setup a completion without wait
0 to skip
![Page 23: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/23.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
![Page 24: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/24.jpg)
Buses, devices, and driversBuses, devices, and drivers
BusesChannel between the processor and one or more devices
Devices and device drivers
Once again, much of the material covered here will never be needed by many driver authors.
kobjectkobjectcorecore
DriverDrivercorecorebusbus
driverdriver
devicedevice
Functional view inside kernel
structdevice
structdevicedriver
structkobject
structldd_device
structldd_driver
![Page 25: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/25.jpg)
Buses (0/2)Buses (0/2)
struct bus_type {
char *name;
struct subsystem subsys;
struct kset drivers;
struct kset devices;
int (*match)(struct device *dev, struct device_driver *drv);
struct device *(*add)(struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
/* Some fields omitted */
};
![Page 26: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/26.jpg)
Buses (1/2)Buses (1/2)
For example, lddbus in example.tgz
Bus registrationstruct bus_type ldd_bus_type = {
.name = "ldd",
.match = ldd_match, // 容後再述
.hotplug = ldd_hotplug, // 容後再述 };
int __init ldd_bus_init(void) {
ret = bus_register(&ldd_bus_type); //ret value must be checked
… // 在 bus subsystem 下 , /sys/bus/ldd
ret = device_register(&ldd_bus);
Deregistration void ldd_bus_exit(void){
device_unregister(&ldd_bus);
bus_unregister(&ldd_bus_type);
![Page 27: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/27.jpg)
Buses (2/2)Buses (2/2)
Bus methodsint (*match)(struct device *device, struct device_driver *driver);
Called whenever a new device or driver is added for this busReturn a nonzero value if the device can be handled by driver
static int ldd_match(struct device *dev, struct device_driver *driver){
return !strncmp(dev->bus_id, driver->name, strlen(driver->name));}
int (*hotplug) (struct device *device, char **envp, int num_envp, char *buffer, int buffer_size);
Allow the bus to add environment variables直接看範例程式 , LDDBUS_VERSION
Iterating over devices and driversbus_for_each_dev( ), bus_for_each_drv( )
Bus attributesstruct bus_attribute, (*show), (*store)BUS_ATTR(name, mode, show, store); declare “struct bus_attr_name”bus_create_file( ), bus_remove_file( ) 看 lddbus 的 BUS_ATTR(version
![Page 28: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/28.jpg)
Devices (0/1)Devices (0/1)
struct device {
struct device *parent;
struct kobject kobj;
char bus_id[BUS_ID_SIZE];
struct bus_type *bus;
struct device_driver *driver;
void *driver_data;
void (*release)(struct device *dev);
/* Several fields omitted */
};
Must be set before registering
device->kobj->parent == &device->parent->kobj
kobject_unregister( )
kobject_del()kobject_hotplug() kobject_put()
kobject_release( )
kset’s release也就是 device_release( )
dev->release( )
![Page 29: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/29.jpg)
Devices (1/1)Devices (1/1)
Device registrationint device_register(struct device *dev);
void device_unregister(struct device *dev);
An actual bus is a device and must be registered static void ldd_bus_release(struct device *dev)
{ printk(KERN_DEBUG "lddbus release\n"); }
struct device ldd_bus = {
.bus_id = "ldd0",
.release = ldd_bus_release
};
// device_register( ) & unregister( ) 在 ldd_bus_init( ) & exit( ) 被叫
// 在 devices subsystem 下 , /sys/devices/ldd0/
Device attributesstruct device_attribute, DEVICE_ATTR( ), device_create_file, …
![Page 30: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/30.jpg)
Device structure embeddingDevice structure embeddingfor a specific bus (e.g., pci_dev, ldd_device)for a specific bus (e.g., pci_dev, ldd_device)
“struct device” contains the device core’s information
Most subsystems track other about the devices they host
As a result, “struct device” is usually embeddedlddbus creates its own device type for ldd devices
struct ldd_device {
char *name;
struct ldd_driver *driver;
struct device dev;
};
#define to_ldd_device(dev) container_of(dev, struct ldd_device, dev);
sculld 多了 device register 之類動作 , 納入 sysfs, 理論上可以 hotplug; scullp 僅有 module 下有
![Page 31: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/31.jpg)
Device driversDevice drivers
struct device_driver {
char *name;
struct bus_type *bus;
struct kobject kobj;
struct list_head devices;
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown) (struct device *dev);
};
![Page 32: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/32.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
![Page 33: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/33.jpg)
ClassesClasses
net/core/net-sysfs.c, line 460 class_register(&net_class);
net/bluetooth/hci_sysfs.c, line 147 class_register(&bt_class);
drivers/pcmcia/cs.c, line 1892 class_register(&pcmcia_socket_class);
drivers/usb/core/file.c: line 90 class_register(&usb_class);
drivers/usb/core/hcd.c, line 649 class_register(&usb_host_class);
drivers/pci/probe.c, line 110 class_register(&pcibus_class);
還有很多
![Page 34: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/34.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
![Page 35: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/35.jpg)
![Page 36: Chapter 14 The Linux Device Model 潘仁義 CCU EE&COMM](https://reader033.vdocuments.site/reader033/viewer/2022061605/56649d3a5503460f94a14e7a/html5/thumbnails/36.jpg)
OutlinesOutlines
Base typeKobjects, Ksets, and Subsystems
Low-level sysfs operations
Derived type and interactionHotplug event generation
Buses, devices, and drivers
High level viewClasses
Put it all together
番外篇 – Dealing with Firmware