Hi everyone, It's clear that it's possible to save a few seconds of boot time by using a pre-populated /dev, rather than letting udev populate it dynamically. This would be simple in a "locked down" system where upgrades were impossible or monolithic, but it's harder to do neatly in Debian. What I've done is not perfect, but it's a start and I thought I ought to write it up.
The existing code is in /etc/init.d/udev, which basically - starts udevd - runs udevadm trigger - runs udevadm settle The last two steps implement "coldplugging" - they generate hotplug events for the devices that were already attached when you started up, which mostly means things that are physically built in. It's this coldplugging that takes the time; I still start udev and it looks after any genuinely hotplugged devices. Also, I still use coldplugging for removeable devices that are already connected at boot - i.e. usb devices. I do this by adding the option "--subsystem-match=usb" to the udevadm trigger call. It's only the coldplugging for built-in devices that I've removed. In order to pre-populate /dev with entries for the coldplugged devices, I have hacked /etc/init.d/udev to check for and untar a file called /etc/init-devs.tar. If it doesn't find it, it falls back to the old behaviour. If it does exist, after untarring it does coldplugging for only usb devices as described above. More code in the same script generates the tar file if a sentinel file has been created asking it to do so. The tar file should be generated early on as other steps in the boot process may change permissions on things in /dev. It's important to remember that udev can be configured to carry out arbitrary actions. So simply recording what /dev entries it created may not be sufficient in some cases. The other thing that it commonly does is to load modules, but I've already bypassed that by building the drivers needed by built-in devices into the kernel. Net devices are one class of things that do more than just create /dev nodes, so they need to be properly coldplugged. But I've chosen to do that in a separate init script that runs much later, concurrent with X starting up. Wireless networking causes further complications because this is the one thing that I have in a module. I have currently hacked this based on its PCI ID to run during the later network coldplugging. So in summary I have the following in /etc/init.d/udev; I hope it's obvious where it goes: log_daemon_msg "Starting the hotplug events dispatcher" "udevd" if udevd --daemon; then log_end_msg $? else log_end_msg $? fi mkdir -p /dev/.udev/queue/ /dev/.udev/rules.d/ create_dev_root_rule /dev/.udev/ # Pre-populate /dev if this file exists. If you remove this # file you'll get the old behaviour. if [ -r /etc/init-devs.tar ] then echo "Installing initial devices" tar -x -C / -f /etc/init-devs.tar trigger_rules="--subsystem-match=usb" else trigger_rules="--subsystem-nomatch=net --attr-nomatch=vendor=0x1814" fi log_action_begin_msg "Synthesizing the initial hotplug events" if udevadm trigger $trigger_rules ; then log_action_end_msg $? else log_action_end_msg $? fi create_dev_makedev # wait for the udevd childs to finish log_action_begin_msg "Waiting for /dev to be fully populated" if udevadm settle; then log_action_end_msg 0 else log_action_end_msg 0 'timeout' fi if [ -f /etc/create-init-devs ] then tar cf /dev/init-devs.tar /dev # /etc is read-only or something I think fi and I have this in /etc/init.d/coldplug_networking: echo "Coldplugging network devices..." udevadm trigger --attr-match=vendor=0x1814 udevadm trigger --subsystem-match=net udevadm settle echo "Coldplugging network done." To use it, I touch /etc/create-init-devs, reboot, mv /dev/init-devs.tar /etc; rm /etc/create-init-devs. If for some reason I want to regenerate the files (after a kernel upgrade perhaps?) I rm /etc/init-devs.tar and do it again. I haven't used this much yet so if anyone can see any flaws please let me know. The main time saving comes from doing the network startup concurrently with the X startup; I forget exactly what that saves because I did it a while ago, but it's perhaps 3 seconds (in part due to a sleep in net.agent). The main /dev pre-population saves about 2 seconds. I don't think I'm going to spend much more time on this fast boot exercise, but there are two things that still bother me: - I want to get the kernel's 2 second probing of the touchpad off the critical path. - Setting the clock takes up to a second. But I don't think it would if we didn't have to use --directisa. So can someone remind me why we do that? I also look forward to improved X startup time using kernel mode setting, but I think I'll wait until someone else implements it. Cheers, Phil. _______________________________________________ Debian-eeepc-devel mailing list Debian-eeepc-devel@lists.alioth.debian.org http://lists.alioth.debian.org/mailman/listinfo/debian-eeepc-devel