Last active
April 22, 2025 15:43
-
-
Save Yousha/6ebb8901ee114f399bfcd113c708c0cd to your computer and use it in GitHub Desktop.
Shell script to update Linux kernel. (Traditionally)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Update Linux Kernel | |
# Version: 2.0.0.2 | |
# Description: Script to download, config, compile, and install Linux kernel manually. | |
# Requirements: Slackware Linux, x86_64 architecture, root privileges. | |
# Usage: sudo ./update_linux_kernel.sh [<kernel_version>] | |
# Enable strict mode: Abort on errors, unset variables, and pipe failures. | |
set -o nounset # Exit if an unbound variable is used. | |
set -o errexit # Exit if any command fails. | |
set -o pipefail # Fail pipelines if any command in the pipeline fails. | |
# Environment / locale settings. | |
LANG=C | |
LC_ALL=C | |
IFS=$'\n\t' # Set IFS to default for better string handling. | |
# Constants | |
readonly KERNEL_BASE_URL="https://cdn.kernel.org/pub/linux/kernel" | |
readonly DEFAULT_KERNEL_VERSION="6.1.24" | |
readonly BUILD_THREADS=$(( ($(nproc) + 1) / 2 )) # Use half of available cores + 1. | |
readonly SOURCE_DIR="/usr/src" | |
# Log messages with timestamps. | |
log() { | |
local message="$*" | |
echo "$message" | |
} | |
# Exit with an error message and cleanup. | |
error_exit() { | |
log "ERROR: $1" | |
exit "${2:-1}" # Default exit code is 1 if not provided. | |
} | |
# Check if the user is root. | |
check_root() { | |
[[ "$EUID" -eq 0 ]] || error_exit "This script must be run as root." 13 | |
} | |
# Verify system architecture. | |
check_architecture() { | |
[[ "$(uname -m)" == "x86_64" ]] || error_exit "Only x86_64 architecture is supported." 1 | |
} | |
# Print usage instructions. | |
usage() { | |
echo "Usage: sudo $0 [<kernel_version>]" | |
echo "Note: If no kernel_version is provided, the default (${DEFAULT_KERNEL_VERSION}) is used." | |
} | |
# Check available disk space (minimum 3GB). | |
check_disk_space() { | |
local required_space_kb=3145728 # 3GB in KB. | |
local available_space=$(df -k --output=avail "$SOURCE_DIR" | tail -1) | |
[[ "$available_space" -ge "$required_space_kb" ]] || \ | |
error_exit "Insufficient disk space. Need at least 3GB in ${SOURCE_DIR}." 1 | |
} | |
# Check script dependencies. | |
check_dependencies() { | |
local required=("wget" "gcc" "make" "xz" "tar" "git") | |
local missing=() | |
for cmd in "${required[@]}"; do | |
if ! command -v "$cmd" >/dev/null 2>&1; then | |
missing+=("$cmd") | |
fi | |
done | |
if [[ ${#missing[@]} -gt 0 ]]; then | |
error_exit "Missing required tools: ${missing[*]}." 1 | |
fi | |
} | |
# Download and verify the kernel source. | |
download_kernel() { | |
local kernel_version="$1" | |
local major_version="v${kernel_version%%.*}.x" | |
local file_source="linux-${kernel_version}.tar.xz" | |
local url="${KERNEL_BASE_URL}/${major_version}/${file_source}" | |
mkdir -p "$SOURCE_DIR" | |
cd "$SOURCE_DIR" | |
# Remove old files if they exist. | |
rm -f "${file_source}"* | |
log "Downloading Linux kernel ${kernel_version}..." | |
if ! wget --quiet --show-progress --continue --output-document="${file_source}" "${url}"; then | |
error_exit "Failed to download kernel source from ${url}." | |
fi | |
} | |
# Extract kernel archive. | |
extract_kernel() { | |
local kernel_version="$1" | |
local file_source="linux-${kernel_version}.tar.xz" | |
local dir_source="linux-${kernel_version}" | |
if [[ -d "$dir_source" ]]; then | |
log "Source directory exists, cleaning..." | |
rm -rf "$dir_source" | |
fi | |
log "Extracting kernel source..." | |
if ! tar --extract --xz --file="${file_source}"; then | |
error_exit "Failed to extract kernel source." | |
fi | |
log "Removing downloaded kernel archive..." | |
rm -f "${file_source}"* | |
} | |
# Configure kernel build. | |
configure_kernel() { | |
local kernel_version="$1" | |
local dir_source="linux-${kernel_version}" | |
cd "${SOURCE_DIR}/${dir_source}" | |
log "Using current system kernel config as base..." | |
if [[ -f /proc/config.gz ]]; then | |
zcat /proc/config.gz > .config | |
elif [[ -f /boot/config-$(uname -r) ]]; then | |
cp "/boot/config-$(uname -r)" .config | |
else | |
error_exit "Could not find current kernel config." | |
fi | |
log "Preparing kernel build configs..." | |
make ARCH=x86_64 olddefconfig || error_exit "Failed to configure kernel." | |
} | |
# Compile kernel. | |
build_kernel() { | |
local kernel_version="$1" | |
local dir_source="linux-${kernel_version}" | |
cd "${SOURCE_DIR}/${dir_source}" | |
log "Building kernel... (${BUILD_THREADS} threads)" | |
if ! make ARCH=x86_64 -j"${BUILD_THREADS}" all; then | |
error_exit "Kernel build failed." | |
fi | |
} | |
# Install kernel related files. | |
install_kernel() { | |
local dir_source="linux-${kernel_version}" | |
cd "${SOURCE_DIR}/${dir_source}" | |
log "Installing kernel modules... (/lib/modules/)" | |
if ! make modules_install; then | |
error_exit "Failed to install kernel modules." | |
fi | |
log "Installing kernel headers... (/usr/include/)" | |
if ! make headers_install INSTALL_HDR_PATH=/usr; then | |
error_exit "Failed to install kernel headers." | |
fi | |
log "Installing kernel and System.map... (/boot/)" | |
if ! make install; then | |
error_exit "Failed to install kernel." | |
fi | |
} | |
# Regenerate InitialRAMFilesystem. | |
regenerate_initramfs() { | |
local kernel_version="$1" | |
local script_path="/usr/share/mkinitrd/mkinitrd_command_generator.sh" | |
[[ -x "$script_path" ]] || error_exit "InitRAMFs script not found or not executable." | |
log "Regenerating InitRAMFs for kernel ${kernel_version}..." | |
if ! "$script_path" -k "${kernel_version}" > update_mkinit.sh; then | |
error_exit "Failed to generate InitRAMFs script." | |
fi | |
chmod +x update_mkinit.sh | |
if ! ./update_mkinit.sh; then | |
error_exit "Failed to regenerate InitRAMFs." | |
fi | |
rm -f update_mkinit.sh | |
} | |
main() { | |
# Use the first argument as kernel version, or default if not provided. | |
local kernel_version="${1:-$DEFAULT_KERNEL_VERSION}" | |
log "Starting kernel update to version ${kernel_version}..." | |
log "System: $(uname -a)" | |
check_root | |
check_architecture | |
check_dependencies | |
check_disk_space | |
download_kernel "$kernel_version" | |
extract_kernel "$kernel_version" | |
configure_kernel "$kernel_version" | |
build_kernel "$kernel_version" | |
install_kernel | |
regenerate_initramfs "$kernel_version" | |
cleanup_old_kernels | |
log "Kernel update to version ${kernel_version} completed successfully." | |
log "System needs to be rebooted to use the new kernel." | |
exit 0 | |
} | |
# Show usage if -h or --help is provided. | |
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then | |
usage | |
exit 0 | |
fi | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment