Linux Device Model
Linux Device Model
Part 1
Sarah Diesburg
COP5641
Unified Device Model
• Kernels previous to 2.5 had no single data
structure to store information on how
system is put together
• Demands of newer systems with more
complicated topologies and power
management motivated construction of
the Linux Unified Device Model
Device Model Functionality
• Power management and system shutdown
• Knowing the ordering of when to shut down
components.
• E.g., shut down USB mouse before USB
controller
• Communication with user space
• Sysfs virtual file system tightly tied into device
model and exposes structure and device
tuning
Device Model Functionality
• Hotpluggable devices
• Used to handle and communicate the plugging
and unplugging of devices
• Device classes
• Allows system to discover types of devices that
are related
• Other
• Common facilities such as reference counting
• Capability to enumerate all devices and status
kobject
• struct kobject is used for:
• reference counting
• sysfs representation
• "data structure glue" - representing relationships
between devices
• OO-like programming
• hotplug event handling
struct kobject
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct sysfs_dirent *sd;
struct kref kref;
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};
struct kobject
• name
• Points to name of this kobject
• parent
• Points to this kobject’s parent
• In this manner, builds a hierarchy to describe
relationship between objects
• sd
• Points to sysfs_dirent structure that represents
this kobject in sysfs
• Inode inside this structure for sysfs
struct kobject
• kref
• Provices reference counting
• ktype and kset
• Describe and group objects
Example: struct cdev
• Struct kobjects are
embedded within other
types of objects to
provide capabilities
• For example, see type
struct cdev
Finding the struct cdev object associated with
a struct kobject pointed to by kp
struct cdev *device =
container_of(kp, struct cdev,
kobj);
kobject Initialization
• The kobj field of struct cdev is initialized in
cdev_alloc
• The kobj field of struct cdev is named in
register_chrdev:
kobject_set_name(&cdev->kobj,
"%s", name);
kobject Reference Counts
• kobject_get() “checks out” a kobj
• kobject_put() returns a kobj
• Cleaned up via kobject_release() when
reference count drops to 0
• Calls kobject_cleanup() which in turn calls the
.release() function pointer registered on the ktype…
ktypes
• Every kobject has a field for a
struct kobj_type
• Short for “kernel object type”
struct kobj_type {
void (*release)(struct kobject *);
const struct sysfs_ops sysfs_ops;
struct attribute **default_attrs;
};
ktypes
• Describes default behavior for a family of
kobjects
• Instead of each kobject defining own behavior,
behavior is stored in ktype
• Kobjects of the same “type” point at the same
ktype structure
ktypes
• Use the standard function to extract the
type
struct kobj_type *get_ktype(struct
kobject *kobj);
struct kset {
struct list_head list;
spinlock_t list_lock;
struct kobject kobj;
struct kset_uevent_ops *
uevent_ops;
};
struct kset
• list
• Linked list of all kobjects in this kset
• list_lock
• Spinlock protecting linked list
• kobj
• kobject representing base class for the set
• kset_uevent_ops
• Points to structure that describes the hotplug
behavior of kobjects in this kset
• uevent = “user event”
struct kset
• Each fully "set up" kset corresponds to
a sysfs directory
• To add kobject to the set specified by
its kset field
int kobject_add(struct kobject
*kobj …);
• To delete
void kobject_del(struct kobject
*kobj …);
kobject and sysfs
• kobject_add creates a sysfs entry for the
object
• Each kobject corresponds to a directory
• The directory contains attributes of the object
• kobject_set_name() names of objects must
be unique within the containing (parent)
directory
• If object has null parent, then kobject_add sets
parent to kset
• If both are null, object becomes child-member of
top-level sys directory
How do they all relate?
sysfs
• In-memory virtual file system
• Provides view of the kobject hierarchy
• Enables users to view device topology of
system
• kobjects can export files that enable kernel
variables to be read and written
• Sound a lot like /proc?
sysfs Directories
• block
• Contains one directory for each of the registered
block devices on the system
• Contains subdirectories for partitions on the device
• bus
• class
• Organized by high-level function
• dev
• Registered device nodes
• devices
• Gives view of topology of devices in system
sysfs Directories
• firmware
• System-specific tree of low-level subsystems
• ACPI, EDD, EFI
• fs
• kernel
• Kernel configuration options and status info
• modules
• power
sysfs Directories
• devices is most important directory –
exports device model
• Much of the data in other directories is
alternative organization of data in devices
• Neat to see interconnections
• High-level concepts in class
• Low-level physical devices in devices
• Actual drivers in bus
Adding and Removing kobjects
from sysfs
• To add kobject directory to sysfs:
int kobject_add(struct kobject *kobj, struct
kobject *parent, const char *fmt, ...);
• Where it is added depends on kobject’s
location
• If parent pointer is set
• Maps to subdirectory inside of parent’s directory
• If parent pointer is NULL
• Maps to subdirectory inside kset->kobj
• If neither parent nor kset fields are set
• Maps to root-level directory in sysfs
Adding and Removing kobjects
from sysfs
• To remove kobject directory from sysfs:
void kobject_del(struct kobject *kobj);
sysfs Files and Attributes
• Now we know how to add directories, but
what about files?
• Default set of files is provided via the ktype
field in kobjects and ksets
• Implication: All kobjects of the same type have
the same type of files populating their sysfs
directories
sysfs Files and Attributes
• kobj_type structure contains member
default_attrs that is an array of
attribute structures
• Recall:
struct kobj_type {
void (*release)(struct kobject *);
const struct sysfs_ops sysfs_ops;
struct attribute **default_attrs;
};
struct attribute
• Attributes map kernel data to files in sysfs
• Structure is defined in <linux/sysfs.h>
struct attribute {
const char *name; /* attribute’s name */
struct module *owner; /* owning module, if
any */
mode_t mode; /* permissions */
};
struct attribute
• Name
• Filename of resulting file in sysfs
• Owner
• Points to owning module, otherwise NULL
• Mode
• Permissions for file in sysfs
• S_IRUGO : world readable
• S_IRUSR : owner-readable
• By default, all files and dirs in sysfs owned by uid 0
and gid 0
struct sysfs_ops
• kobj_type->sysfs_ops describes how
to use the attributes
struct sysfs_ops {
/* method invoked on read of a sysfs file */
ssize_t (*show) (struct kobject *kobj,
struct attribute *attr,
char *buffer);
• Destroy attributes
void sysfs_remove_file(struct kobject *kobj,
const struct attribute *attr);
Binary Attributes
• Special case, for large chunks of binary
data
• e.g., proprietary configuration data/firmware
for a device (not allowed in Gnu sources)
• scenario:
• Device is detected
• User-space program is fired up, passes binary
data to kernel via sysfs binary attribute
• Kernel module uses binary data
Symbolic Links
int sysfs_create_link(struct kobject * kobj,
struct kobject * target, char * name);