diff --git a/main/s390-tools/APKBUILD b/main/s390-tools/APKBUILD
index fea27e9081cddf04799d055d1e5bcd1847dc93de..ae71844dfa1bfb9c9086d8accffea1754e717c6c 100644
--- a/main/s390-tools/APKBUILD
+++ b/main/s390-tools/APKBUILD
@@ -2,7 +2,7 @@
 # Maintainer: Tuan M. Hoang <tmhoang@flatglobe.org>
 pkgname=s390-tools
 pkgver=1.37.0
-pkgrel=3
+pkgrel=4
 pkgdesc="Utilities for Linux on IBM z Systems"
 url="http://www.ibm.com/developerworks/linux/linux390/s390-tools.html"
 arch="s390x"
@@ -29,6 +29,8 @@ source="http://download.boulder.ibm.com/ibmdl/pub/software/dw/linux390/ht_src/$p
 
 	0200-dasdinfo-gnu-ext-hack.patch
 	0300-disable-program-using-gnu-ext.patch
+
+	mk-s390-cdboot.c
 	"
 builddir="$srcdir/$pkgname-$pkgver"
 
@@ -38,11 +40,13 @@ build() {
 		HAVE_SNMP=0 \
 		HAVE_PFM=0 \
 		LIBEXECINFO_LIBS="-lexecinfo"
+	gcc -Wall -o mk-s390-cdboot "$srcdir"/mk-s390-cdboot.c
 }
 
 package() {
 	cd "$builddir"
 	make HAVE_SNMP=0 HAVE_PFM=0 DESTDIR="$pkgdir" install
+	install -Dm755 mk-s390-cdboot "$pkgdir"/sbin/mk-s390-cdboot
 }
 
 sha512sums="3667ba4eb7e2b74629958f530002953adebe6e41d6429c99ae5f82d1406d6963aacdc35b63114683c365b9fa40ac32b4c22f226918ecb53423e80f944d24cb9c  s390-tools-1.37.0.tar.bz2
@@ -59,4 +63,5 @@ d4d707aadf095f48dd3ae79f60d17194e479d8a6ca08c6b6d64582e6d09b33d7d065a7349cc7fe61
 d879173250fc0cabef198785923248e6832158e38d6ea9ef615f14e2d6698810b54c38c8327f20b2c43d8d509a274b27a7c0ad999a0c0bed2743715f21ab859a  0100-zipl-no-pie.patch
 1cbbe3fe265c7d4164143d24c532c18b354be4bc295ad24064d379660e43a475b7d678b458cdf74ffdb44d6cd38a497dbe00758d688c547c6ece63b6dee091b7  0101-zipl-dont-optimize-size.patch
 4ce15b615ff08e5c0a23d3c3b19d1e9d6362239fb731e67fa68e6cd108cfdeaaf16186c5416cc211082aa60c4d1946b930b9ea4c300458da98e9a701feed99c3  0200-dasdinfo-gnu-ext-hack.patch
-6736ca9deb25838511e715e96d1f5bfc283460689e767181463d1827c80be200b1375708ff48772599083b14f74594f7053cf30fcc6c93ba7fa5dfae832434de  0300-disable-program-using-gnu-ext.patch"
+6736ca9deb25838511e715e96d1f5bfc283460689e767181463d1827c80be200b1375708ff48772599083b14f74594f7053cf30fcc6c93ba7fa5dfae832434de  0300-disable-program-using-gnu-ext.patch
+349eb06895016d16194819c4a04f604720f1373ea61a9bc4c58467281c9a2ed3539bd4e8b6984f4e5177630dbe8b928aa95912c9a3e3b0e1fe275d59f9fe573d  mk-s390-cdboot.c"
diff --git a/main/s390-tools/mk-s390-cdboot.c b/main/s390-tools/mk-s390-cdboot.c
new file mode 100644
index 0000000000000000000000000000000000000000..4a5825853ad91074eab76ff9d0272b0f38801cad
--- /dev/null
+++ b/main/s390-tools/mk-s390-cdboot.c
@@ -0,0 +1,284 @@
+/*
+ * mk-s390-cdboot -- creates one big image using a kernel, a ramdisk and
+ *                   a parmfile
+ *
+ * 2003-07-24 Volker Sameske <sameske@de.ibm.com>
+ * 2008-09-22 Updated by David Cantrell <dcantrell@redhat.com>
+ *
+ * compile with:
+ *     gcc -Wall -o mk-s390-cdboot mk-s390-cdboot.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <libgen.h>
+
+#define BUFFER_LEN 1024
+#define INITRD_START 0x0000000000800000LL
+#define START_PSW_ADDRESS 0x80010000
+
+static struct option getopt_long_options[]= {
+    { "image", 1, 0, 'i'},
+    { "ramdisk", 1, 0, 'r'},
+    { "parmfile", 1, 0, 'p'},
+    { "outfile", 1, 0, 'o'},
+    { "help", 0, 0, 'h'},
+    {0, 0, 0, 0}
+};
+
+static void usage(char *cmd) {
+    printf("%s [-h] [-v] -i <kernel> -r <ramdisk> -p <parmfile> -o <outfile>\n", cmd);
+}
+
+int main (int argc, char **argv) {
+    char *cmd = basename(argv[0]);
+    FILE *fd1 = NULL;
+    FILE *fd2 = NULL;
+    FILE *fd3 = NULL;
+    FILE *fd4 = NULL;
+    char buffer[BUFFER_LEN];
+    int wc, rc, oc, index;
+    unsigned long long initrd_start = INITRD_START;
+    unsigned long long initrd_size;
+    char *image = NULL;
+    char *ramdisk = NULL;
+    char *parmfile = NULL;
+    char *outfile = NULL;
+    int image_specified = 0;
+    int ramdisk_specified = 0;
+    int parmfile_specified = 0;
+    int outfile_specified = 0;
+    int start_psw_address = START_PSW_ADDRESS;
+
+    opterr = 0;
+    while (1) {
+        oc = getopt_long(argc, argv, "i:r:p:o:h?", getopt_long_options, &index);
+        if (oc == -1) {
+            break;
+        }
+
+        switch (oc) {
+            case '?':
+            case 'h':
+                usage(cmd);
+                exit(0);
+            case 'i':
+                image = strdup(optarg);
+                image_specified = 1;
+                break;
+            case 'r':
+                ramdisk = strdup(optarg);
+                ramdisk_specified = 1;
+                break;
+            case 'p':
+                parmfile = strdup(optarg);
+                parmfile_specified = 1;
+                break;
+            case 'o':
+                outfile = strdup(optarg);
+                outfile_specified = 1;
+                break;
+            default:
+                usage(cmd);
+                exit(0);
+        }
+    }
+
+    if (!image_specified || !ramdisk_specified ||
+        !parmfile_specified || !outfile_specified) {
+        usage(cmd);
+        exit(0);
+    }
+
+    printf("Creating bootable CD-ROM image...\n");
+    printf("kernel is  : %s\n", image);
+    printf("ramdisk is : %s\n", ramdisk);
+    printf("parmfile is: %s\n", parmfile);
+    printf("outfile is : %s\n", outfile);
+
+    if ((fd1 = fopen(outfile, "w")) == NULL) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if ((fd2 = fopen(image, "r")) == NULL) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if ((fd3 = fopen(ramdisk, "r")) == NULL) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if ((fd4 = fopen(parmfile, "r")) == NULL) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    printf("writing kernel...\n");
+    while (1) {
+        rc = fread(buffer, 1, 1, fd2);
+
+        if (rc == 0) {
+            break;
+        }
+
+        if (feof(fd2) || ferror(fd2)) {
+            fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+            abort();
+        }
+
+        wc = fwrite(buffer, 1, 1, fd1);
+        if (feof(fd1) || ferror(fd1)) {
+            fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+            abort();
+        }
+
+        if (wc != rc) {
+          fprintf(stderr, "could only write %i of %i bytes of kernel\n",
+                  wc, rc);
+        }
+    }
+
+    printf("writing initrd...\n");
+    fseek(fd1, initrd_start, SEEK_SET);
+    while (1) {
+        rc = fread(buffer, 1, 1, fd3);
+
+        if (rc == 0) {
+            break;
+        }
+
+        if (feof(fd3) || ferror(fd3)) {
+            fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+            abort();
+        }
+
+        wc = fwrite(buffer, 1, 1, fd1);
+        if (feof(fd1) || ferror(fd1)) {
+            fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+            abort();
+        }
+
+        if (wc != rc) {
+          fprintf(stderr, "could only write %i of %i bytes of initrd\n",
+                  wc, rc);
+        }
+    }
+
+    if (fseek(fd3, 0, SEEK_END) == -1) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if ((initrd_size = ftell(fd3)) == -1) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    printf("changing start PSW address to 0x%08x...\n", start_psw_address);
+    if (fseek(fd1, 0x4, SEEK_SET) == -1) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    wc = fwrite(&start_psw_address, 1, 4, fd1);
+    if (feof(fd1) || ferror(fd1)) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if (wc != 4) {
+        fprintf(stderr, "could only write %i of %i bytes of PSW address\n",
+                wc, 4);
+    }
+
+    printf("writing initrd address and size...\n");
+    printf("INITRD start: 0x%016llx\n",  initrd_start);
+    printf("INITRD size : 0x%016llx\n", initrd_size);
+
+    if (fseek(fd1, 0x10408, SEEK_SET) == -1) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    wc = fwrite(&initrd_start, 1, 8, fd1);
+    if (feof(fd1) || ferror(fd1)) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if (wc != 8) {
+        fprintf(stderr, "could only write %i of %i bytes of INITRD start\n",
+                wc, 8);
+    }
+
+    if (fseek(fd1, 0x10410, SEEK_SET) == -1) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    wc = fwrite(&initrd_size, 1, 8, fd1);
+    if (feof(fd1) || ferror(fd1)) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    if (wc != 8) {
+        fprintf(stderr, "could only write %i of %i bytes of INITRD size\n",
+                wc, 8);
+    }
+
+    printf("writing parmfile...\n");
+    if (fseek(fd1, 0x10480, SEEK_SET) == -1) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+        abort();
+    }
+
+    while (1) {
+        rc = fread(buffer, 1, 1, fd4);
+
+        if (rc == 0) {
+            break;
+        }
+
+        if (feof(fd4) || ferror(fd4)) {
+            fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+            abort();
+        }
+
+        wc = fwrite(buffer, 1, 1, fd1);
+        if (feof(fd1) || ferror(fd1)) {
+            fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+            abort();
+        }
+
+        if (wc != 1) {
+            fprintf(stderr, "could only write %i of %i bytes of parmfile\n",
+                    wc, 1);
+        }
+    }
+
+    if (fclose(fd1) == EOF) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+    }
+
+    if (fclose(fd2) == EOF) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+    }
+
+    if (fclose(fd3) == EOF) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+    }
+
+    if (fclose(fd4) == EOF) {
+        fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno));
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/scripts/mkimg.base.sh b/scripts/mkimg.base.sh
index 3ba6bfd04bb9963c5ba8ce1d9673d8a54f7f32b5..6dfd9db8a9864e28769c1f607b35e0b90389ec48 100755
--- a/scripts/mkimg.base.sh
+++ b/scripts/mkimg.base.sh
@@ -257,6 +257,16 @@ create_image_iso() {
 			-sysid LINUX \
 			-volid "alpine-${profile_abbrev:-$PROFILE} $RELEASE $ARCH"
 	else
+		if [ "$ARCH" = s390x ]; then
+			printf %s "$initfs_cmdline $kernel_cmdline " > ${WORKDIR}/parmfile
+			for _f in $kernel_flavors; do
+				mk-s390-cdboot -p ${WORKDIR}/parmfile \
+					-i ${DESTDIR}/boot/vmlinuz-$_f \
+					-r ${DESTDIR}/boot/initramfs-$_f \
+					-o ${DESTDIR}/boot/merged.img
+			done
+			iso_opts="$iso_opts -no-emul-boot -eltorito-boot boot/merged.img"
+		fi
 		xorrisofs \
 			-quiet \
 			-output ${ISO} \