summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorDavid Cantrell <dcantrell@redhat.com>2008-07-17 14:58:00 -1000
committerDavid Cantrell <dcantrell@redhat.com>2008-07-17 14:59:00 -1000
commitdc8272f623924fa58056aaa6447356416ccc8788 (patch)
treedd9eaeda1557122fde377af15413808eb9903c2a /utils
parent2aa051b9d8a7846c93182f1d82abeee4d201a428 (diff)
downloadanaconda-dc8272f623924fa58056aaa6447356416ccc8788.tar.gz
anaconda-dc8272f623924fa58056aaa6447356416ccc8788.tar.xz
anaconda-dc8272f623924fa58056aaa6447356416ccc8788.zip
Support booting from FCP-attached CD/DVD drive on s390 (#184648)
The s390 can boot El Torito CD or DVD images iff they are attached by zFCP, used as the IPL device, and contain a specially formatted boot image on the disc. IBM provided the tool to combobulate the boot image together and a description of the desired execution path. When you boot on s390, the linuxrc.s390 will look to see if you IPL'ed from a CD or DVD. If you did, it will ask if you also want to install from that device. If you answer yes (y, Y, or any case spelling of 'yes'), the script will bring the IPL device online so the kernel assigns it a device name. Then it skips over the network configuration and starts you in to loader. If you tell it no or did not IPL from a CD or DVD, it'll launch the missiles--wait, no, I mean you get the normal network installation questions before loader starts. I have no way to test this as it requires the following changes: (1) Rel-eng needs to build s390x media with -no-emul-boot and specify the new cdboot.img file on that platform. I have already contacted rel-eng about making this change. (2) I don't have a CD-ROM drive in my mainframe. IBM does and testing is all falling on them. IBM knows this...maybe. I explain all of this like anyone else on the team will ever get a chance to experience it. So there you have it. A letter opener.
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile10
-rw-r--r--utils/mk-s390-cdboot.c156
2 files changed, 164 insertions, 2 deletions
diff --git a/utils/Makefile b/utils/Makefile
index 78acd770a..fcd6efc1e 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -31,10 +31,10 @@ RPMCFLAGS = $(CFLAGS) -I/usr/include/rpm
UTILS = modlist snarffont mapshdr readmap
ifeq (s390, $(ARCH))
-UTILS += geninitrdsz
+UTILS += geninitrdsz mk-s390-cdboot
endif
ifeq (s390x, $(ARCH))
-UTILS += geninitrdsz
+UTILS += geninitrdsz mk-s390-cdboot
endif
ifeq (.depend,$(wildcard .depend))
@@ -67,6 +67,9 @@ hash.o : hash.c
geninitrdsz: geninitrdsz.c
$(CC) $(CFLAGS) -o $@ $<
+mk-s390-cdboot: mk-s390-cdboot.c
+ $(CC) $(CFLAGS) -o $@ $<
+
depends:
install: all
@@ -80,6 +83,9 @@ install: all
if [ -x geninitrdsz ]; then \
install -m755 geninitrdsz $(DESTDIR)/$(RUNTIMEDIR) ; \
fi
+ if [ -x mk-s390-cdboot ]; then \
+ install -m755 mk-s390-cdboot $(DESTDIR)/$(RUNTIMEDIR) ; \
+ fi
clean:
rm -f modlist snarffont mapshdr readmap geninitrdsz \
diff --git a/utils/mk-s390-cdboot.c b/utils/mk-s390-cdboot.c
new file mode 100644
index 000000000..45e5cf845
--- /dev/null
+++ b/utils/mk-s390-cdboot.c
@@ -0,0 +1,156 @@
+/*
+ * mk-s390-cdboot -- creates one big image using a kernel, a ramdisk and
+ * a parmfile
+ *
+ *
+ * 2003-07-24 Volker Sameske <sameske@de.ibm.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>
+
+#define BUFFER_LEN 1024
+#define INITRD_START 0x0000000000800000LL
+#define START_PSW_ADDRESS 0x80010000
+#define PARAMETER_BUFFER_LEN 80
+
+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;
+ FILE *fd2;
+ FILE *fd3;
+ FILE *fd4;
+ char buffer[BUFFER_LEN];
+ int rc, oc, index;
+ unsigned long long initrd_start = INITRD_START;
+ unsigned long long initrd_size;
+ char image[PARAMETER_BUFFER_LEN];
+ char ramdisk[PARAMETER_BUFFER_LEN];
+ char parmfile[PARAMETER_BUFFER_LEN];
+ char outfile[PARAMETER_BUFFER_LEN];
+ 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':
+ strcpy(image, optarg);
+ image_specified = 1;
+ break;
+ case 'r':
+ strcpy(ramdisk, optarg);
+ ramdisk_specified = 1;
+ break;
+ case 'p':
+ strcpy(parmfile, optarg);
+ parmfile_specified = 1;
+ break;
+ case 'o':
+ strcpy(outfile, 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);
+
+ fd1 = fopen(outfile, "w");
+ fd2 = fopen(image, "r");
+ fd3 = fopen(ramdisk, "r");
+ fd4 = fopen(parmfile, "r");
+
+ printf("writing kernel...\n");
+ while (1) {
+ rc = fread(buffer, BUFFER_LEN, 1, fd2);
+ fwrite(buffer, BUFFER_LEN, 1, fd1);
+ if (rc == 0) break;
+ }
+
+ printf("writing initrd...\n");
+ fseek(fd1, initrd_start, SEEK_SET);
+ while (1) {
+ rc = fread(buffer, BUFFER_LEN, 1, fd3);
+ fwrite(buffer, BUFFER_LEN, 1, fd1);
+ if (rc == 0) break;
+ }
+
+ fseek(fd3, 0 ,SEEK_END);
+ initrd_size = ftell(fd3);
+
+ printf("changing start PSW address to 0x%08x...\n", start_psw_address);
+ fseek(fd1, 0x4, SEEK_SET);
+ fwrite(&start_psw_address, 4, 1, fd1);
+
+ printf("writing initrd address and size...\n");
+ printf("INITRD start: 0x%016llx\n", initrd_start);
+ printf("INITRD size : 0x%016llx\n", initrd_size);
+
+ fseek(fd1, 0x10408, SEEK_SET);
+ fwrite(&initrd_start, 8, 1, fd1);
+ fseek(fd1, 0x10410, SEEK_SET);
+ fwrite(&initrd_size, 8, 1, fd1);
+
+ printf("writing parmfile...\n");
+ fseek(fd1, 0x10480, SEEK_SET);
+ while (1) {
+ rc = fread(buffer, 1, 1, fd4);
+ fwrite(buffer, 1, 1, fd1);
+ if (rc == 0) break;
+ }
+
+ fclose(fd1);
+ fclose(fd2);
+ fclose(fd3);
+ fclose(fd4);
+ return 0;
+}