summaryrefslogtreecommitdiff
path: root/mkinitramfs
blob: b0b015ebe0e4934c8672a1b771ca0a8088f0c3fa (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   # Copy in terminals database
  138   mkdir -p "${cache}/usr/share"
  139   cp -r /usr/share/terminfo "${cache}/usr/share/terminfo"
  140 }
  141 
  142 
  143 #
  144 # Checks installed kernel modules for the specified version to see if the
  145 # corresponding kernel has encryption support statically compiled in.
  146 #
  147 # @param version Version of kernel modules to check
  148 #
  149 function check_crypto_support {
  150   [[ -z ${1} ]] && echo "Kernel version required." && exit 1
  151   local version=${1}
  152 
  153   builtinpath=/lib/modules/${version}/modules.builtin
  154   
  155   # Check for encryption support
  156   if [[ ! $(grep dm-crypt ${builtinpath}) ]]; then
  157     echo -e "\n\nWarning: Static encryption support not found."
  158     echo "         Module dm-crypt not found in modules.builtin."
  159     echo "Press enter to continue, or Ctrl+c to exit and resolve."
  160     read
  161   fi
  162 }
  163 
  164 
  165 #
  166 # Checks to see if kernel modules for the specified version have been
  167 # installed.
  168 #
  169 # @param version Version to check for installation status
  170 #
  171 function check_kernel_version {
  172   [[ -z ${1} ]] && echo "Kernel version required." && exit 1
  173   local version=${1}
  174 
  175   modulespath=/lib/modules/${version}
  176   if [[ ! -d ${modulespath} ]]; then
  177     echo "Error: Could not find ${modulespath}."
  178     echo "Has kernel version ${version} been comiled?"
  179     exit 1
  180   fi
  181 }
  182 
  183 
  184 function main {
  185   [[ -z ${1} ]] && echo "Please specify a kernel version" && exit 1
  186 
  187   local version=${1}
  188 
  189   check_kernel_version ${version}
  190 
  191   local cache='/tmp/initrd'
  192   local res_path=/usr/share/mkinitramfs/
  193 
  194   # List of binaries to exist in the new initramfs
  195   resolve_bins \
  196     bash cat echo ls cryptsetup chmod chown mount sleep umount clear cut \
  197     grep less tr which blkid partprobe reboot shutdown switch_root
  198 
  199 
  200   # Set up the archive source dir.
  201   cache_dir_setup ${cache}
  202 
  203   # Ensure static crypto support exists in kernel
  204   check_crypto_support ${version}
  205 
  206   # Copy binary and dependencies to cache dir
  207   for bin in ${fqbins[@]}; do
  208     # Copy the binary of interest
  209     install -D "${bin}" "${cache}/${bin}"
  210 
  211     local deps=$(get_deps ${bin})
  212     # Copy each of the binary's deps
  213     for dep in ${deps[@]}; do
  214       install -D ${dep} "${cache}/${dep}"
  215     done
  216   done
  217 
  218   # Copy in message file
  219   [ -f "/etc/msg" ] && install -D "/etc/msg" "${cache}/etc/msg"
  220   # Copy in init script and add execute
  221   install -D -m 755 "${res_path}/init" "${cache}/init"
  222   # Copy in the system shell profile
  223   install -D "/etc/profile" "${cache}/etc/profile"
  224 
  225   # Create archive image
  226   mkcpio ${cache} ${version}
  227 }
  228 
  229 
  230 main ${@}

Generated by cgit