From a7a7a6160bcfac196ef254f8fd931faf64ef806a Mon Sep 17 00:00:00 2001 From: Josephine Pfeiffer Date: Sun, 1 Jun 2025 14:31:36 +0200 Subject: [PATCH] fix ci & cleanup mkintcpio patching --- .github/workflows/release.yml | 29 +++- Containerfile | 10 ++ README.md | 2 +- patches/mkinitcpio-s390x-base-hook.patch | 176 ++++++++++++---------- patches/mkinitcpio-s390x.conf | 9 ++ scripts/build-all.sh | 24 +++ scripts/build-busybox-s390x.sh | 44 ++++-- scripts/build-initramfs-final.sh | 179 ++++++++--------------- scripts/build-kernel-container.sh | 3 + 9 files changed, 265 insertions(+), 211 deletions(-) create mode 100644 patches/mkinitcpio-s390x.conf diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 280a80e..ac57348 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,14 +31,26 @@ jobs: echo "Building required containers..." # Build the main container scripts/build-container.sh - # Tag it with the additional name used by initramfs script - sudo podman tag s390x-archlinux-dev s390x-mkinitcpio-complete - name: Build kernel run: | echo "Building s390x kernel..." scripts/build-kernel-container.sh + - name: Build s390x busybox + run: | + echo "Building s390x busybox binary..." + # The build-all.sh script will handle this automatically + # but we'll call it explicitly for clarity in CI + if [ ! -f output/busybox-s390x-static ]; then + sudo podman run --rm \ + -v $PWD:/work \ + -v $PWD/output:/output \ + -w /work \ + s390x-archlinux-dev \ + /work/scripts/build-busybox-s390x.sh + fi + - name: Build initramfs run: | echo "Building s390x initramfs..." @@ -69,6 +81,11 @@ jobs: # Create tarball of all artifacts tar -czf archlinux-s390x-${{ github.event.inputs.version }}.tar.gz -C release-artifacts . + + # Capture build information + echo "KERNEL_VERSION=6.6.10" >> $GITHUB_ENV + echo "MKINITCPIO_COMMIT=$(cd mkinitcpio-source && git rev-parse HEAD)" >> $GITHUB_ENV + echo "MKINITCPIO_SHORT_COMMIT=$(cd mkinitcpio-source && git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Create GitHub Release uses: softprops/action-gh-release@v1 @@ -80,10 +97,16 @@ jobs: ${{ github.event.inputs.release_notes }} + ## Build Information + + - **Kernel Version**: ${{ env.KERNEL_VERSION }} + - **mkinitcpio**: Built from commit [`${{ env.MKINITCPIO_SHORT_COMMIT }}`](https://github.com/archlinux/mkinitcpio/commit/${{ env.MKINITCPIO_COMMIT }}) + - **Build Date**: ${{ github.event.repository.updated_at }} + ## Release Contents This release includes: - - **vmlinuz-linux-s390x**: Linux kernel 6.6.10 for s390x architecture + - **vmlinuz-linux-s390x**: Linux kernel ${{ env.KERNEL_VERSION }} for s390x architecture - **initramfs-linux-s390x.img**: Initial RAM filesystem with s390x busybox - **Boot configuration files**: IPL configuration for s390x mainframes - **SHA256SUMS**: Checksums for all artifacts diff --git a/Containerfile b/Containerfile index b4b8dae..d78439e 100644 --- a/Containerfile +++ b/Containerfile @@ -8,9 +8,17 @@ RUN dnf install -y \ gcc-s390x-linux-gnu \ binutils-s390x-linux-gnu \ kernel-cross-headers \ + kernel-headers \ glibc-devel \ glibc-headers \ glibc-static \ + glibc-common \ + glibc-all-langpacks \ + musl-devel \ + musl-gcc \ + musl-libc-static \ + libstdc++-devel \ + libstdc++-static \ # Kernel build dependencies make \ flex \ @@ -47,6 +55,8 @@ RUN dnf install -y \ coreutils \ util-linux \ file \ + busybox \ + bsdtar \ && dnf clean all # Upgrade meson to latest version (Fedora 39 has 1.3.2, mkinitcpio needs >=1.4.0) diff --git a/README.md b/README.md index cb99f8b..7c25871 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Uses **Fedora containers with Podman** for cross-compilation: ```bash # Container images: s390x-fedora-kernel # Kernel compilation -s390x-mkinitcpio-complete # Initramfs generation +s390x-archlinux-dev # All-in-one development container ``` ### Key Scripts: diff --git a/patches/mkinitcpio-s390x-base-hook.patch b/patches/mkinitcpio-s390x-base-hook.patch index d756f76..71f57cc 100644 --- a/patches/mkinitcpio-s390x-base-hook.patch +++ b/patches/mkinitcpio-s390x-base-hook.patch @@ -1,79 +1,97 @@ ---- a/install/base -+++ b/install/base -@@ -3,10 +3,60 @@ - - build() { - local applet -- -- add_binary /usr/lib/initcpio/busybox /bin/busybox -- -- for applet in $(/usr/lib/initcpio/busybox --list); do -+ -+ # Use s390x busybox binary if available (cross-architecture support) -+ if [[ -f "/work/output/busybox-s390x-native" ]]; then -+ echo "Using s390x busybox binary" -+ add_file "/work/output/busybox-s390x-native" "/bin/busybox" 755 -+ -+ # Create symlinks for busybox applets (using a known list since we can't execute cross-arch binary) -+ local busybox_applets=( -+ "[" "[[" "ash" "awk" "basename" "cat" "chgrp" "chmod" "chown" "cp" "cut" -+ "date" "dd" "df" "dirname" "dmesg" "du" "echo" "env" "expr" "false" -+ "find" "grep" "head" "hostname" "id" "kill" "ln" "ls" "mkdir" "mknod" -+ "mktemp" "mount" "mv" "printf" "ps" "pwd" "readlink" "rm" "rmdir" -+ "sed" "sh" "sleep" "sort" "stat" "tail" "tar" "test" "touch" "tr" -+ "true" "umount" "uname" "uniq" "wc" "which" "whoami" "xargs" -+ ) -+ -+ for applet in "${busybox_applets[@]}"; do -+ add_symlink "/usr/bin/$applet" busybox -+ done -+ else -+ echo "Warning: s390x busybox not found, using system busybox (may cause architecture mismatch)" -+ add_binary /usr/lib/initcpio/busybox /bin/busybox -+ for applet in $(/usr/lib/initcpio/busybox --list); do -+ add_symlink "/usr/bin/$applet" busybox -+ done -+ fi -+ -+ # For other binaries, try to use available versions, otherwise skip -+ echo "Adding kmod utilities..." -+ if type -P kmod >/dev/null 2>&1; then -+ add_binary kmod -+ for applet in {dep,ins,rm,ls}mod mod{probe,info}; do -+ add_symlink "/usr/bin/$applet" kmod -+ done -+ else -+ echo "Warning: kmod not found, skipping module utilities" -+ fi -+ -+ # Check for additional utilities (may not be available in cross-compile environment) -+ echo "Checking for additional utilities..." -+ for binary in blkid mount umount switch_root; do -+ if type -P "$binary" >/dev/null 2>&1; then -+ echo "Adding $binary" -+ add_binary "$binary" -+ else -+ echo "Warning: $binary not found, skipping" -+ fi -+ done -+ -+ # Original code (for reference): -+ # add_binary /usr/lib/initcpio/busybox /bin/busybox -+ # for applet in $(/usr/lib/initcpio/busybox --list); do - add_symlink "/usr/bin/$applet" busybox - done - -@@ -16,9 +66,10 @@ - add_symlink "/usr/bin/$applet" kmod - done - -- add_binary blkid -- map add_binary mount umount -- add_binary switch_root -+ # add_binary blkid -+ # map add_binary mount umount -+ # add_binary switch_root -+ # (These are now handled conditionally above) - - add_binary "/usr/lib/initcpio/init_functions" "/init_functions" - add_binary "/usr/lib/initcpio/init" "/init" 755 \ No newline at end of file +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0-only +# Modified for s390x cross-architecture support + +build() { + local applet + + # Use s390x busybox binary if available (cross-architecture support) + if [[ -f "/work/output/busybox-s390x-static" ]]; then + echo "Using s390x static busybox binary" + add_file "/work/output/busybox-s390x-static" "/bin/busybox" 755 + + # Create symlinks for busybox applets (using a known list since we can't execute cross-arch binary) + local busybox_applets=( + "[" "[[" "ash" "awk" "basename" "cat" "chgrp" "chmod" "chown" "cp" "cut" + "date" "dd" "df" "dirname" "dmesg" "du" "echo" "env" "expr" "false" + "find" "grep" "head" "hostname" "id" "kill" "ln" "ls" "mkdir" "mknod" + "mktemp" "mount" "mv" "printf" "ps" "pwd" "readlink" "rm" "rmdir" + "sed" "sh" "sleep" "sort" "stat" "tail" "tar" "test" "touch" "tr" + "true" "umount" "uname" "uniq" "wc" "which" "whoami" "xargs" + ) + + for applet in "${busybox_applets[@]}"; do + add_symlink "/usr/bin/$applet" busybox + done + elif [[ -f "/work/output/busybox-s390x-native" ]]; then + echo "Using s390x busybox binary" + add_file "/work/output/busybox-s390x-native" "/bin/busybox" 755 + + # Create symlinks for busybox applets (using a known list since we can't execute cross-arch binary) + local busybox_applets=( + "[" "[[" "ash" "awk" "basename" "cat" "chgrp" "chmod" "chown" "cp" "cut" + "date" "dd" "df" "dirname" "dmesg" "du" "echo" "env" "expr" "false" + "find" "grep" "head" "hostname" "id" "kill" "ln" "ls" "mkdir" "mknod" + "mktemp" "mount" "mv" "printf" "ps" "pwd" "readlink" "rm" "rmdir" + "sed" "sh" "sleep" "sort" "stat" "tail" "tar" "test" "touch" "tr" + "true" "umount" "uname" "uniq" "wc" "which" "whoami" "xargs" + ) + + for applet in "${busybox_applets[@]}"; do + add_symlink "/usr/bin/$applet" busybox + done + else + echo "Warning: s390x busybox not found, using system busybox (may cause architecture mismatch)" + # Try to find busybox in various locations + if [[ -f /usr/lib/initcpio/busybox ]]; then + add_binary /usr/lib/initcpio/busybox /bin/busybox + elif [[ -f /usr/bin/busybox ]]; then + add_binary /usr/bin/busybox /bin/busybox + elif [[ -f /bin/busybox ]]; then + add_binary /bin/busybox /bin/busybox + else + echo "ERROR: No busybox binary found!" + return 1 + fi + # Get applet list from the binary we found + for applet in $(busybox --list 2>/dev/null || echo "sh ash"); do + add_symlink "/usr/bin/$applet" busybox + done + fi + + # Add kmod with applet symlinks (if available) + if type -P kmod >/dev/null 2>&1; then + echo "Adding kmod utilities..." + add_binary kmod + for applet in {dep,ins,rm,ls}mod mod{probe,info}; do + add_symlink "/usr/bin/$applet" kmod + done + else + echo "Warning: kmod not found, module utilities will not be available" + fi + + # Check for additional utilities (may not be available in cross-compile environment) + for binary in blkid mount umount switch_root; do + if type -P "$binary" >/dev/null 2>&1; then + echo "Adding $binary" + add_binary "$binary" + else + echo "Warning: $binary not found, skipping (functionality may be limited)" + fi + done + + # Always add init files + echo "Adding init files..." + add_file "/usr/lib/initcpio/init_functions" "/init_functions" + add_file "/usr/lib/initcpio/init" "/init" 755 +} + +help() { + cat < include/byteswap.h << 'BYTESWAP_EOF' +# Create minimal byteswap.h (always create to ensure compatibility) +echo "Creating minimal byteswap.h for cross-compilation..." +mkdir -p include + +# Create byteswap.h that uses system stdint.h +cat > include/byteswap.h << 'BYTESWAP_EOF' #ifndef _BYTESWAP_H #define _BYTESWAP_H @@ -92,14 +93,28 @@ static inline uint64_t bswap_64(uint64_t x) { #endif /* _BYTESWAP_H */ BYTESWAP_EOF + +# Remove any conflicting stdint.h from busybox source +if [ -f include/stdint.h ]; then + echo "Removing busybox's conflicting stdint.h" + rm -f include/stdint.h fi -# Build with specific flags to handle missing headers -echo "Building busybox..." +# Let busybox find its own headers +echo "Building busybox with minimal configuration..." +make clean || true + +# Try building with the cross compiler's sysroot +SYSROOT=$(s390x-linux-gnu-gcc -print-sysroot) +echo "Using sysroot: $SYSROOT" + +# Build with proper include path order - system headers first make \ - EXTRA_CFLAGS="-I$(pwd)/include -D__MUSL__ -static" \ - EXTRA_LDFLAGS="-static -pthread" \ - CONFIG_EXTRA_LDLIBS="pthread" \ + CFLAGS="--sysroot=$SYSROOT -I$(pwd)/include" \ + LDFLAGS="-static" \ + CONFIG_STATIC=y \ + HOSTCC=gcc \ + HOSTCFLAGS="" \ -j$(nproc) 2>&1 | tee build.log # Verify the binary was built and is correct architecture @@ -108,9 +123,12 @@ if [ -f busybox ]; then file busybox ls -la busybox - # Copy to output directory - cp busybox "$OUTPUT_DIR/busybox-s390x" - chmod +x "$OUTPUT_DIR/busybox-s390x" + # Copy to output directory with both naming conventions + cp busybox "$OUTPUT_DIR/busybox-s390x-static" + chmod +x "$OUTPUT_DIR/busybox-s390x-static" + + # Also create a native version link for compatibility + ln -sf busybox-s390x-static "$OUTPUT_DIR/busybox-s390x-native" echo "✅ s390x busybox binary built successfully!" echo "Size: $(du -h busybox | cut -f1)" diff --git a/scripts/build-initramfs-final.sh b/scripts/build-initramfs-final.sh index bc4cae5..70a03da 100755 --- a/scripts/build-initramfs-final.sh +++ b/scripts/build-initramfs-final.sh @@ -9,8 +9,7 @@ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" OUTPUT_DIR="$PROJECT_ROOT/output" INITRAMFS_NAME="initramfs-${KERNEL_VERSION}-s390x.img" MKINITCPIO_SOURCE="$PROJECT_ROOT/mkinitcpio-source" -MKINITCPIO_REPO="https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio.git" -MKINITCPIO_VERSION="v39.2" # Latest stable version +MKINITCPIO_REPO="https://github.com/archlinux/mkinitcpio.git" # Colors RED='\033[0;31m' @@ -20,15 +19,15 @@ NC='\033[0m' echo -e "${GREEN}=== Building initramfs with modified mkinitcpio ===${NC}" -# Clone mkinitcpio from upstream -echo -e "${YELLOW}Cloning mkinitcpio from upstream...${NC}" +# Clone mkinitcpio from upstream (latest version) +echo -e "${YELLOW}Cloning mkinitcpio from upstream (latest)...${NC}" rm -rf "$MKINITCPIO_SOURCE" -git clone --depth 1 --branch "$MKINITCPIO_VERSION" "$MKINITCPIO_REPO" "$MKINITCPIO_SOURCE" +git clone --depth 1 "$MKINITCPIO_REPO" "$MKINITCPIO_SOURCE" if [ $? -ne 0 ]; then echo -e "${RED}Failed to clone mkinitcpio${NC}" exit 1 fi -echo -e "${GREEN}✓ Cloned mkinitcpio ${MKINITCPIO_VERSION}${NC}" +echo -e "${GREEN}✓ Cloned latest mkinitcpio${NC}" # Create build script that runs inside container cat > "$PROJECT_ROOT/build-final-initramfs.sh" << 'EOF' @@ -41,101 +40,31 @@ INITRAMFS_OUTPUT="/work/output/initramfs-${KERNEL_VERSION}-s390x.img" echo "Building and installing modified mkinitcpio..." # Copy the mkinitcpio source -cp -r /work/mkinitcpio-source /tmp/mkinitcpio +mkdir -p /tmp/mkinitcpio +cp -r /work/mkinitcpio-source/* /tmp/mkinitcpio/ +cp -r /work/mkinitcpio-source/.[^.]* /tmp/mkinitcpio/ 2>/dev/null || true cd /tmp/mkinitcpio +# Verify we're in the right directory +if [ ! -f "meson.build" ]; then + echo "ERROR: meson.build not found. Directory contents:" + ls -la + exit 1 +fi + # Apply s390x patches echo "Applying s390x patches to mkinitcpio..." -cat > install/base << 'PATCH_EOF' -#!/usr/bin/env bash -# SPDX-License-Identifier: GPL-2.0-only -# Modified for s390x cross-architecture support -build() { - local applet - - # Use s390x busybox binary if available (cross-architecture support) - if [[ -f "/work/output/busybox-s390x-static" ]]; then - echo "Using s390x static busybox binary" - add_file "/work/output/busybox-s390x-static" "/bin/busybox" 755 - - # Create symlinks for busybox applets (using a known list since we can't execute cross-arch binary) - local busybox_applets=( - "[" "[[" "ash" "awk" "basename" "cat" "chgrp" "chmod" "chown" "cp" "cut" - "date" "dd" "df" "dirname" "dmesg" "du" "echo" "env" "expr" "false" - "find" "grep" "head" "hostname" "id" "kill" "ln" "ls" "mkdir" "mknod" - "mktemp" "mount" "mv" "printf" "ps" "pwd" "readlink" "rm" "rmdir" - "sed" "sh" "sleep" "sort" "stat" "tail" "tar" "test" "touch" "tr" - "true" "umount" "uname" "uniq" "wc" "which" "whoami" "xargs" - ) - - for applet in "${busybox_applets[@]}"; do - add_symlink "/usr/bin/$applet" busybox - done - elif [[ -f "/work/output/busybox-s390x-native" ]]; then - echo "Using s390x busybox binary" - add_file "/work/output/busybox-s390x-native" "/bin/busybox" 755 - - # Create symlinks for busybox applets (using a known list since we can't execute cross-arch binary) - local busybox_applets=( - "[" "[[" "ash" "awk" "basename" "cat" "chgrp" "chmod" "chown" "cp" "cut" - "date" "dd" "df" "dirname" "dmesg" "du" "echo" "env" "expr" "false" - "find" "grep" "head" "hostname" "id" "kill" "ln" "ls" "mkdir" "mknod" - "mktemp" "mount" "mv" "printf" "ps" "pwd" "readlink" "rm" "rmdir" - "sed" "sh" "sleep" "sort" "stat" "tail" "tar" "test" "touch" "tr" - "true" "umount" "uname" "uniq" "wc" "which" "whoami" "xargs" - ) - - for applet in "${busybox_applets[@]}"; do - add_symlink "/usr/bin/$applet" busybox - done - else - echo "Warning: s390x busybox not found, using system busybox (may cause architecture mismatch)" - add_binary /usr/lib/initcpio/busybox /bin/busybox - for applet in $(/usr/lib/initcpio/busybox --list 2>/dev/null || echo "sh ash"); do - add_symlink "/usr/bin/$applet" busybox - done - fi - - # Add kmod with applet symlinks (if available) - if type -P kmod >/dev/null 2>&1; then - echo "Adding kmod utilities..." - add_binary kmod - for applet in {dep,ins,rm,ls}mod mod{probe,info}; do - add_symlink "/usr/bin/$applet" kmod - done - else - echo "Warning: kmod not found, module utilities will not be available" - fi - - # Check for additional utilities (may not be available in cross-compile environment) - for binary in blkid mount umount switch_root; do - if type -P "$binary" >/dev/null 2>&1; then - echo "Adding $binary" - add_binary "$binary" - else - echo "Warning: $binary not found, skipping (functionality may be limited)" - fi - done - - # Always add init files - echo "Adding init files..." - add_file "/usr/lib/initcpio/init_functions" "/init_functions" - add_file "/usr/lib/initcpio/init" "/init" 755 -} - -help() { - cat < /etc/mkinitcpio-s390x.conf << 'CONFIG' -# Minimal s390x mkinitcpio configuration -# This config creates a basic initramfs without kernel modules -MODULES=() -BINARIES=() -FILES=() -# Only use base hook which provides busybox, init, and basic utilities -HOOKS=(base) -COMPRESSION="gzip" -COMPRESSION_OPTIONS=(-6) -CONFIG +# Copy mkinitcpio configuration +if [ -f "/work/patches/mkinitcpio-s390x.conf" ]; then + echo "Using s390x mkinitcpio configuration..." + cp /work/patches/mkinitcpio-s390x.conf /etc/mkinitcpio-s390x.conf +else + echo "ERROR: Configuration file not found at /work/patches/mkinitcpio-s390x.conf" + exit 1 +fi echo "Generating initramfs with mkinitcpio..." echo "Configuration:" @@ -226,6 +161,20 @@ cat /etc/mkinitcpio-s390x.conf # The s390x busybox integration is now handled by the patched base install hook echo "s390x busybox will be handled by the patched mkinitcpio base hook..." +# Ensure busybox binary is available for the base hook +if [ -f "/work/output/busybox-s390x-static" ]; then + echo "✓ Found s390x static busybox at /work/output/busybox-s390x-static" + ls -la /work/output/busybox-s390x-static +elif [ -f "/work/output/busybox-s390x-native" ]; then + echo "✓ Found s390x native busybox at /work/output/busybox-s390x-native" + ls -la /work/output/busybox-s390x-native +else + echo "ERROR: No s390x busybox binary found in /work/output/" + echo "Available files in /work/output:" + ls -la /work/output/ + exit 1 +fi + # Debug: List all files that mkinitcpio expects echo "Checking mkinitcpio dependencies:" ls -la /usr/lib/initcpio/ 2>/dev/null || echo "/usr/lib/initcpio/ not found" @@ -303,7 +252,7 @@ sudo podman run --rm \ -v "$PROJECT_ROOT:/work" \ -w /work \ --privileged \ - s390x-mkinitcpio-complete \ + s390x-archlinux-dev \ /work/build-final-initramfs.sh # Clean up copied source diff --git a/scripts/build-kernel-container.sh b/scripts/build-kernel-container.sh index 1f616bb..133db1e 100755 --- a/scripts/build-kernel-container.sh +++ b/scripts/build-kernel-container.sh @@ -79,6 +79,9 @@ CONFIG_VIRTIO_PCI=y CONFIG_TN3215=y CONFIG_TN3270=y +# System identity +CONFIG_DEFAULT_HOSTNAME="arch" + # Required for initramfs CONFIG_BLK_DEV_INITRD=y CONFIG_RD_GZIP=y