########################################################################### # Script : Slackware ARM kernel's 'doinst.sh' post installation script # # Purpose : Append the correct Flattened Device Tree Blob ('FDT' file) to # # the corresponding zImage, and subsequently produce a suitable # # U-Boot 'uImage' file for devices that do not have a U-Boot # # capable of loading a FDT itself. # # Author : Stuart Winter # # Version: 1.01 # # Date : 18-Dec-2014 # ########################################################################### # Note: makepkg must always *prepend* the symlink code to this script # # since we rely on the versionless symlinks. # ########################################################################### # Change log # # v1.00 - 08-Jul-2014 # # * First version # # v1.01 - 18-Dec-2014 # # * OpenRD Kirkwood-based systems now use Flattened Device Tree since # # Linux v3.18. Removed old OpenRD code. # ########################################################################### # Ensure we can find mkimage first. u-boot-tools is supplied in the # installer, and it's a REQuired package so we should always be ok. # If the tool is not present, we bail out with 0 exit code since it may not # be an issue if the kernel does not need an appended FDT. which mkimage > /dev/null 2>&1 || { echo "Warning: 'mkimage' tool cannot be found - this may be a problem if your Kernel needs an appended FDT" ; exit 0 ;} # See if we can pull a DTB file name from the Kernel command line: if grep -iq "dtb=[a-zA-Z0-9]" /proc/cmdline ; then dtb="$( sed 's/.*dtb=\([^ ]*\).*/\1/' < /proc/cmdline )" fi # We need to set the Kernel name to be the same as the Slackware Kernel # package. Otherwise we end up running appending (for example) the Kirkwood # DTB file to the armv7 uImage. This may not be an issue, but it's ugly # to see and could cause unexpected problems. if grep -iq "slkkernel=[a-zA-Z0-9]" /proc/cmdline ; then slkkernel="$( sed 's/.*slkkernel=\([^ ]*\).*/\1/' < /proc/cmdline )" fi # Obtain the name of the zImage that we need for this particular kernel. # Unfortunately this won't work if you're installing the kernel package on a machine # other than the one upon which you'll be using this kernel on. # MACHINETYPE="$( uname -r | sed 's/\(.*-\)//g' )" # # This would take the package file name from the command line of installpkg: # sed -e 's?\x0? ?g' -e 's/\(.*installpkg \)//g' -e 's,.*/,,' /proc/$PPID/cmdline # These two are slightly less efficient ways of obtaining only the Kernel package name: #MACHINETYPE="$( sed -e 's?\x0? ?g' -e 's/\(.*installpkg \)//g' -e 's,.*/,,' < /proc/$PPID/cmdline | sed -n 's/.*kernel_//;s/-.*//p' )" #MACHINETYPE="$( ps -p $PPID -o cmd= | sed -e 's/\(.*installpkg \)//g' -e 's,.*/,,' | sed -n 's/.*kernel_//;s/-.*//p' )" # This will give us the kernel name from the package we're installing: MACHINETYPE="$( sed -ne 's/.*kernel_//;s/-.*//p' /proc/$PPID/cmdline )" if [ ! -z "$dtb" ]; then # We have been supplied with a DTB file name. Let's ensure that it exists. # We will always pre-pend /boot/dtb/ - there's no chance to put it elsewhere # since we won't always know what directory this install script is running from-- # we're not using chroot here. if [ ! -s boot/dtb/$dtb ]; then echo "Error: Unable to find DTB file 'boot/dtb/$dtb'" exit 0 else # Sanity check: if [ -z "$MACHINETYPE" ]; then echo "Error: Unable to determine machine type from the Kernel package" echo " that is currently being installed. This is necessary to" echo " determine which 'zImage' to use." exit 0 fi if [ -z "$slkkernel" ]; then echo "Error: Kernel parameter 'slkkernel' is unset. This parameter " echo " must be set to the name of the Slackware Kernel package" echo " that your system is using. " echo " For example:" echo " slkkernel=armv7 or slkkernel=armv5" exit 0 fi # Exit silently if the Slackware Kernel package name doesn't match the # Kernel parameter. It simply means that the user is installing an unneeded # Slackware Kernel package onto their system - as happens with a full installation. if [ "$MACHINETYPE" != "$slkkernel" ]; then exit 0 fi # Ensure that the zImage-$MACHINETYPE is sane, or at least not 0 bytes. if [ ! -s boot/zImage-$MACHINETYPE ]; then echo "Error: 'zImage-$MACHINETYPE' is missing or is 0 bytes" exit 0 else printf "\nAppending FDT 'boot/dtb/$dtb' to 'boot/uImage-${MACHINETYPE}' ..\n" # Append the DTB to a temporary zImage. We want to leave the existing one # in pristine condition particularly since 'upgradepkg' installs the package twice! cat boot/zImage-$MACHINETYPE boot/dtb/$dtb >> boot/zImage-$MACHINETYPE-appended # Create the new uImage using the appended zImage. mkimage writes through the symlink # to the versioned Kernel image file, so we don't need to faff around. # We'll let mkimage spit out the informational blurb so the user can see something useful happened. mkimage -A arm \ -O linux \ -T kernel \ -C none \ -a 0x00008000 \ -e 0x00008000 \ -n "Slackware on $MACHINETYPE" \ -d boot/zImage-$MACHINETYPE-appended \ boot/uImage-$MACHINETYPE rm -f boot/zImage-$MACHINETYPE-appended fi fi else # # We haven't been supplied with a DTB from the Kernel command line, so let's # try and figure it out. # ... at some point in the future. This isn't an easy task to code, and # probably isn't worth the effort either. For now let's just inform the user # that they will need to take some manual action. # Sanity check: if [ ! -f /proc/device-tree/model ]; then echo "WARNING: Unable to find /proc/device-tree/model -- cannot determine device type" # Don't exit with an error since it may not be catastrophic on some devices - esp. # if you're installing in a chroot or similar. exit 0 fi # For the Kirkwood systems that are supported (Sheeva, Guru, OpenRD), I know that # there's no newer U-Boot that supports FDT (if there is, let mozes@slackware.com know!) # so let's mark them as needing the DTB appended: APPENDNOTNEEDED=3 # by default we don't know what system type we are running on ( strings /proc/device-tree/model 2>/dev/null | grep -Eq "OpenRD|Guru|Sheeva" ) && APPENDNOTNEEDED=0 ( strings /proc/device-tree/model 2>/dev/null | grep -Eq "V2P-CA9|TrimSlice|Banana Pi" ) && APPENDNOTNEEDED=1 # Alert the user if we don't know about their device type and whether it needs # a DTB appending or not. #HWTYPE="$( grep '^Hardware.*: ' /proc/cpuinfo | sed 's/\(.*: \)//g' )" #case "$HWTYPE" in # # "NVIDIA Tegra SoC (Flattened Device Tree)") APPENDNOTNEEDED=1 # shift;; # # "Marvell Kirkwood (Flattened Device Tree)") APPENDNOTNEEDED=0 # shift;; # # *) APPENDNOTNEEDED=3 # shift;; # # --) shift; break;; #esac # The first error block here isn't true since if we can read the device tree model then # we know which is required - probably anyway, it depends on the specificity of the contents # e.g. can we know for sure which one we need for the GuruPlug? # this could be automated (and most of this script rewritten) to better handle this once I have # enough data to make distinctions. For now, upgrading from Slackware ARM 14.1 to 14.2 would # be hard on a first pass because the device tree wouldn't exist for some Kirkwood platforms, and # it's easier to let the user specify the required dtb= kernel parameter -- they just need to # read the docs: # case $APPENDNOTNEEDED in 0) echo "Error: Your device requires the FDT blob to be appended to the Kernel," echo " but we don't know which one is required since no Device Tree Blob" echo " (kernel parameter dtb=) was specified; you must manually append a" echo "DTB to the zImage and re-make the U-Boot uImage using the 'mkimage' tool." ;; # Note that a DTB not needed means that it doesn't need *appending* to the uImage. # This is because the U-Boot loader will have been updated to handle FDT within itself. 1) echo "Appended DTB not needed for this platform" > /dev/null ## don't make noise for no reason ;; 3) echo "Warning: No Device Tree Blob (kernel parameter dtb=) not specified" echo " and your system is unknown. You may need to append a DTB" echo " file to your zImage (and possibly re-create uImage if your" echo " boot loader is U-Boot) in order for your system to boot" echo " using this Kernel." ;; esac fi