1、创建设备类,是为了让mdev知道根据这些信息来创建设备节点,根据/sys来创建,所以从devfs开始,根文件系统就引入了一个/sys目录,/sys/dev下面都是内核加载的驱动的主从设备号
2、class的初始化过程(在/sys/下创建class目录):
start_kernel() -> rest_init() -> kernel_init() -> do_basic_setup() -> driver_init() -> classes_init()
3、所谓的uevent机制,就是由内核来启动一个用户进程
4、uevent通知机制:kobject_uevent() -> kobject_uevent_env()
11.1、得到kset->uevent_ops,通过filter判断kset中的内核对象状态改变是否需要通知到用户层,返回0就不通知
11.2、如果内核对象状态变化需要通知用户层,分配环境变量空间env,并设置环境变量
11.3、内核来启动一个用户空间的程序,一般默认为这个属性文件(/proc/sys/kernel/hotplug)指定的进程,如:/sbin/mdev
5、在x86系统下,用户空间一般会有udevd这个守护进程一直监听kobject_uevent通过netlink广播的uevent数据包,来获取内核的各种变化,可通过命令查看:ps -aux |grep udevd
6、调用通知用户过程:
设备端:device_add() -> kobject_uevent(&dev->kobj, KOBJ_ADD);
驱动端:driver_register() -> bus_add_driver() -> kobject_uevent(&priv->kobj, KOBJ_ADD);
设备端卸载:
device_del() -> bus_remove_device() -> bus_put() -> kset_put() -> kobject_put() -> -> kobject_release() -> kobject_cleanup() -> kobject_uevent(kobj, KOBJ_REMOVE);
device_del() -> put_device() -> kobject_put() ......
驱动端卸载:
driver_unregister() -> bus_remove_driver() -> kobject_put() ......
driver_unregister() -> bus_remove_driver() -> bus_put() -> kset_put() -> kobject_put() ......
7、当内核对象kset改变时,内核会采用内核对象通知机制(kobject_uevent),通知用户层,那么用户程序必须指定一个进程给/proc/sys/kernel/hotplug,比如/sbin/mdev
8、咱们也可以替换/sbin/mdev来观察现象,但被替换的应用程序由于没有任何描述符可用,所以需要自己打开标准输入输出,如:
fd = open("/dev/console",O_RDWR);