@@ -221,9 +221,9 @@ static void run_eckd_boot_script(block_number_t mbr_block_nr)
static void ipl_eckd_cdl(void)
{
XEckdMbr *mbr;
- Ipl2 *ipl2 = (void *)sec;
+ EckdCdlIpl2 *ipl2 = (void *)sec;
IplVolumeLabel *vlbl = (void *)sec;
- block_number_t block_nr;
+ block_number_t mbr_block_nr;
/* we have just read the block #0 and recognized it as "IPL1" */
sclp_print("CDL\n");
@@ -231,7 +231,7 @@ static void ipl_eckd_cdl(void)
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
read_block(1, ipl2, "Cannot read IPL2 record at block 1");
- mbr = &ipl2->u.x.mbr;
+ mbr = &ipl2->mbr;
IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record.");
IPL_assert(block_size_ok(mbr->blockptr.xeckd.bptr.size),
"Bad block size in zIPL section of IPL2 record.");
@@ -239,7 +239,7 @@ static void ipl_eckd_cdl(void)
"Non-ECKD device type in zIPL section of IPL2 record.");
/* save pointer to Boot Script */
- block_nr = eckd_block_num((void *)&(mbr->blockptr));
+ mbr_block_nr = eckd_block_num((void *)&(mbr->blockptr));
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
read_block(2, vlbl, "Cannot read Volume Label at block 2");
@@ -249,7 +249,7 @@ static void ipl_eckd_cdl(void)
"Invalid magic of volser block");
print_volser(vlbl->f.volser);
- run_eckd_boot_script(block_nr);
+ run_eckd_boot_script(mbr_block_nr);
/* no return */
}
@@ -280,8 +280,8 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
{
- block_number_t block_nr;
- BootInfo *bip = (void *)(sec + 0x70); /* BootInfo is MBR for LDL */
+ block_number_t mbr_block_nr;
+ EckdLdlIpl1 *ipl1 = (void *)sec;
if (mode != ECKD_LDL_UNLABELED) {
print_eckd_ldl_msg(mode);
@@ -292,15 +292,17 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
read_block(0, sec, "Cannot read block 0 to grab boot info.");
if (mode == ECKD_LDL_UNLABELED) {
- if (!magic_match(bip->magic, ZIPL_MAGIC)) {
+ if (!magic_match(ipl1->boot_info.magic, ZIPL_MAGIC)) {
return; /* not applicable layout */
}
sclp_print("unlabeled LDL.\n");
}
- verify_boot_info(bip);
+ verify_boot_info(&ipl1->boot_info);
+
+ mbr_block_nr =
+ eckd_block_num((void *)&(ipl1->boot_info.bp.ipl.bm_ptr.eckd.bptr));
- block_nr = eckd_block_num((void *)&(bip->bp.ipl.bm_ptr.eckd.bptr));
- run_eckd_boot_script(block_nr);
+ run_eckd_boot_script(mbr_block_nr);
/* no return */
}
@@ -226,22 +226,47 @@ typedef struct BootInfo { /* @ 0x70, record #0 */
} bp;
} __attribute__ ((packed)) BootInfo; /* see also XEckdMbr */
-typedef struct Ipl1 {
- unsigned char key[4]; /* == "IPL1" */
- unsigned char data[24];
-} __attribute__((packed)) Ipl1;
+/*
+ * Structs for IPL
+ */
+#define STAGE2_BLK_CNT_MAX 24 /* Stage 1b can load up to 24 blocks */
-typedef struct Ipl2 {
- unsigned char key[4]; /* == "IPL2" */
- union {
- unsigned char data[144];
- struct {
- unsigned char reserved1[92-4];
- XEckdMbr mbr;
- unsigned char reserved2[144-(92-4)-sizeof(XEckdMbr)];
- } x;
- } u;
-} __attribute__((packed)) Ipl2;
+typedef struct EckdCdlIpl1 {
+ uint8_t key[4]; /* == "IPL1" */
+ uint8_t data[24];
+} __attribute__((packed)) EckdCdlIpl1;
+
+typedef struct BootEckdSeekarg {
+ uint16_t pad;
+ uint16_t cyl;
+ uint16_t head;
+ uint8_t sec;
+ uint8_t pad2;
+} __attribute__ ((packed)) BootEckdSeekarg;
+
+typedef struct BootEckdStage1b {
+ uint8_t reserved[32 * STAGE2_BLK_CNT_MAX];
+ struct BootEckdSeekarg seek[STAGE2_BLK_CNT_MAX];
+ uint8_t unused[64];
+} __attribute__ ((packed)) BootEckdStage1b;
+
+typedef struct BootEckdStage1 {
+ uint8_t reserved[72];
+ struct BootEckdSeekarg seek[2];
+} __attribute__ ((packed)) BootEckdStage1;
+
+typedef struct EckdCdlIpl2 {
+ uint8_t key[4]; /* == "IPL2" */
+ struct BootEckdStage1 stage1;
+ XEckdMbr mbr;
+ uint8_t reserved2[24];
+} __attribute__((packed)) EckdCdlIpl2;
+
+typedef struct EckdLdlIpl1 {
+ uint8_t reserved[24];
+ struct BootEckdStage1 stage1;
+ BootInfo boot_info; /* BootInfo is MBR for LDL */
+} __attribute__((packed)) EckdLdlIpl1;
typedef struct IplVolumeLabel {
unsigned char key[4]; /* == "VOL1" */