#!/usr/bin/python # # Simple script to make it easier to create a custom initramfs that runs # something you want in init-premount (that is: in the boot process, # before disks are mounted). Beware, this is a very restrictive environment # # (c) 2009 Dennis Kaarsemaker - Licensed under the GNU GPL v3+ from __future__ import with_statement # Part 1: Settings # name -- should contain only letters and numbers name = 'hpfirmware' # update-initramfs.conf, must be a valid sh script # See /usr/share/initramfs-tools/update-initramfs.conf update_initramfs_conf = """ update_initramfs=yes backup_initramfs=no """ # initramfs.conf, must be a valid sh script # See /usr/share/initramfs-tools/initramfs.conf initramfs_conf = """ MODULES=netboot BUSYBOX=y BOOT=local DEVICE=eth0 NFSROOT=auto """ # Modules modules = """ # Needed for dell optiplex 755 heci e1000_ich9 e1000e """ # Part 2: Hook. See existing initramfs hooks for examples. # # This must be a valid sh script. It can be used to add or remove things # from the initramfs that is being built. The existing initramfs-tools # live in /usr/share/initramfs-tools/hooks. hook = """PREREQ="" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac . /usr/share/initramfs-tools/hook-functions # Drop usplash stuff rm -f ${DESTDIR}/sbin/usplash rm -f ${DESTDIR}/lib/libusplash.so.0 rm -f ${DESTDIR}/lib/libx86.so.1 rm -f ${DESTDIR}/sbin/usplash_write rm -f ${DESTDIR}/etc/usplash.conf rm -f ${DESTDIR}/usr/lib/usplash/usplash-artwork.so #Drop fuse/ntfs-3g rm -f ${DESTDIR}/sbin/mount.fuse rm -f ${DESTDIR}/lib/modules/2.6.27-11-generic/kernel/fs/fuse/fuse.ko rm -f ${DESTDIR}/bin/ntfs-3g rm -f ${DESTDIR}/lib/libfuse.so.2 rm -f ${DESTDIR}/lib/librt.so.1 rm -f ${DESTDIR}/lib/libdl.so.2 rm -f ${DESTDIR}/lib/libntfs-3g.so.28 rm -f ${DESTDIR}/lib/libpthread.so.0 # Copy over some binaries we need mkdir -p $DESTDIR/usr/bin/ $DESTDIR/usr/sbin copy_exec /usr/sbin/dmidecode /usr/sbin rm -f ${DESTDIR}/bin/gzip copy_exec /bin/gzip /bin copy_exec /bin/rm /bin copy_exec /bin/tar /bin copy_exec /usr/bin/tail /usr/bin copy_exec /bin/mktemp /bin copy_exec /bin/echo /bin copy_exec /bin/date /bin copy_exec /usr/bin/wget /usr/bin copy_exec /usr/bin/which /usr/bin copy_exec /usr/bin/yes /usr/bin """ # Part 3: Script. # # This bust be a valid sh (ash, not bash, so no bashisms) script. It is run # in the very restrictive initramfs environment. Make sure you add a call to # reboot at the end of this script. Look at existing scripts for examples. # These live in /usr/share/initramfs-tools/scripts/ # # This new script will be run in init-premount, so before any disk mounting # is attempted script = """PREREQ="udev" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac iface=eth0 for arg in $(cat /proc/cmdline); do case $arg in iface=*) iface=${arg#iface=} ;; esac done slumber=20 while [ 0 ]; do /bin/ipconfig $iface ret=$? if [ $ret -eq 0 ]; then break fi if [ $slumber -lt 1 ]; then echo "Can't bring up $iface" sleep 5 reboot fi sleep 0.5 slumber=$(( ${slumber} - 1)) echo "Slumber: $slumber" done echo "This machine is:" /usr/sbin/dmidecode -s system-manufacturer /usr/sbin/dmidecode -s bios-version /usr/sbin/dmidecode -s bios-release-date /usr/sbin/dmidecode -s system-product-name machine=`/usr/sbin/dmidecode -s system-product-name | awk '{ print $2 $3 }'` echo "Getting firmware for $machine ..." /usr/bin/wget http://10.147.103.2/firmware/hp/server/$machine.scexe yes | sh $machine.scexe reboot """ # Part 4: The actual work. Do not change unless you know what you are doing. # Create our workdir import os.path import tempfile import shutil import subprocess def make_initramfs(): # Copy kernel kernel_version = subprocess.Popen(['uname', '-r'], stdout=subprocess.PIPE).communicate()[0].strip() shutil.copy(os.path.join('/boot', 'vmlinuz-' + kernel_version), os.path.join(workdir,'vmlinuz-%s' % name)) # Create our mkinitramfs config hookf = os.path.join(workdir,'initramfs-tools','hooks','custom_%s' % name) scriptf = os.path.join(workdir,'initramfs-tools','scripts','init-premount','custom_%s' % name) os.makedirs(os.path.dirname(hookf)) os.makedirs(os.path.dirname(scriptf)) with open(hookf,'w') as fd: fd.write(hook) os.chmod(hookf, 0755) with open(scriptf,'w') as fd: fd.write(script) os.chmod(scriptf, 0755) with open(os.path.join(workdir,'initramfs-tools','initramfs.conf'),'w') as fd: fd.write(initramfs_conf) with open(os.path.join(workdir,'initramfs-tools','update-initramfs.conf'),'w') as fd: fd.write(update_initramfs_conf) with open(os.path.join(workdir,'initramfs-tools','modules'),'w') as fd: fd.write(modules) # Call mkinitramfs subprocess.Popen(['mkinitramfs', '-v', # add '-k' here to keep the initramfs build root for inspection '-d', os.path.join(workdir, 'initramfs-tools'), '-o', os.path.join(workdir, 'initrd-%s.img' % name), kernel_version]).wait() shutil.rmtree(os.path.join(workdir,'initramfs-tools')) workdir = tempfile.mkdtemp() try: make_initramfs() print "Your custom vmlinuz and initramfs can be found in %s and %s" % \ (os.path.join(workdir, 'vmlinuz-%s' % name), os.path.join(workdir, 'initrd-%s' % name)) except: print "Creating initramfs failed. Inspect %s for details" % workdir raise