mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
![Kay Sievers](/assets/img/avatar_default.png)
Devtmpfs lets the kernel create a tmpfs instance called devtmpfs very early at kernel initialization, before any driver-core device is registered. Every device with a major/minor will provide a device node in devtmpfs. Devtmpfs can be changed and altered by userspace at any time, and in any way needed - just like today's udev-mounted tmpfs. Unmodified udev versions will run just fine on top of it, and will recognize an already existing kernel-created device node and use it. The default node permissions are root:root 0600. Proper permissions and user/group ownership, meaningful symlinks, all other policy still needs to be applied by userspace. If a node is created by devtmps, devtmpfs will remove the device node when the device goes away. If the device node was created by userspace, or the devtmpfs created node was replaced by userspace, it will no longer be removed by devtmpfs. If it is requested to auto-mount it, it makes init=/bin/sh work without any further userspace support. /dev will be fully populated and dynamic, and always reflect the current device state of the kernel. With the commonly used dynamic device numbers, it solves the problem where static devices nodes may point to the wrong devices. It is intended to make the initial bootup logic simpler and more robust, by de-coupling the creation of the inital environment, to reliably run userspace processes, from a complex userspace bootstrap logic to provide a working /dev. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Jan Blunck <jblunck@suse.de> Tested-By: Harald Hoyer <harald@redhat.com> Tested-By: Scott James Remnant <scott@ubuntu.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
147 lines
5 KiB
C
147 lines
5 KiB
C
|
|
/**
|
|
* struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.
|
|
*
|
|
* @subsys - the struct kset that defines this bus. This is the main kobject
|
|
* @drivers_kset - the list of drivers associated with this bus
|
|
* @devices_kset - the list of devices associated with this bus
|
|
* @klist_devices - the klist to iterate over the @devices_kset
|
|
* @klist_drivers - the klist to iterate over the @drivers_kset
|
|
* @bus_notifier - the bus notifier list for anything that cares about things
|
|
* on this bus.
|
|
* @bus - pointer back to the struct bus_type that this structure is associated
|
|
* with.
|
|
*
|
|
* This structure is the one that is the actual kobject allowing struct
|
|
* bus_type to be statically allocated safely. Nothing outside of the driver
|
|
* core should ever touch these fields.
|
|
*/
|
|
struct bus_type_private {
|
|
struct kset subsys;
|
|
struct kset *drivers_kset;
|
|
struct kset *devices_kset;
|
|
struct klist klist_devices;
|
|
struct klist klist_drivers;
|
|
struct blocking_notifier_head bus_notifier;
|
|
unsigned int drivers_autoprobe:1;
|
|
struct bus_type *bus;
|
|
};
|
|
|
|
struct driver_private {
|
|
struct kobject kobj;
|
|
struct klist klist_devices;
|
|
struct klist_node knode_bus;
|
|
struct module_kobject *mkobj;
|
|
struct device_driver *driver;
|
|
};
|
|
#define to_driver(obj) container_of(obj, struct driver_private, kobj)
|
|
|
|
|
|
/**
|
|
* struct class_private - structure to hold the private to the driver core portions of the class structure.
|
|
*
|
|
* @class_subsys - the struct kset that defines this class. This is the main kobject
|
|
* @class_devices - list of devices associated with this class
|
|
* @class_interfaces - list of class_interfaces associated with this class
|
|
* @class_dirs - "glue" directory for virtual devices associated with this class
|
|
* @class_mutex - mutex to protect the children, devices, and interfaces lists.
|
|
* @class - pointer back to the struct class that this structure is associated
|
|
* with.
|
|
*
|
|
* This structure is the one that is the actual kobject allowing struct
|
|
* class to be statically allocated safely. Nothing outside of the driver
|
|
* core should ever touch these fields.
|
|
*/
|
|
struct class_private {
|
|
struct kset class_subsys;
|
|
struct klist class_devices;
|
|
struct list_head class_interfaces;
|
|
struct kset class_dirs;
|
|
struct mutex class_mutex;
|
|
struct class *class;
|
|
};
|
|
#define to_class(obj) \
|
|
container_of(obj, struct class_private, class_subsys.kobj)
|
|
|
|
/**
|
|
* struct device_private - structure to hold the private to the driver core portions of the device structure.
|
|
*
|
|
* @klist_children - klist containing all children of this device
|
|
* @knode_parent - node in sibling list
|
|
* @knode_driver - node in driver list
|
|
* @knode_bus - node in bus list
|
|
* @driver_data - private pointer for driver specific info. Will turn into a
|
|
* list soon.
|
|
* @device - pointer back to the struct class that this structure is
|
|
* associated with.
|
|
*
|
|
* Nothing outside of the driver core should ever touch these fields.
|
|
*/
|
|
struct device_private {
|
|
struct klist klist_children;
|
|
struct klist_node knode_parent;
|
|
struct klist_node knode_driver;
|
|
struct klist_node knode_bus;
|
|
void *driver_data;
|
|
struct device *device;
|
|
};
|
|
#define to_device_private_parent(obj) \
|
|
container_of(obj, struct device_private, knode_parent)
|
|
#define to_device_private_driver(obj) \
|
|
container_of(obj, struct device_private, knode_driver)
|
|
#define to_device_private_bus(obj) \
|
|
container_of(obj, struct device_private, knode_bus)
|
|
|
|
extern int device_private_init(struct device *dev);
|
|
|
|
/* initialisation functions */
|
|
extern int devices_init(void);
|
|
extern int buses_init(void);
|
|
extern int classes_init(void);
|
|
extern int firmware_init(void);
|
|
#ifdef CONFIG_SYS_HYPERVISOR
|
|
extern int hypervisor_init(void);
|
|
#else
|
|
static inline int hypervisor_init(void) { return 0; }
|
|
#endif
|
|
extern int platform_bus_init(void);
|
|
extern int system_bus_init(void);
|
|
extern int cpu_dev_init(void);
|
|
|
|
extern int bus_add_device(struct device *dev);
|
|
extern void bus_probe_device(struct device *dev);
|
|
extern void bus_remove_device(struct device *dev);
|
|
|
|
extern int bus_add_driver(struct device_driver *drv);
|
|
extern void bus_remove_driver(struct device_driver *drv);
|
|
|
|
extern void driver_detach(struct device_driver *drv);
|
|
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
|
|
static inline int driver_match_device(struct device_driver *drv,
|
|
struct device *dev)
|
|
{
|
|
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
|
|
}
|
|
|
|
extern void sysdev_shutdown(void);
|
|
|
|
extern char *make_class_name(const char *name, struct kobject *kobj);
|
|
|
|
extern int devres_release_all(struct device *dev);
|
|
|
|
extern struct kset *devices_kset;
|
|
|
|
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
|
|
extern void module_add_driver(struct module *mod, struct device_driver *drv);
|
|
extern void module_remove_driver(struct device_driver *drv);
|
|
#else
|
|
static inline void module_add_driver(struct module *mod,
|
|
struct device_driver *drv) { }
|
|
static inline void module_remove_driver(struct device_driver *drv) { }
|
|
#endif
|
|
|
|
#ifdef CONFIG_DEVTMPFS
|
|
extern int devtmpfs_init(void);
|
|
#else
|
|
static inline int devtmpfs_init(void) { return 0; }
|
|
#endif
|