Linux核心熱拔插機制

2021-06-19 17:34:52 字數 3602 閱讀 7196

在linux2.6.30.4的核心中,註冊驅動時呼叫device_create,解除安裝驅動時呼叫

device_destory函式最終都將導致kobject_uevent_env函式被呼叫,該函式用於

通知使用者空間裝置傳送了動態變化

新增:device_create(struct class *class, struct device *parent,

dev_t devt, void *drvdata, const char *fmt, ...)

device_register(dev);

device_add(dev);

kobject_uevent(&dev->kobj, kobj_add);

kobject_uevent_env(kobj, action, null);

移除:device_destroy(struct class *class, dev_t devt)

device_unregister(dev);

device_del(dev);

kobject_uevent(&dev->kobj, kobj_remove);

kobject_uevent_env(kobj, action, null);

mdev函式分析:(busybox:mdev.c)

uevent_helper = /sbin/mdev

env->envp[0] = action=add

env->envp[1] = devpath=/devices/virtual/misc/buttons

env->envp[2] = subsystem=misc

env->envp[3] = major=10

env->envp[4] = minor=58

env->envp[5] = seqnum=410

env->envp[6] = home=/

env->envp[7] = path=/sbin:/bin:/usr/sbin:/usr/bin

action = getenv("action"); // action = "add"

env_path = getenv("devpath"); // env_path ="/devices/virtual/misc/buttons"

seq = getenv("seqnum"); // seq = "410" 

snprintf(temp, path_max, "/sys%s", env_path); // temp = "sys/devices/virtual/misc/buttons"

if (!strcmp(action, "remove"))

make_device(temp, 1);

else if (!strcmp(action, "add")) 

make_device(temp, 0);

add:

// 讀取主次裝置號

len = open_read_close("sys/devices/virtual/misc/buttons/dev", dev_maj_min + 1, 64);

device_name = bb_basename(path);

type = s_ifchr; // 判斷是字元裝置還是塊裝置

if (strstr("sys/devices/virtual/misc/buttons/", "/block/"))

type = s_ifblk;

// 如果有"/etc/mdev.conf"檔案將依據該檔案建立裝置檔案

mknod(device_name, mode | type, makedev(major, minor))

使用mdev在初始化指令碼中需要以下**片段:

[0] mount -t proc proc /proc

[1] mount -t sysfs sysfs /sys

[2] echo /bin/mdev > /proc/sys/kernel/hotplug

[3] mdev -s

或者不使用/proc檔案系統:

[1] mount -t sysfs sysfs /sys

[2] sysctl -w kernel.hotplug=/bin/mdev

[3] mdev -s

完整的啟動指令碼中還會有以下**片段:

[4] mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev

[5] mkdir /dev/pts

[6] mount -t devpts devpts /dev/pts

mdev.conf檔案的編寫

mdev.conf是乙個可選的配置檔案,控制裝置節點的所有權/許可權,如果你的系統需要改變預設的root/root

660許可權

檔案的格式如下:

裝置的正規表示式 使用者id  組id  

八進位制的許可權

: 示例:

hd[a-z][0-9]* 0:3 660

正規表示式:

*  : 重複0次或更多次

? :重複0次或1次

.  : 匹配換行符以外的任意字元

: 匹配裡面的某個字元

配置檔案的解析將停止於第乙個匹配的行,如果沒有一行可以匹配,將使用預設的0:0 660

你也可以重新命名/移除裝置節點通過以下可選的域:

裝置的正規表示式 使用者id 組id 八進位制的許可權

: [=path]

如果你想將裝置節點放置於某個子目錄中,確保路徑中含"/",如果你想給某個裝置節點重新命名

只需要放置名字。

hda 0:3 660 =drives/

這樣會將裝置檔案"hda"放置到drives/ 子目錄中

hdb 0:3 660 =cdrom

這樣會將"hdb"重新命名為"cdrom"

類似的,">path" 重新命名/移除裝置但還會建立乙個符號鏈結從"/dev/devname"到重新命名/移除的裝置

可以支援執行自己編寫的命令,此時檔案的格式如下:

:[=path] [@|$|*]

或者 :[>path] [@|$|*]

相關字元的意思:

@ 建立裝置之後執行

$ 移除裝置之前執行

* 在建立裝置之後和移除裝置之前都執行

命令是通過system()函式來執行(這意味著你應該給shell提供命令),所以你應該確保/bin/sh shell

已經安裝,當核心指向hotplug helpers時將stdin,stdout,stderr連線到/dev/null

使用環境變數$mdev被設定成裝置名。

掛載u盤的mdev.conf

sd[a-d]+[1-9]+ 0:0  660 * /bin/mount_udisk.sh

其中/bin/mount_udisk.sh的內容如下:

#!/bin/sh

if [ $action = "add" ];

then

mount /dev/$mdev /mnt/udisk;

else

umount /mnt/udisk;

fi

正規表示式 :

mdev的配置文件: busybo***x/doc/mdev.txt

USB熱拔插事件

usb universal serial bus 通用序列匯流排 的縮寫,是乙個 外部匯流排 標準,用於規範主機與 外圍裝置 的連線以及通訊,目前使用較多的版本有 usb1.1 usb2.0 usb3.0 等。usb 介面常用在諸如 usb序列裝置驅動 3g 4g 上網絡卡 藍芽裝置 串列埠裝置 u...

centos linux熱拔插scsi硬碟

自己配置虛擬機器,需要新增一塊虛擬硬碟存放資料。虛擬機器在更新軟體,不想停機。學習了下熱拔插硬碟的知識點 1.在虛擬機器中建立虛擬磁碟並新增。2.檢視目前的磁碟資訊 cat proc scsi scsi 我返回的結果如下 attached devices host scsi1 channel 00 ...

HDMI介面之HPD(熱拔插)

hdmi pin 19 dvi pin16 的功能是熱插拔檢測 hpd 這個訊號將作為hdmi 源端 source 是否發起edid讀,是否開始傳送 s訊號的依據。hpd是從hdmi顯示器端 sink 生成並輸出送往hdmi 源端 source 的乙個檢測訊號。熱插拔檢測的作用是當顯示器等hdmi介...