36
Chapter 14 Chapter 14 The Linux Device Model The Linux Device Model 潘潘潘 CCU EE&COMM

Chapter 14 The Linux Device Model

  • Upload
    susane

  • View
    39

  • Download
    3

Embed Size (px)

DESCRIPTION

Chapter 14 The Linux Device Model. 潘仁義 CCU EE&COMM. The 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 space Sysfs - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter 14 The Linux Device Model

Chapter 14Chapter 14The Linux Device ModelThe Linux Device Model

潘仁義CCU EE&COMM

Page 2: Chapter 14 The Linux Device Model

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

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

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

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

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

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

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

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

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

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

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

Kobjects’ hierarchy of block subsystemKobjects’ hierarchy of block subsystem

Page 14: Chapter 14 The Linux Device Model

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
Page 36: Chapter 14 The Linux Device Model

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