萬盛學電腦網

 萬盛學電腦網 >> Linux教程 >> mdev的hotplug模式介紹

mdev的hotplug模式介紹

  mdev的hotplug模式

  上面的試驗中,我們在加載完驅動模塊後調用了mdev -s 命令來生成硬盤的設備文件。其實,可以使用mdev的hotplug模式在加載內核時自動生成對應的設備文件:

  在執行insmod命令前,用

  echo /sbin/mdev > /proc/sys/kernel/hotplug

  命令設置系統的hotplug程序為mdev。

  後續使用insmod命令加載模塊時,系統自動調用mdev生成相應的設備文件。

  注意:內核必須配置支持hotplug功能。

  udev的coldplug模式

  內核在啟動時已經檢測到了系統的硬件設備,並把硬件設備信息通過sysfs內核虛擬文件 系統導出。sysfs文件系統由系統初始化腳本掛載到/sys上。udev掃描sysfs文件系統,根據硬件設備信息生成熱插拔(hotplug)事 件,udev再讀取這些事件,生成對應的硬件設備文件。由於沒有實際的硬件插拔動作,所以這一過程被稱為coldplug。我們的initramfs就是 利用這一機制,加載硬件設備的驅動程序模塊。

  udev完成coldplug操作,需要下面三個程序:

  udevd——作為deamon,記錄hotplug事件,然後排隊後再發送給udev,避免事件沖突(race conditions)。

  udevtrigger——掃描sysfs文件系統,生成相應的硬件設備hotplug事件。

  udevsettle——查看udev事件隊列,等隊列內事件全部處理完畢才退出。

  在initramfs的init腳本中可以執行下面的語句實現coldplug功能:

  mkdir -p /dev/.udev/db

  udevd --daemon

  mkdir -p /dev/.udev/queue

  udevtrigger

  udevsettle

  許多文檔提到的在udevd --daemon 命令前要執行

  echo > /proc/sys/kernel/hotplug

  命令,經驗證,在我們的initramfs環境下的coldplug功能中並不需要。

  用udev自動加載設備驅動模塊

  了解了udev的coldplug的機理,我們就試驗一下用udev自動加載設備驅動模塊,並生成硬件設備文件。

  (1)從 /sbin 目錄下拷貝udevd、udevtrigger、udevsettle程序到image目錄下的sbin目錄下,並用ldd命令找到它們所需要的動態庫文件,拷貝到image目錄下的lib目錄下。

  (2)修改init腳本,增加coldplug功能:

  #!/bin/sh

  mount -t proc proc /proc

  mount -t sysfs sysfs /sys

  mdev -s

  #using udev autoload hard disk driver module

  mkdir -p /dev/.udev/db

  udevd --daemon

  mkdir -p /dev/.udev/queue

  udevtrigger

  udevsettle

  mount /dev/sda8 /mnt

  killall udevd

  exec switch_root /mnt /sbin/init

  注意:在切換到真正根文件系統前,要把udevd進程殺掉,否則會和真正根文件系統中的udev腳本的執行相沖突。這就是上面killall udevd 語句的作用。

  (3)編寫udev規則文件

  規 則文件是udev的靈魂,沒有規則文件,udev無法自動加載硬件設備的驅動模塊。為了簡單,我們直接使用CLFS中的40- modprobe.rules,把它拷貝到image目錄下的etc/udev/rules.d目錄。

  #

  # Description : 40-modprobe.rules

  #

  # Authors : Based on Open Suse Udev Rules

  # [url=mailto:[email protected]][email protected]

  #

  # Adapted to : Jim Gifford

  # LFS : Alexander E. Patrakov

  #

  # Version : 00.01

  #

  # Notes :

  #

  ########################################################################

  # hotplug

  ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}"

  # scsi

  SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0|7|14", RUN+="/sbin/modprobe sd_mod"

  SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="On[sS]tream", RUN+="/sbin/modprobe osst"

  SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", RUN+="/sbin/modprobe st"

  SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="[45]", RUN+="/sbin/modprobe sr_mod"

  SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg"

  # floppy

  KERNEL=="nvram", ACTION=="add", RUN+="load_floppy_module.sh"

  注意:上面的

  ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}"

  語 句是實現自動加載硬件設備驅動模塊功能的關鍵,它根據sysfs文件系統中記錄的模塊aliases數據,用modprobe命令加載對應的內核模塊。有 關模塊aliases的進一步說明,可參考CLFS手冊(CLFS-1.0.0-x86)中的11.5.2.4. Module Loading一節的描述。

  (4)拷貝modprobe命令

  前一節提到過,busybox的modprobe 命令不能正常使用,所以我們需要拷貝 /sbin 目錄下的modprobe命令到image目錄下的sbin目錄,供udev加載內核模塊使用。

  再用ldd命令檢查一下 /sbin/modprobe 命令所需的動態庫文件,如果有則拷貝到image/lib目錄下。(我的檢查結果是,除了libc6外,不需要其他動態庫,所以不需要拷貝)

  好了,重新生成initramfs,initramfs能夠自動加載硬盤設備的驅動模塊,系統順利地從initramfs切換到了真正的根文件系統。

copyright © 萬盛學電腦網 all rights reserved