CCU EE&COMM
Hot-pluggable devices
Device classes
Describe devices at a functional level
Object lifecycles
Reference count
Inheritance
Kobject,
Kset
Bus, driver,
device,
partition
Polymorphism
Refers to the object's ability to respond in an individual manner to
the same message
hotplug(), match(),
Dynamic binding
probe(), kobj_type
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations
Sysfs representation
A visible representation
$(KERNELDIR)/lib/kobject*.c
Directory entry,
maybe for sysfs
Reference count
struct 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()
ksets
Adding a kobject to a kset
kobjects kset must be pointed at the kset of interest
Call kobject_add(struct kobject *kobj); // reference count ++
kobject_init( ) + kobject_add( ) kobject_register( )
Operation on ksets
void 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
Subsystems
Representation for a high-level portion of the kernel
Usually show up at the top of the sysfs
Block devices, block_subsys, /sys/block
Core device hierarchy, devices_subsys, /sys/devices
Every bus type known to the kernel
Subsystems
fs/char_dev.c, line 442
subsystem_init(&cdev_subsys);
//not public in sysfs
drivers/firmware/efivars.c, line 689
subsystem_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);
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations
Default attributes
struct attribute {
char *name;
struct module *owner;
mode_t mode;
};
kobj_type
(*release)( )
*sysfs_ops
**default_attrs
sysfs_ops
*(show)
*(store)
{
snprintf();
}
attribute
version
*
struct sysfs_ops {
ssize_t (*show)(*kobj, struct attribute *attr, char *buffer);
S_IRUGO
ssize_t (*store)(*kobj, struct attribute *attr, const char *buffer, size_t size);
PAGE_SIZE
};
Binary 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);
};
Symbolic links
int sysfs_create_link(*kobj, struct kobject *target, char *name);
void sysfs_remove_link(*kobj, char *name);
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations
To invoke /sbin/hotplug
/proc/sys/kernel/hotplug specifies hotplug program path
|| (ktype = = &ktype_part));
block subsystem
}
kobject_hotplug( )
Called by kobject_register( )
kobject_hotplug( )
kset
kset/subsystem filter()
kset/subsystem name()
/sbin/hotplug $1
kset/subsystem hotplug()
call_usermodehelper( )
Setup a completion without wait
0 to skip
return
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations
struct
device
struct
ldd_device
Driver kobject
core
core
bus
driver
struct
ldd_driver
struct
device
driver
struct
kobject
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 */
};
Buses (1/2)
For example, lddbus in example.tgz
Bus registration
struct 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);
Buses (2/2)
Bus methods
int (*match)(struct device *device, struct device_driver *driver);
Called whenever a new device or driver is added for this bus
Return 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
Bus attributes
struct 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
Devices (0/1)
struct device {
Must be set before registering
struct device *parent;
struct kobject kobj;
device->kobj->parent
char bus_id[BUS_ID_SIZE];
== &device->parent->kobj
struct bus_type *bus;
struct device_driver *driver;
kobject_unregister( )
void *driver_data;
void (*release)(struct device *dev);
/* Several fields omitted */ kobject_hotplug() kobject_del() kobject_put()
};
kobject_release( )
ksets release
device_release( )
dev->release( )
Devices (1/1)
Device registration
int 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 attributes
struct device_attribute, DEVICE_ATTR( ), device_create_file,
Device 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);
};
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations
Classes
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);
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations
Outlines
Base type
Kobjects, Ksets, and Subsystems
Low-level sysfs operations