Skip to content

Instantly share code, notes, and snippets.

@webgeek1234
Last active August 29, 2015 14:07
Show Gist options
  • Save webgeek1234/7d7448e84a1880fef990 to your computer and use it in GitHub Desktop.
Save webgeek1234/7d7448e84a1880fef990 to your computer and use it in GitHub Desktop.
Build Shield First Stage Initramfs
#!/bin/sh
# ----------------------------------------------------------------------------
# build_shield_first_stage_initramfs.sh
# This script generates a small initramfs that mounts the boot partition and
# chainloads the official Fedora initramfs. It packages the initramfs and
# kernel a fastboot image. This is designed for use with the Nvidia Shield,
# but might be useful for other fastboot devices with a small boot partition.
# Copyright 2014, Aaron Kling <aaron.c.kling@gmail.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License at <http://www.gnu.org/licenses/> for
# more details.
# Usage: build_shield_first_stage_initramfs.sh kernel_version
# Revision history:
# 2014-10-06 Fix fastboot image creation. Usable as long as mkbootimg exists.
# 2014-10-05 Initial creation
# ----------------------------------------------------------------------------
RDROOT=/tmp/ramdisk
# Busybox is required and not normally installed
if [ ! -f "/usr/sbin/busybox" ]; then
echo "Busybox is not installed. Please run yum install busybox as root."
exit -1;
fi;
# mkbootimg is also required and not normally installed
if [ ! -f "/usr/bin/mkbootimg" ]; then
echo "mkbootimg is not installed. Please install it before continuing."
exit -1;
fi;
# Check to see if parameter is given
if [ -z "$1" ]; then
echo "Usage: $0 kernel-version";
echo "Example: $0 $(uname -r)";
exit -1;
fi;
# Check to see if parameter is valid
if [ ! -d "/lib/modules/$1" ]; then
echo "$1 is not an installed kernel.";
exit -1;
fi;
# Set up directory structure
rm -rf $RDROOT
mkdir $RDROOT
mkdir $RDROOT/bin
mkdir $RDROOT/etc
mkdir $RDROOT/lib
mkdir $RDROOT/lib/modules
mkdir $RDROOT/lib/modules/$1
mkdir $RDROOT/lib/modules/$1/kernel
mkdir $RDROOT/lib/modules/$1/kernel/drivers
mkdir $RDROOT/lib/modules/$1/kernel/drivers/mmc
mkdir $RDROOT/lib/modules/$1/kernel/drivers/mmc/card
mkdir $RDROOT/lib/modules/$1/kernel/drivers/mmc/core
mkdir $RDROOT/lib/modules/$1/kernel/drivers/mmc/host
mkdir $RDROOT/sbin
mkdir $RDROOT/usr
mkdir $RDROOT/usr/bin
mkdir $RDROOT/usr/sbin
# Copy in busybox
cp /usr/sbin/busybox $RDROOT/bin/
# Needs the GNU cpio since dracut uses a cpio algorithm not supported
# by busybox. Since there isn't currently a staticly linked cpio in
# Fedora's repos, the linked libraries need pulled in. Need to make
# a staticly linked cpio once COPR supports arm.
cp /usr/bin/cpio $RDROOT/usr/bin/
cp /lib/libgcc_s.so.1 $RDROOT/lib/
cp /lib/libc.so.6 $RDROOT/lib/
cp /lib/ld-linux-armhf.so.3 $RDROOT/lib/
# Copy in mmc modules and run depmod
cp /lib/modules/$1/modules.{builtin,order} $RDROOT/lib/modules/$1/
cp /lib/modules/$1/kernel/drivers/mmc/card/mmc_block.ko $RDROOT/lib/modules/$1/kernel/drivers/mmc/card/
cp /lib/modules/$1/kernel/drivers/mmc/core/mmc_core.ko $RDROOT/lib/modules/$1/kernel/drivers/mmc/core/
cp /lib/modules/$1/kernel/drivers/mmc/host/{mmci,mvsdio,omap_hsmmc,omap,sdhci-dove,sdhci-esdhc-imx,sdhci,sdhci-pltfm,sdhci-tegra}.ko $RDROOT/lib/modules/$1/kernel/drivers/mmc/host/
depmod -b $RDROOT $1
# Link only required programs
ln -s busybox $RDROOT/bin/cat
ln -s busybox $RDROOT/bin/cp
ln -s busybox $RDROOT/bin/echo
ln -s busybox $RDROOT/bin/gzip
ln -s busybox $RDROOT/bin/mkdir
ln -s busybox $RDROOT/bin/mount
ln -s busybox $RDROOT/bin/sh
ln -s busybox $RDROOT/bin/sleep
ln -s busybox $RDROOT/bin/umount
ln -s busybox $RDROOT/bin/uname
ln -s ../bin/busybox $RDROOT/sbin/init
ln -s ../bin/busybox $RDROOT/sbin/mdev
ln -s ../bin/busybox $RDROOT/sbin/modprobe
ln -s ../../bin/busybox $RDROOT/usr/bin/[
ln -s ../../bin/busybox $RDROOT/usr/sbin/switch_root
# A basic fstab is needed
echo "proc /proc proc defaults 0 0" > $RDROOT/etc/fstab
echo "sysfs /sys sysfs defaults 0 0" >> $RDROOT/etc/fstab
echo "debugfs /d debugfs defaults 0 0" >> $RDROOT/etc/fstab
# The main init
# Note the BOOTPART= is not escaped. It's getting the partition from the running system.
echo "#!/bin/sh" > $RDROOT/init
echo "BOOTPART=\"$(grep '/boot' /etc/fstab |awk '{ print $1 }')\"" >> $RDROOT/init
echo "TMPBOOT=/tmpboot" >> $RDROOT/init
echo "NEWROOT=/newroot" >> $RDROOT/init
echo "" >> $RDROOT/init
echo "# Prepare basic system" >> $RDROOT/init
echo "mkdir /proc" >> $RDROOT/init
echo "mkdir /sys" >> $RDROOT/init
echo "mount /proc" >> $RDROOT/init
echo "mount /sys" >> $RDROOT/init
echo "modprobe sdhci-tegra" >> $RDROOT/init
echo "modprobe mmc_block" >> $RDROOT/init
echo "sleep 1" >> $RDROOT/init
echo "mdev -s" >> $RDROOT/init
echo "" >> $RDROOT/init
echo "# Create mount points" >> $RDROOT/init
echo "mkdir -p \$TMPBOOT" >> $RDROOT/init
echo "mkdir -p \$NEWROOT" >> $RDROOT/init
echo "mount \$BOOTPART \$TMPBOOT" >> $RDROOT/init
echo "mount -ttmpfs -osize=32m tmpfs \$NEWROOT" >> $RDROOT/init
echo "" >> $RDROOT/init
echo "# Decompress and run the official initramfs" >> $RDROOT/init
echo "cp \$TMPBOOT/initramfs-\$(uname -r).img /tmp.cpio.gz" >> $RDROOT/init
echo "gzip -d /tmp.cpio.gz" >> $RDROOT/init
echo "cd \$NEWROOT && cpio --quiet -id < /tmp.cpio" >> $RDROOT/init
echo "umount \$BOOTPART" >> $RDROOT/init
echo "exec switch_root \$NEWROOT /sbin/init" >> $RDROOT/init
chmod 755 $RDROOT/init
# Generate the initramfs file
cd $RDROOT && find . |cpio --quiet -o --format=newc |gzip -c - > /tmp/first_stage_$1.img
# Generate the kernel appended with a modified dtb. The dtb has to be modified since dracut
# doesn't seem to mount /sysroot when root= is defined internally by kernel_cmdline=.
# Also need to add mkbootimg to a COPR repo once COPR supports arm.
dtc -Idtb -Odts -o /tmp/tegra114-roth.dts /boot/dtb-$1/tegra114-roth.dtb
sed -i "s|fbcon=rotate:1\"|fbcon=rotate:1 root=$(grep '/\ ' /etc/fstab |awk '{ print $1 }') ro\"|" /tmp/tegra114-roth.dts
dtc -Idts -Odtb -o /tmp/tegra114-roth.dtb /tmp/tegra114-roth.dts
cat /boot/vmlinuz-$1 /tmp/tegra114-roth.dtb > /tmp/vmlinuz-$1-dtb
mkbootimg --kernel /tmp/vmlinuz-$1-dtb --ramdisk /tmp/first_stage_$1.img -o /boot/fastboot-$1.img
# Remove intermediary files.
rm -rf $RDROOT
rm -f /tmp/first_stage_$1.img
rm -f /tmp/vmlinuz-$1-dtb
rm -f /tmp/tegra114-roth.dt*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment