summaryrefslogtreecommitdiff
path: root/mkinitramfs
blob: d7d3d6165596e1d44134d955add2af2bb8fa2096 (plain)
    1 #!/usr/bin/env bash
    2 #
    3 # Mkinitramfs creates a basic init ram fs with encryption support.
    4 # Copyright (C)  2016  Aaron Ball <nullspoon@oper.io>
    5 #
    6 # This program is free software: you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation, either version 3 of the License, or
    9 # (at your option) any later version.
   10 #
   11 # This program is distributed in the hope that it will be useful,
   12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 # GNU General Public License for more details.
   15 #
   16 # You should have received a copy of the GNU General Public License
   17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
   18 #
   19 
   20 
   21 # Hash of fully-qualified binaries
   22 declare -a fqbins
   23 
   24 
   25 #
   26 # Searches PATH for all binaries listed as function arguments. Each found
   27 # binary is then put into the global "bins" array.
   28 #
   29 # This function also serves to ensure all specified binaries are present and
   30 # in PATH. It will exit code 1 with an error message if any binaries are not
   31 # found.
   32 #
   33 # Note: To use this function, insert "declare -a fqbins" at top of script).
   34 #
   35 # @param bins All function arguments are the names of binaries to locate.
   36 #
   37 function resolve_bins {
   38   local args=${@}
   39 
   40   for i in ${args[@]}; do
   41     local path=$(which ${i} 2>/dev/null)
   42 
   43     if [[ $? -gt 0 ]]; then
   44       echo "Could not find binary ${i}. Is it installed?"
   45       exit 1
   46     fi
   47 
   48     echo "Located ${i} at ${path}"
   49     fqbins+=("${path}")
   50   done
   51 }
   52 
   53 
   54 #
   55 # Gets first path locatable in a string
   56 #
   57 function get_first_path {
   58   local str=${1}
   59 
   60   local out=''
   61   local cursor=''
   62 
   63   for ((i=0; i<${#str}; i++)); do
   64     if [[ ${str:$i:1} == '/' ]]; then
   65       cursor=${i}
   66       break
   67     fi
   68   done
   69 
   70   # Exit if no path found
   71   [[ ${cursor} == '' ]] && return
   72 
   73   while [[ ${str:$cursor:1} != ' ' ]] && [[ ${cursor} -lt ${#str} ]]; do
   74     out="${out}${str:$cursor:1}"
   75     cursor=$((${cursor} + 1))
   76   done
   77 
   78   echo "${out}"
   79 }
   80 
   81 
   82 function get_deps {
   83   local bin=${1}
   84 
   85   for dep in $(ldd ${bin}); do
   86      get_first_path "${dep}"
   87   done
   88 }
   89 
   90 
   91 #
   92 # Creates cpio file for specified initrd cache directory.
   93 # Outputs to /boot/initrd-${version}.
   94 #
   95 # @param cache   Path to the uncompressed source directory to be archived
   96 # @param version Version of initrd archive
   97 #
   98 function mkcpio {
   99   [[ -z ${1} ]] && echo "Initramfs cache path required." && exit 1
  100   [[ -z ${2} ]] && echo "Kernel version required." && exit 1
  101 
  102   local cache=${1}
  103   local version=${2}
  104 
  105   cd ${cache}
  106   fspath="/boot/initrd-${version}"
  107 
  108   # Notify user of initrd overwriting
  109   [[ -f ${fspath} ]] && echo -e "\n\n${fspath} exists. Overwriting.\n"
  110 
  111   # Create the initrd
  112   find . -print0 | cpio --null -ov --format=newc | xz -C crc32 -v -9 -c > ${fspath}
  113 }
  114 
  115 
  116 #
  117 # Sets up cache dir for later writing to an archive (via cpio).
  118 # Performs simple operations like creating a basic directory structure, 
  119 #
  120 # @param cache Path to the cache directory. Will be created if not exists
  121 #
  122 function cache_dir_setup {
  123   [[ -z ${1} ]] && echo "Please specify a cache dir." && exit 1
  124   local cache=${1}
  125 
  126   # Clean the cache so we start fresh
  127   rm -rf ${cache} && mkdir ${cache}
  128 
  129   local dirs=(bin dev etc lib lib32 lib64 mnt/root proc root run sbin sys usr)
  130 
  131   # Create the temporary directory structure
  132   for i in ${dirs[*]}; do
  133     mkdir -p ${cache}/${i}
  134   done
  135 }
  136 
  137 
  138 #
  139 # Checks installed kernel modules for the specified version to see if the
  140 # corresponding kernel has encryption support statically compiled in.
  141 #
  142 # @param version Version of kernel modules to check
  143 #
  144 function check_crypto_support {
  145   [[ -z ${1} ]] && echo "Kernel version required." && exit 1
  146   local version=${1}
  147 
  148   builtinpath=/lib/modules/${version}/modules.builtin
  149   
  150   # Check for encryption support
  151   if [[ ! $(grep dm-crypt ${builtinpath}) ]]; then
  152     echo -e "\n\nWarning: Static encryption support not found."
  153     echo "         Module dm-crypt not found in modules.builtin."
  154     echo "Press enter to continue, or Ctrl+c to exit and resolve."
  155     read
  156   fi
  157 }
  158 
  159 
  160 #
  161 # Checks to see if kernel modules for the specified version have been
  162 # installed.
  163 #
  164 # @param version Version to check for installation status
  165 #
  166 function check_kernel_version {
  167   [[ -z ${1} ]] && echo "Kernel version required." && exit 1
  168   local version=${1}
  169 
  170   modulespath=/lib/modules/${version}
  171   if [[ ! -d ${modulespath} ]]; then
  172     echo "Error: Could not find ${modulespath}."
  173     echo "Has kernel version ${version} been comiled?"
  174     exit 1
  175   fi
  176 }
  177 
  178 
  179 function main {
  180   [[ -z ${1} ]] && echo "Please specify a kernel version" && exit 1
  181 
  182   local version=${1}
  183 
  184   check_kernel_version ${version}
  185 
  186   local cache='/tmp/initrd'
  187   local res_path=/usr/share/mkinitramfs/
  188 
  189   # List of binaries to exist in the new initramfs
  190   resolve_bins \
  191     bash cat echo ls cryptsetup chmod chown mount sleep umount clear cut \
  192     grep less tr which blkid reboot shutdown switch_root
  193 
  194 
  195   # Set up the archive source dir.
  196   cache_dir_setup ${cache}
  197 
  198   # Ensure static crypto support exists in kernel
  199   check_crypto_support ${version}
  200 
  201   # Copy binary and dependencies to cache dir
  202   for bin in ${fqbins[@]}; do
  203     # Copy the binary of interest
  204     install -D "${bin}" "${cache}/${bin}"
  205 
  206     local deps=$(get_deps ${bin})
  207     # Copy each of the binary's deps
  208     for dep in ${deps[@]}; do
  209       install -D ${dep} "${cache}/${dep}"
  210     done
  211   done
  212 
  213   # Copy in message file
  214   [[ -f ${res_path}/msg ]] && install -D ${res_path}/msg ${cache}/etc/msg
  215   # Copy in init script and add execute
  216   install -D -m 755 ${res_path}/init ${cache}/init
  217   # Copy in the system shell profile
  218   install -D /etc/profile ${cache}/etc/profile
  219 
  220   # Create archive image
  221   mkcpio ${cache} ${version}
  222 }
  223 
  224 
  225 main ${@}

Generated by cgit