summaryrefslogtreecommitdiff
path: root/mkinitramfs
blob: 9ea6760e0adece80d0051e02df479e2c045ff3af (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   echo "Building initrd to ${fspath}"
  113   find . -print0 | cpio --null -o --format=newc | xz -C crc32 -9 -c > ${fspath}
  114 }
  115 
  116 
  117 #
  118 # Sets up cache dir for later writing to an archive (via cpio).
  119 # Performs simple operations like creating a basic directory structure, 
  120 #
  121 # @param cache Path to the cache directory. Will be created if not exists
  122 #
  123 function cache_dir_setup {
  124   [[ -z ${1} ]] && echo "Please specify a cache dir." && exit 1
  125   local cache=${1}
  126 
  127   # Clean the cache so we start fresh
  128   rm -rf ${cache} && mkdir ${cache}
  129 
  130   local dirs=(bin dev etc lib lib32 lib64 mnt/root proc root run sbin sys usr)
  131 
  132   # Create the temporary directory structure
  133   for i in ${dirs[*]}; do
  134     mkdir -p ${cache}/${i}
  135   done
  136 }
  137 
  138 
  139 #
  140 # Checks installed kernel modules for the specified version to see if the
  141 # corresponding kernel has encryption support statically compiled in.
  142 #
  143 # @param version Version of kernel modules to check
  144 #
  145 function check_crypto_support {
  146   [[ -z ${1} ]] && echo "Kernel version required." && exit 1
  147   local version=${1}
  148 
  149   builtinpath=/lib/modules/${version}/modules.builtin
  150   
  151   # Check for encryption support
  152   if [[ ! $(grep dm-crypt ${builtinpath}) ]]; then
  153     echo -e "\n\nWarning: Static encryption support not found."
  154     echo "         Module dm-crypt not found in modules.builtin."
  155     echo "Press enter to continue, or Ctrl+c to exit and resolve."
  156     read
  157   fi
  158 }
  159 
  160 
  161 #
  162 # Checks to see if kernel modules for the specified version have been
  163 # installed.
  164 #
  165 # @param version Version to check for installation status
  166 #
  167 function check_kernel_version {
  168   [[ -z ${1} ]] && echo "Kernel version required." && exit 1
  169   local version=${1}
  170 
  171   modulespath=/lib/modules/${version}
  172   if [[ ! -d ${modulespath} ]]; then
  173     echo "Error: Could not find ${modulespath}."
  174     echo "Has kernel version ${version} been comiled?"
  175     exit 1
  176   fi
  177 }
  178 
  179 
  180 function main {
  181   [[ -z ${1} ]] && echo "Please specify a kernel version" && exit 1
  182 
  183   local version=${1}
  184 
  185   check_kernel_version ${version}
  186 
  187   local cache='/tmp/initrd'
  188   local res_path=/usr/share/mkinitramfs/
  189 
  190   # List of binaries to exist in the new initramfs
  191   resolve_bins \
  192     bash cat echo ls cryptsetup chmod chown mount sleep umount clear cut \
  193     grep less tr which blkid partprobe reboot shutdown switch_root
  194 
  195 
  196   # Set up the archive source dir.
  197   cache_dir_setup ${cache}
  198 
  199   # Ensure static crypto support exists in kernel
  200   check_crypto_support ${version}
  201 
  202   # Copy binary and dependencies to cache dir
  203   for bin in ${fqbins[@]}; do
  204     # Copy the binary of interest
  205     install -D "${bin}" "${cache}/${bin}"
  206 
  207     local deps=$(get_deps ${bin})
  208     # Copy each of the binary's deps
  209     for dep in ${deps[@]}; do
  210       install -D ${dep} "${cache}/${dep}"
  211     done
  212   done
  213 
  214   # Copy in message file
  215   [[ -f ${res_path}/msg ]] && install -D ${res_path}/msg ${cache}/etc/msg
  216   # Copy in init script and add execute
  217   install -D -m 755 ${res_path}/init ${cache}/init
  218   # Copy in the system shell profile
  219   install -D /etc/profile ${cache}/etc/profile
  220 
  221   # Create archive image
  222   mkcpio ${cache} ${version}
  223 }
  224 
  225 
  226 main ${@}

Generated by cgit