免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 820 | 回复: 0
打印 上一主题 下一主题

精通initramfs构建step by step (八):coldplug [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-09 17:32 |只看该作者 |倒序浏览

精通initramfs构建step by step (八):coldplug
二十五、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目录。有关udev的规则文件编写,已超出了本文的范围,后续我有可能专文描述。
########################################################################
#
# Description : 40-modprobe.rules
#
# Authors   : Based on Open Suse Udev Rules
#   
kay.sievers@suse.de
#
# 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,启动CLFS系统,initramfs能够自动加载硬盘设备的驱动模块,系统顺利地从initramfs切换到了真正的CLFS的根文件系统。
---下节预告---现在,initramfs构建中最困难的"识别并自动加载硬件设备的驱动模块"的问题已经解决了,让我们稍稍停顿一下,回头再看看在内核编译时构建initramfs的另外两种方式,那么就请看下一个step:
精通initramfs构建step by step (九):内核编译时构建initramfs补遗


本文来自ChinaUnix博客,如果查看原文请点:[url]http://blog.chinaunix.net/u2/63991/showart_1856683.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP