Note: This is not really Arch-specific although I deal with Arch Linux files in this article; anyone can adapt it for their *NIX platform’s init process.
Quickstart
First, get your sound file ready. We are going to read it after the system has sourced our rc.conf MODULES array, so you are free to choose a player, format and location. To be safe, I have mine in boot, and use aplay instead of mplayer, so it is at /boot/audio.wav as (obviously) a WAVE instead of MP3 or OGG.
Edit /etc/rc.sysinit and look for the line:
# Load modules from the MODULES array defined in rc.conf
and then add:
# start some background audio /usr/sbin/alsactl restore /usr/bin/aplay /boot/audio.wav &
before the lines:
if [ -d /proc/acpi ]; then stat_busy "Loading standard ACPI modules" ACPI_MODULES="ac battery button fan processor thermal"
Or if you manually load modules (all or even a couple), then before:
# Wait for udev uevents
Else, as a last resort, before:
# bring up the loopback interface
Try from the earliest, and if you get low-level ALSA errors, it means the sound device didn’t initialise by the time you wanted it to run. In that case, try the other two positions. Any later than that, I don’t see a point. Also, remember to set a nice level beforehand with alsamixer and then alsactl store it. If you want a different set of levels separate from the post-boot system, simply use a different file with the –file option:
~# alsactl store -f /etc/asoundboot.state
Since this is still a little too late for my taste, I don’t kill it. Good for a non-invasive ambience track, especially if you run a login manager. If you’re very clever and into Rocket Science, you can also use a sound file which fits into the period of bootup from after modules have been loaded (Rocket Science Hint: time or bootchart). Or if you’re not very clever, you can just kill the process from somewhere, eg. /etc/rc.local:
killall -9 aplay
For what it’s worth, that is the earliest time we can play a sound file without modifying the system, and this is before any daemons are run. You can remove your alsa daemon from the system since we already restore the state during the above run (edit the alsactl line accordingly if you have made changes to /etc/conf.d/alsa). Like mentioned, the result is not good enough for me (and possibly a lot of others), because my bootup is 40 seconds til a fully-functional, action-ready and tiled KDE 4 desktop (30 to Awesome WM). Nevertheless, curiosity killed.
Warning: An update to initscripts will replace the sysinit file. Look for “NoUpgrade” in pacman.
Background
Sabayon Linux has been doing it ever since their LiveDVD releases of year 2006, and even though it’s not something everyone would like, the fact is that it gets the curious user excited no matter how nonsensical a purpose it serves. I used Sabayon from around late 2006 to early 2007, at which point I moved to Arch (and I never hopped again), so I can still remember that it had an option to “turn off” the music via the kernel line. Regardless of the on/off state, I never did hear the music. At one point of time, on Arch, I tried to implement something similar. I forgot what I did, whether it even worked, and lost the related prototype files if any at all (I do recall a custom daemon).
Anyway, someone on #archlinux asked about this yesterday, and it got me curious again. My stance is always the same:
There is no reason for any kind of “boot music” aside from when live media is used. Optical read speed is inherently slower than traditional disks or flash drives, and for LiveDVDs it equates to a significant amount of waiting time during the boot process. There, it makes ample sense. If you _are_ curious enough to try it nonetheless, on a sane, installed system, you have to ensure that the music does not start too early or too late, or else it becomes pointless to the extent I should have to punch you.
From this and this it appears Sabayon has something called a “Boot Music Infrastructure”, which is technically nothing more than an init script. The sound file itself is stored in /usr/share/sounds, and the script will read (i.e play) it while the rest of the daemons are being started. The following:
depend() { after modules before hostname before alsasound }
Translates linguistically to:
Start only after all modules have loaded, before the hostname is set, and before alsa state is restored.
I have no idea why they’re creating their own values for the audio levels. Anyway, theoretically, it might be possible to start the sound subsystem even earlier. That would mean injecting the modules (along with dependencies) and binaries into the kernel image (see mkinitcpio), and reconstructing init itself.
Say..a low-level method to play music from POST onwards would be really nice.
Another Rocket Science Hint: iPod
=p