feat: Implement complete Zero OS Alpine Initramfs Builder
- Complete bash framework with strict error handling - Modular library system (docker, alpine, components, initramfs, kernel, testing) - Rust component integration (zinit, rfs, mycelium) with musl targeting - Rootless Docker/Podman support for GitHub Actions - Centralized configuration in config/build.conf - 2-stage module loading system - Strip + UPX optimization for minimal size - Complete zinit integration replacing OpenRC - GitHub Actions CI/CD pipeline - Comprehensive documentation and usage guides Components: - Latest stable kernel 6.12.44 - Alpine Linux 3.22 base - ThreeFold components: zinit, mycelium, rfs, corex - Target: ~8-12MB final initramfs.cpio.xz
This commit is contained in:
265
scripts/lib/kernel.sh
Normal file
265
scripts/lib/kernel.sh
Normal file
@@ -0,0 +1,265 @@
|
||||
#!/bin/bash
|
||||
# Kernel building with embedded initramfs
|
||||
|
||||
# Source common functions
|
||||
LIB_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${LIB_SCRIPT_DIR}/common.sh"
|
||||
|
||||
# Kernel configuration
|
||||
KERNEL_VERSION="${KERNEL_VERSION:-6.12.44}"
|
||||
KERNEL_SOURCE_URL="${KERNEL_SOURCE_URL:-https://cdn.kernel.org/pub/linux/kernel}"
|
||||
KERNEL_CONFIG_SOURCE="${KERNEL_CONFIG_SOURCE:-${PROJECT_ROOT}/configs/kernel-config-generic}"
|
||||
|
||||
# Download kernel source
|
||||
function kernel_download_source() {
|
||||
local kernel_dir="$1"
|
||||
local version="${2:-$KERNEL_VERSION}"
|
||||
|
||||
section_header "Downloading Kernel Source"
|
||||
|
||||
local major_version=$(echo "$version" | cut -d. -f1)
|
||||
local url="${KERNEL_SOURCE_URL}/v${major_version}.x/linux-${version}.tar.xz"
|
||||
local temp_file="/tmp/linux-${version}.tar.xz"
|
||||
local source_dir="${kernel_dir}/linux-${version}"
|
||||
|
||||
log_info "Kernel version: ${version}"
|
||||
log_info "Download URL: ${url}"
|
||||
log_info "Target directory: ${kernel_dir}"
|
||||
|
||||
# Clean existing kernel directory
|
||||
if [[ -d "$kernel_dir" ]]; then
|
||||
log_info "Cleaning existing kernel directory"
|
||||
safe_rmdir "$kernel_dir"
|
||||
fi
|
||||
safe_mkdir "$kernel_dir"
|
||||
|
||||
# Download kernel source
|
||||
if [[ ! -f "$temp_file" ]]; then
|
||||
log_info "Downloading kernel source: ${version}"
|
||||
safe_execute wget --progress=dot:giga -O "$temp_file" "$url"
|
||||
else
|
||||
log_info "Using cached kernel source: ${temp_file}"
|
||||
fi
|
||||
|
||||
# Verify download
|
||||
local file_size=$(get_file_size "$temp_file")
|
||||
log_info "Kernel source size: ${file_size}"
|
||||
|
||||
# Extract kernel source
|
||||
log_info "Extracting kernel source"
|
||||
safe_execute tar -xJf "$temp_file" -C "$kernel_dir"
|
||||
|
||||
# Verify extraction
|
||||
if [[ ! -d "$source_dir" ]]; then
|
||||
log_error "Kernel source extraction failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create symlink for easier access
|
||||
safe_execute ln -sf "linux-${version}" "${kernel_dir}/current"
|
||||
|
||||
# Cleanup download
|
||||
safe_execute rm "$temp_file"
|
||||
|
||||
log_info "Kernel source download complete: ${source_dir}"
|
||||
}
|
||||
|
||||
# Apply kernel configuration with embedded initramfs
|
||||
function kernel_apply_config() {
|
||||
local kernel_dir="$1"
|
||||
local initramfs_path="$2"
|
||||
local config_source="${3:-$KERNEL_CONFIG_SOURCE}"
|
||||
|
||||
section_header "Applying Kernel Configuration"
|
||||
|
||||
local source_dir="${kernel_dir}/current"
|
||||
|
||||
if [[ ! -d "$source_dir" ]]; then
|
||||
log_error "Kernel source directory not found: ${source_dir}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$config_source" ]]; then
|
||||
log_error "Kernel config source not found: ${config_source}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$initramfs_path" ]]; then
|
||||
log_error "Initramfs file not found: ${initramfs_path}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
safe_execute cd "$source_dir"
|
||||
|
||||
# Copy base configuration
|
||||
log_info "Copying kernel configuration from: ${config_source}"
|
||||
safe_copy "$config_source" ".config"
|
||||
|
||||
# Update configuration for embedded initramfs
|
||||
log_info "Updating configuration for embedded initramfs"
|
||||
log_info "Initramfs path: ${initramfs_path}"
|
||||
|
||||
# Resolve absolute path for initramfs
|
||||
local abs_initramfs_path=$(resolve_path "$initramfs_path")
|
||||
|
||||
# Modify config for embedded initramfs
|
||||
kernel_modify_config_for_initramfs "$abs_initramfs_path"
|
||||
|
||||
# Run olddefconfig to apply defaults for any new options
|
||||
log_info "Running olddefconfig to finalize configuration"
|
||||
safe_execute make olddefconfig
|
||||
|
||||
log_info "Kernel configuration applied successfully"
|
||||
}
|
||||
|
||||
# Modify kernel config for embedded initramfs
|
||||
function kernel_modify_config_for_initramfs() {
|
||||
local initramfs_path="$1"
|
||||
|
||||
log_info "Modifying kernel config for embedded initramfs"
|
||||
|
||||
# Use sed to update configuration
|
||||
safe_execute sed -i "s|^CONFIG_INITRAMFS_SOURCE=.*|CONFIG_INITRAMFS_SOURCE=\"${initramfs_path}\"|" .config
|
||||
|
||||
# Ensure XZ compression is enabled for initramfs
|
||||
safe_execute sed -i 's/^# CONFIG_RD_XZ is not set/CONFIG_RD_XZ=y/' .config
|
||||
safe_execute sed -i 's/^CONFIG_INITRAMFS_COMPRESSION_NONE=y/# CONFIG_INITRAMFS_COMPRESSION_NONE is not set/' .config
|
||||
safe_execute sed -i 's/^# CONFIG_INITRAMFS_COMPRESSION_XZ is not set/CONFIG_INITRAMFS_COMPRESSION_XZ=y/' .config
|
||||
|
||||
# Verify critical settings
|
||||
if ! grep -q "CONFIG_INITRAMFS_SOURCE=\"${initramfs_path}\"" .config; then
|
||||
log_error "Failed to set INITRAMFS_SOURCE in kernel config"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! grep -q "CONFIG_RD_XZ=y" .config; then
|
||||
log_error "Failed to enable XZ decompression in kernel config"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Kernel config updated for embedded initramfs"
|
||||
}
|
||||
|
||||
# Build kernel with embedded initramfs
|
||||
function kernel_build_with_initramfs() {
|
||||
local kernel_config="$1"
|
||||
local initramfs_path="$2"
|
||||
local output_file="$3"
|
||||
local kernel_dir="${4:-${PROJECT_ROOT}/kernel}"
|
||||
|
||||
section_header "Building Kernel with Embedded Initramfs"
|
||||
|
||||
# Download kernel source if needed
|
||||
if [[ ! -d "${kernel_dir}/current" ]]; then
|
||||
kernel_download_source "$kernel_dir"
|
||||
fi
|
||||
|
||||
# Apply configuration
|
||||
kernel_apply_config "$kernel_dir" "$initramfs_path" "$kernel_config"
|
||||
|
||||
local source_dir="${kernel_dir}/current"
|
||||
safe_execute cd "$source_dir"
|
||||
|
||||
# Clean previous build
|
||||
log_info "Cleaning previous kernel build"
|
||||
safe_execute make clean
|
||||
|
||||
# Determine number of cores for parallel build
|
||||
local cores=$(nproc)
|
||||
local jobs=$((cores > 1 ? cores - 1 : 1)) # Leave one core free
|
||||
log_info "Building with ${jobs} parallel jobs"
|
||||
|
||||
# Build kernel
|
||||
log_info "Building kernel (this may take a while)..."
|
||||
safe_execute make -j${jobs} bzImage
|
||||
|
||||
# Verify kernel was built
|
||||
local kernel_image="arch/x86/boot/bzImage"
|
||||
if [[ ! -f "$kernel_image" ]]; then
|
||||
log_error "Kernel build failed - bzImage not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Copy to output location
|
||||
local output_dir=$(dirname "$output_file")
|
||||
safe_mkdir "$output_dir"
|
||||
safe_copy "$kernel_image" "$output_file"
|
||||
|
||||
# Verify final kernel
|
||||
local kernel_size=$(get_file_size "$output_file")
|
||||
log_info "Kernel build complete:"
|
||||
log_info " Output file: ${output_file}"
|
||||
log_info " Kernel size: ${kernel_size}"
|
||||
|
||||
# Verify initramfs is embedded
|
||||
if strings "$output_file" | grep -q "initramfs"; then
|
||||
log_info "✓ Initramfs appears to be embedded in kernel"
|
||||
else
|
||||
log_warn "Initramfs embedding verification inconclusive"
|
||||
fi
|
||||
}
|
||||
|
||||
# Build modules for initramfs
|
||||
function kernel_build_modules() {
|
||||
local kernel_dir="$1"
|
||||
local modules_install_dir="$2"
|
||||
local version="${3:-$KERNEL_VERSION}"
|
||||
|
||||
section_header "Building Kernel Modules"
|
||||
|
||||
local source_dir="${kernel_dir}/current"
|
||||
|
||||
if [[ ! -d "$source_dir" ]]; then
|
||||
log_error "Kernel source directory not found: ${source_dir}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
safe_execute cd "$source_dir"
|
||||
|
||||
# Build modules
|
||||
local cores=$(nproc)
|
||||
local jobs=$((cores > 1 ? cores - 1 : 1))
|
||||
|
||||
log_info "Building kernel modules with ${jobs} parallel jobs"
|
||||
safe_execute make -j${jobs} modules
|
||||
|
||||
# Install modules to staging area
|
||||
log_info "Installing modules to: ${modules_install_dir}"
|
||||
safe_mkdir "$modules_install_dir"
|
||||
safe_execute make modules_install INSTALL_MOD_PATH="$modules_install_dir"
|
||||
|
||||
# Run depmod to create module dependencies
|
||||
local modules_dir="${modules_install_dir}/lib/modules/${version}"
|
||||
if [[ -d "$modules_dir" ]]; then
|
||||
log_info "Running depmod for module dependencies"
|
||||
safe_execute depmod -a -b "$modules_install_dir" "$version"
|
||||
fi
|
||||
|
||||
log_info "Kernel modules build complete"
|
||||
}
|
||||
|
||||
# Clean kernel build artifacts
|
||||
function kernel_cleanup() {
|
||||
local kernel_dir="$1"
|
||||
local keep_source="${2:-false}"
|
||||
|
||||
section_header "Cleaning Kernel Build Artifacts"
|
||||
|
||||
if [[ "$keep_source" == "true" ]]; then
|
||||
log_info "Keeping source, cleaning build artifacts only"
|
||||
local source_dir="${kernel_dir}/current"
|
||||
if [[ -d "$source_dir" ]]; then
|
||||
safe_execute cd "$source_dir"
|
||||
safe_execute make clean
|
||||
fi
|
||||
else
|
||||
log_info "Removing entire kernel directory"
|
||||
safe_rmdir "$kernel_dir"
|
||||
fi
|
||||
|
||||
log_info "Kernel cleanup complete"
|
||||
}
|
||||
|
||||
# Export functions
|
||||
export -f kernel_download_source kernel_apply_config kernel_modify_config_for_initramfs
|
||||
export -f kernel_build_with_initramfs kernel_build_modules kernel_cleanup
|
||||
Reference in New Issue
Block a user