#!/bin/sh # installer.SlackBuild # Build a Raspberry Pi installer image # # Copyright 2012 David Spencer, Baildon, West Yorkshire, U.K. # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #------------------------------------------------------------------------------ # # To run this script you will need: # * initrd-versatile.img in this directory, possibly as a symlink to your # armedslack-current tree (it's in armedslack-current/isolinux) # * A recently built kernel tree with 'Image' and modules in # '../kernel_raspi/linux' # * The firmware folder in '../raspi-boot/firmware' # * 'Extra' packages already built in $OUTPUT # #------------------------------------------------------------------------------ TMP=${TMP:-/tmp} OUTPUT=${OUTPUT:-/tmp} MYTMP=$TMP/installer IMAGE=raspi-slack-installer_$(date '+%d%b%y').img CWD=$(pwd) rm -rf $MYTMP mkdir -p $MYTMP set -e #------------------------------------------------------------------------------ # (0) Extract the installer tree from the upstream initrd rm -rf $MYTMP/initrd-tree mkdir -p $MYTMP/initrd-tree cd $MYTMP/initrd-tree zcat $CWD/initrd-versatile.img | cpio -iv #------------------------------------------------------------------------------ # (1) Add raspi device nodes (maybe not needed -- to be checked) # # cd $MYTMP/initrd-tree/ # tar xvf $CWD/../raspi-devs/_devs.tar.xz # #------------------------------------------------------------------------------ # (2) Add README and raspi-extra to the installer tree cat $CWD/README.installer > $MYTMP/initrd-tree/README mkdir -p $MYTMP/initrd-tree/raspi-extra for pkgbase in \ raspi-boot \ raspi-hacks \ kernel_raspi \ kernel-modules-raspi do pkg=$(ls -t $OUTPUT/$pkgbase-*.t?z | head -1) cp -a -v \ $pkg \ $MYTMP/initrd-tree/raspi-extra/ done #------------------------------------------------------------------------------ # (3) Add kernel modules to the installer tree # Remove the versatile modules # (it might be helpful to qemu users to keep them, but they're just too big) rm -rf $MYTMP/initrd-tree/lib/modules/* cd $CWD/../kernel_raspi/linux make modules_install INSTALL_MOD_PATH=$MYTMP/initrd-tree #------------------------------------------------------------------------------ # (4) Roll the initrd. We name it 'install.gz' so it's recognisable and # can be removed after installation. cd $MYTMP/initrd-tree find . | cpio -o -v -H newc | gzip -9c > $MYTMP/install.gz #------------------------------------------------------------------------------ # (5) Make an empty image and format it rm -f $MYTMP/$IMAGE echo "Making $MYTMP/$IMAGE" # Let's work in 512B sectors. # 128 "heads" and 32 "sectors" => 2MiB "cylinders", # That's 4096 sectors per "cylinder". # 4 "cylinders" = 8MiB erase block boundary (or 2*4MiB boundaries). # So keep partition boundaries at 4-cyl multiples for best results. # That's 16384 sectors per erase block. # 944 "cylinders" = 1979711488B, which is < 2MB, so fits on a "2Mb" card. dd if=/dev/zero of=$MYTMP/$IMAGE bs=512 count=$(( 128 * 32 * 944 )) # Drop in the prepared MBR. # Partition 1 start 1 end 180223 type 0c # Partition 2 start 180224 end 1032191 type 82 # Partition 3 start 1032192 end 3866623 type 83 dd if=$CWD/mbr of=$MYTMP/$IMAGE bs=512 count=1 conv=notrunc LOOPDEV=$(losetup -f --show $MYTMP/$IMAGE) mdadm --build --force raspimg --level linear --raid-devices 1 $LOOPDEV # It takes a few secs to ready /dev/md/* apparently sleep 5 mkdosfs -I /dev/md/raspimg1 mkswap /dev/md/raspimg2 mkfs -t ext4 -O ^has_journal -E stride=2,stripe-width=1024 -b 4096 /dev/md/raspimg3 # Save the empty SD card image as a useful by-product. # (Very time consuming, so only do this if needed.) EMPTY=raspi-empty-sdcard.img if [ ! -f $OUTPUT/$EMPTY.gz ]; then echo "Compressing image to $OUTPUT/$EMPTY.gz" gzip -c $MYTMP/$IMAGE > $OUTPUT/$EMPTY.gz sha1sum $OUTPUT/$EMPTY.gz > $OUTPUT/$EMPTY.gz.sha1 fi #------------------------------------------------------------------------------ # (6) Copy everything onto image partition 1 mkdir -p $MYTMP/mnt mount -t vfat /dev/md/raspimg1 $MYTMP/mnt # Get the boot firmware and default config cd $CWD/../raspi-boot/firmware cp -v \ boot/bootcode.bin \ boot/LICENCE.broadcom \ $MYTMP/mnt cp -v \ boot/start*.elf \ boot/fixup*.dat \ $MYTMP/mnt/ # Use 16 Mb of the memory for the graphics, # so we have the rest for the installer sed "s|@GPUMEM@|16|" $CWD/../raspi-boot/config.txt > $MYTMP/mnt/config.txt # Kernel cp -v \ $CWD/../kernel_raspi/linux/arch/arm/boot/zImage \ $MYTMP/mnt/kernel.img # Pass a simplified command line echo "dwc_otg.lpm_enable=0 console=tty1" > $MYTMP/mnt/cmdline.txt # Get install.gz cp -v \ $MYTMP/install.gz \ $MYTMP/mnt/ # Add initrd stuff for install.gz to /boot/config.txt and /boot/cmdline.txt LOADADDR="0xa00000" SIZE="0x$(printf '%x' $(stat --format='%s' $MYTMP/mnt/install.gz))" echo "initramfs install.gz $LOADADDR" >> $MYTMP/mnt/config.txt sed -i -e "s/\$/ initrd=$LOADADDR,$SIZE/" $MYTMP/mnt/cmdline.txt # Assemble the README cat $CWD/README.installer > $MYTMP/mnt/README echo "" >> $MYTMP/mnt/README echo "" >> $MYTMP/mnt/README cat $MYTMP/initrd-tree/.installer-version >> $MYTMP/mnt/README echo "Raspberry Pi:" >> $MYTMP/mnt/README echo "-------------" >> $MYTMP/mnt/README KREV=$(echo $CWD/../kernel_raspi/raspberrypi-linux-*.tar.gz | sed -e "s|.*raspberrypi-linux-||" -e "s|\.tar\.gz||") echo "Kernel git rev.......: $KREV" >> $MYTMP/mnt/README BREV=$(echo $CWD/../raspi-boot/raspberrypi-firmware-*.tar.gz | sed -e "s|.*raspberrypi-firmware-||" -e "s|\.tar\.gz||") echo "Boot fw git rev......: $BREV" >> $MYTMP/mnt/README echo "Build host...........: $(uname -a)" >> $MYTMP/mnt/README echo "Build date...........: $(date)" >> $MYTMP/mnt/README #------------------------------------------------------------------------------ # (7) Compress and do a checksum umount -v $MYTMP/mnt mdadm --stop /dev/md/raspimg losetup -d $LOOPDEV echo "Compressing image to $OUTPUT/$IMAGE.gz" gzip -c $MYTMP/$IMAGE > $OUTPUT/$IMAGE.gz sha1sum $OUTPUT/$IMAGE.gz > $OUTPUT/$IMAGE.gz.sha1 rm $MYTMP/$IMAGE #------------------------------------------------------------------------------ exit 0