#!/usr/bin/env bash # DEBUG if [ ! -z "$DEBUG" ]; then echo "DEBUG is set" set -o xtrace fi SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) # shellcheck source=HW5/config.sh source "${SCRIPT_DIR}/config.sh" function download() { local -r url="${1}" local -r sha256="${2}" if which nix-prefetch-url >/dev/null 2>&1; then nix-prefetch-url --print-path --type sha256 "${url}" "${sha256}" | tail -n 1 else local -r tmpdir="$(mktemp -d)" cd "${tmpdir}" && local -r filename="$(curl "${url}" --remote-name -w "%{filename_effective}")" echo "${tmpdir}/${filename}" fi } function download_extract() { local -r url="${1}" local -r sha256="${2}" local -r path="${3}" echo "Downloading '${url}'..." local -r archive="$(download "${url}" "${sha256}")" if [ -z "$sha256" ]; then echo "Verify checksum of '${archive}'..." if [ "$(sha256sum "${archive}" | cut -d' ' -f1)" != "${sha256}" ]; then echo 'Error: Invalid checksum!' return 1 fi fi echo "Extracting '${archive}'..." tar -xf "${archive}" -C "${path}" || return $? } function download_extract_all() { download_extract "${KERNEL_URL}" "${KERNEL_SHA256}" "${KERNEL_PATH}" || return $? } function cpu_count() { if [ -f /proc/cpuinfo ]; then grep -c ^processor /proc/cpuinfo else if which sysctl >/dev/null 2>&1; then sysctl hw.ncpu | cut -d ' ' -f 2 else echo '4' fi fi } # compile kernel function compile_kernel() { ln -sf "${KERNEL_CONFIG_PATH}" "${KERNEL_SOURCE_PATH}/.config" echo "Compile kernel..." time ARCH="$KERNEL_ARCH" make -C "${KERNEL_SOURCE_PATH}" -j "$(cpu_count)" || return $? echo "Copy kernel..." cp -pf "${KERNEL_IMAGE}" "${ARTIFACTS_PATH}/" } function find_modules() { find "$MODULES_DIR" -mindepth 1 -maxdepth 1 -type d -not -name '_*' -print0 } function compile_module() { local -r module_dir="$1" local -r module="$(basename "$module_dir")" local -r module_test_src="${module_dir}/${module}.test.c" echo "Compile kernel module '$module'..." time KVER="$KERNEL_VERSION" make -C "${module_dir}" -j "$(cpu_count)" || return $? if [ -f "${module_test_src}" ]; then time make -C "${module_dir}" -j "$(cpu_count)" test || return $? fi echo "Copy kernel module '$module'..." cp -pf "${module_dir}/${module}.ko" "$MODULES_DST_DIR/" cp -pf "${module_dir}/${module}.ko.test" "$MODULES_DST_DIR/" if [ -f "${module_test_src}" ]; then build_binary "${module_dir}/${module}.ko.test" "$(basename "$MODULES_DST_DIR")/" || return $? fi } function modules_compile() { mkdir -p "$MODULES_DST_DIR" while IFS= read -r -d '' module_dir; do compile_module "$module_dir" || return $? done < <(find_modules) } function compile() { modules_compile || return $? } function get_binary_linker() { local -r binary="$1" file "$binary" | grep -o -E ', interpreter (.*\.so(\.[0-9]+)?)' | cut -d' ' -f3 } # clean untracked git files function clean() { echo "Clean non git files..." cd "${SCRIPT_DIR}" && git clean -dfx || return $? } function main() { local -r cmd="${1:-all}" shift 1 case "$cmd" in all ) download_extract_all && compile ;; download ) download_extract_all ;; compile ) compile ;; modules ) modules_compile ;; modules_build ) modules_compile ;; modules_copy ) modules_copy ;; clean ) clean ;; * ) echo "Error: unkown command" && false ;; esac return $? } main "$@"