1#!/bin/sh 2# Copyright (C) 2011 O.S. Systems Software LTDA. 3# Licensed on MIT 4# 5# Provides the API to be used by the initramfs modules 6# 7# Modules need to provide the following functions: 8# 9# <module>_enabled : check if the module ought to run (return 1 to skip) 10# <module>_run : do what is need 11# 12# Boot parameters are available on environment in the as: 13# 14# 'foo=value' as 'bootparam_foo=value' 15# 'foo' as 'bootparam_foo=true' 16# 'foo.bar[=value] as 'foo_bar=[value|true]' 17 18# Register a function to be called before running a module 19# The hook is called as: 20# <function> pre <module> 21add_module_pre_hook() { 22 MODULE_PRE_HOOKS="$MODULE_PRE_HOOKS $1" 23} 24 25# Register a function to be called after running a module 26# The hook is called as: 27# <function> post <module> 28add_module_post_hook() { 29 MODULE_POST_HOOKS="$MODULE_POST_HOOKS $1" 30} 31 32# Load kernel module 33load_kernel_module() { 34 if modprobe $1 >/dev/null 2>&1; then 35 info "Loaded module $1" 36 else 37 debug "Failed to load module $1" 38 fi 39} 40 41# Prints information 42msg() { 43 echo "$@" >/dev/console 44} 45 46# Prints information if verbose bootparam is used 47info() { 48 [ -n "$bootparam_verbose" ] && echo "$@" >/dev/console 49} 50 51# Prints information if debug bootparam is used 52debug() { 53 [ -n "$bootparam_debug" ] && echo "DEBUG: $@" >/dev/console 54} 55 56# Prints a message and start a endless loop 57fatal() { 58 echo $1 >/dev/console 59 echo >/dev/console 60 61 if [ -n "$bootparam_init_fatal_sh" ]; then 62 sh 63 else 64 while [ "true" ]; do 65 sleep 3600 66 done 67 fi 68} 69 70# Variables shared amoung modules 71ROOTFS_DIR="/rootfs" # where to do the switch root 72MODULE_PRE_HOOKS="" # functions to call before running each module 73MODULE_POST_HOOKS="" # functions to call after running each module 74MODULES_DIR=/init.d # place to look for modules 75EFI_DIR=/sys/firmware/efi # place to store device firmware information 76 77# make mount stop complaining about missing /etc/fstab 78touch /etc/fstab 79 80# initialize /proc, /sys, /run/lock and /var/lock 81mkdir -p /proc /sys /run/lock /var/lock 82mount -t proc proc /proc 83mount -t sysfs sysfs /sys 84 85if [ -d $EFI_DIR ];then 86 mount -t efivarfs none /sys/firmware/efi/efivars 87fi 88 89# populate bootparam environment 90for p in `cat /proc/cmdline`; do 91 if [ -n "$quoted" ]; then 92 value="$value $p" 93 if [ "`echo $p | sed -e 's/\"$//'`" != "$p" ]; then 94 eval "bootparam_${quoted}=${value}" 95 unset quoted 96 fi 97 continue 98 fi 99 100 opt=`echo $p | cut -d'=' -f1` 101 opt=`echo $opt | sed -e 'y/.-/__/'` 102 if [ "`echo $p | cut -d'=' -f1`" = "$p" ]; then 103 eval "bootparam_${opt}=true" 104 else 105 value="`echo $p | cut -d'=' -f2-`" 106 if [ "`echo $value | sed -e 's/^\"//'`" != "$value" ]; then 107 quoted=${opt} 108 continue 109 fi 110 eval "bootparam_${opt}=\"${value}\"" 111 fi 112done 113 114# use /dev with devtmpfs 115if grep -q devtmpfs /proc/filesystems; then 116 mkdir -p /dev 117 mount -t devtmpfs devtmpfs /dev 118else 119 if [ ! -d /dev ]; then 120 fatal "ERROR: /dev doesn't exist and kernel doesn't has devtmpfs enabled." 121 fi 122fi 123 124mkdir $ROOTFS_DIR 125 126# Load and run modules 127for m in $MODULES_DIR/*; do 128 # Skip backup files 129 if [ "`echo $m | sed -e 's/\~$//'`" != "$m" ]; then 130 continue 131 fi 132 133 module=`basename $m | cut -d'-' -f 2` 134 debug "Loading module $module" 135 136 # pre hooks 137 for h in $MODULE_PRE_HOOKS; do 138 debug "Calling module hook (pre): $h" 139 eval "$h pre $module" 140 debug "Finished module hook (pre): $h" 141 done 142 143 # process module 144 . $m 145 146 if ! eval "${module}_enabled"; then 147 debug "Skipping module $module" 148 continue 149 fi 150 151 debug "Running ${module}_run" 152 eval "${module}_run" 153 154 # post hooks 155 for h in $MODULE_POST_HOOKS; do 156 debug "Calling module hook (post): $h" 157 eval "$h post $module" 158 debug "Finished module hook (post): $h" 159 done 160done 161 162# Catch all 163fatal "ERROR: Initramfs failed to initialize the system." 164