static void ipl_eckd_cdl(void) { XEckdMbr *mbr; Ipl2 *ipl2 = (void *)sec; IplVolumeLabel *vlbl = (void *)sec; block_number_t block_nr; /* we have just read the block #0 and recognized it as "IPL1" */ sclp_print("CDL\n"); memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(1, ipl2, "Cannot read IPL2 record at block 1"); IPL_assert(magic_match(ipl2, IPL2_MAGIC), "No IPL2 record"); mbr = &ipl2->u.x.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."); IPL_assert(mbr->dev_type == DEV_TYPE_ECKD, "Non-ECKD device type in zIPL section of IPL2 record."); /* save pointer to Boot Script */ 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"); IPL_assert(magic_match(vlbl->key, VOL1_MAGIC), "Invalid magic of volume label block"); IPL_assert(magic_match(vlbl->f.key, VOL1_MAGIC), "Invalid magic of volser block"); print_volser(vlbl->f.volser); run_eckd_boot_script(block_nr); /* no return */ }
static struct trigger * trigger_set_magic(int proto, int num, u_char *buf, int len) { struct trigger *t, tr; char *name; if ((name = magic_match(buf, len)) == NULL) return (NULL); t = NULL; tr.num = num; if (proto == IPPROTO_UDP) { trigger_set_udp(num, name); if (strcmp(name, "portmap") == 0 || /* XXX - hack */ strcmp(name, "mountd") == 0 || strcmp(name, "yppasswd") == 0) { trigger_set_udp(0 - num, name); } t = (struct trigger *) bsearch(&tr, &udp_triggers, udp_cnt, sizeof(tr), trigger_compare); } else if (proto == IPPROTO_TCP) { trigger_set_tcp(num, name); if (strcmp(name, "portmap") == 0 || /* XXX - hack */ strcmp(name, "mountd") == 0 || strcmp(name, "yppasswd") == 0) { trigger_set_tcp(0 - num, name); } t = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt, sizeof(tr), trigger_compare); } return (t); }
/* Run a zipl program */ static void zipl_run(ScsiBlockPtr *pte) { ComponentHeader *header; ComponentEntry *entry; uint8_t tmp_sec[MAX_SECTOR_SIZE]; read_block(pte->blockno, tmp_sec, "Cannot read header"); header = (ComponentHeader *)tmp_sec; IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic"); IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type"); dputs("start loading images\n"); /* Load image(s) into RAM */ entry = (ComponentEntry *)(&header[1]); while (entry->component_type == ZIPL_COMP_ENTRY_LOAD) { zipl_load_segment(entry); entry++; IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE), "Wrong entry value"); } IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry"); /* should not return */ jump_to_IPL_code(entry->load_address); }
static sym_class_t elf_class(FILE *fp) { unsigned char e_ident[EI_NIDENT]; if (fseek(fp, 0, SEEK_SET) != 0) { return (SYM_CLASS_INVALID); } if (fread(e_ident, EI_NIDENT, 1, fp) != 1) { return (SYM_CLASS_INVALID); } if (!magic_match(e_ident)) { return (SYM_CLASS_INVALID); } switch (e_ident[EI_CLASS]) { case ELFCLASS32: return (SYM_CLASS_ELF32); case ELFCLASS64: return (SYM_CLASS_ELF64); default: break; } return (SYM_CLASS_INVALID); }
static inline void verify_boot_info(BootInfo *bip) { IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL magic"); IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version"); IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL"); IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD"); IPL_assert(bip->flags == BOOT_INFO_FLAGS_ARCH, "Not for this arch"); IPL_assert(block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size), "Bad block size in zIPL section of the 1st record."); }
void zipl_load(void) { ScsiMbr *mbr = (void *)sec; LDL_VTOC *vlbl = (void *)sec; /* Grab the MBR */ memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(0, mbr, "Cannot read block 0"); dputs("checking magic\n"); if (magic_match(mbr->magic, ZIPL_MAGIC)) { ipl_scsi(); /* no return */ } /* We have failed to follow the SCSI scheme, so */ sclp_print("Using ECKD scheme.\n"); if (virtio_guessed_disk_nature()) { sclp_print("Using guessed DASD geometry.\n"); virtio_assume_eckd(); } if (magic_match(mbr->magic, IPL1_MAGIC)) { ipl_eckd(ECKD_CDL); /* no return */ } /* LDL/CMS? */ memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(2, vlbl, "Cannot read block 2"); if (magic_match(vlbl->magic, CMS1_MAGIC)) { ipl_eckd(ECKD_CMS); /* no return */ } if (magic_match(vlbl->magic, LNX1_MAGIC)) { ipl_eckd(ECKD_LDL); /* no return */ } virtio_panic("\n* invalid MBR magic *\n"); }
const char* mime_cache_lookup_magic( MimeCache* cache, const char* data, int len ) { const char* magic = cache->magics; int i; if( G_UNLIKELY( ! data || (0 == len) || ! magic ) ) return NULL; for( i = 0; i < cache->n_magics; ++i, magic += 16 ) { if( magic_match( cache->buffer, magic, data, len ) ) { return cache->buffer + VAL32( magic, 4 ); } } return NULL; }
static void ipl_scsi(void) { ScsiMbr *mbr = (void *)sec; uint8_t *ns, *ns_end; int program_table_entries = 0; const int pte_len = sizeof(ScsiBlockPtr); ScsiBlockPtr *prog_table_entry; /* The 0-th block (MBR) was already read into sec[] */ sclp_print("Using SCSI scheme.\n"); debug_print_int("program table", mbr->blockptr.blockno); /* Parse the program table */ read_block(mbr->blockptr.blockno, sec, "Error reading Program Table"); IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic"); ns_end = sec + virtio_get_block_size(); for (ns = (sec + pte_len); (ns + pte_len) < ns_end; ns++) { prog_table_entry = (ScsiBlockPtr *)ns; if (!prog_table_entry->blockno) { break; } program_table_entries++; } debug_print_int("program table entries", program_table_entries); IPL_assert(program_table_entries != 0, "Empty Program Table"); /* Run the default entry */ prog_table_entry = (ScsiBlockPtr *)(sec + pte_len); zipl_run(prog_table_entry); /* no return */ }
int __attribute__((noreturn)) yflash(uint32_t blk_offs, unsigned int blk_size, const struct magic * magic) { struct { struct magic_hdr hdr; struct magic_rec rec[MAGIC_REC_MAX]; } magic_buf; struct ymodem_rcv ry; unsigned int cnt; uint32_t offs; int ret; int i; if (magic != 0) { /* copy magic check block */ cnt = magic->hdr.cnt > MAGIC_REC_MAX ? MAGIC_REC_MAX : magic->hdr.cnt; for (i = 0; i < cnt; ++i) { // usb_send(CDC_TX_EP, "\r\nmagic.", 8); magic_buf.rec[i] = magic->rec[i]; } magic_buf.hdr.cnt = cnt; magic_buf.hdr.pos = magic->hdr.pos; } else { magic_buf.hdr.cnt = 0; magic_buf.hdr.pos = 0; } DCC_LOG(LOG_TRACE, "flash_unlock()"); LOG_CODE(0); LOG_STATE(0); #if 0 if (opt & XFLASH_OPT_BYPASS) { PUTS(s_ok); usb_drain(CDC_TX_EP); return 55; } #endif do { PUTS(s_ymodem); ymodem_rcv_init(&ry); ry.fsize = blk_size; offs = blk_offs; cnt = 0; flash_unlock(); while ((ret = usb_ymodem_rcv_pkt(&ry)) >= 0) { DCC_LOG1(LOG_TRACE, "usb_ymodem_rcv_pkt() ret=%d)", ret); #if XMODEM_FALLBACK if ((ret == 0) && (ry.xmodem)) { LOG_CODE(1); break; } #endif int len = ret; if (ry.pktno == 1) { char * cp; int fsize; cp = (char *)ry.pkt.data; while (*cp != '\0') cp++; cp++; /* skip null */ fsize = dec2int(cp); if (fsize == 0) { LOG_CODE(2); break; } ry.fsize = fsize; } else { if (ry.pktno == 2) { if (!magic_match((struct magic *)&magic_buf, cnt, ry.pkt.data, len)) { DCC_LOG(LOG_WARNING, "invalid file magic!"); #if XFLASH_VERBOSE usb_ymodem_rcv_cancel(&ry); delay(1000); PUTS(s_invalid); #endif LOG_CODE(3); ret = -3; break; } // flash_erase(offs, ry->fsize); } DCC_LOG2(LOG_TRACE, "flash_erase(offs=0x%06x, len=%d)", offs, len); if ((ret = flash_erase(offs, len)) < 0) { DCC_LOG(LOG_WARNING, "flash_erase() failed!"); #if XFLASH_VERBOSE usb_ymodem_rcv_cancel(&ry); delay(1000); PUTS(s_erase); #endif LOG_CODE(4 + (-ret * 0x10000)); ret = -4; break; } DCC_LOG(LOG_TRACE, "flash_write()"); if ((ret = flash_write(offs, ry.pkt.data, len)) < 0) { DCC_LOG(LOG_WARNING, "flash_write() failed!"); #if XFLASH_VERBOSE usb_ymodem_rcv_cancel(&ry); delay(1000); PUTS(s_program); #endif LOG_CODE(5); ret = -5; break; } offs += len; cnt += len; LOG_STATE(cnt); } } // if (opt & XFLASH_OPT_RET_ERR) { // return ret; // } } while ((ret < 0) || (cnt == 0)); PUTS(s_ok); usb_drain(CDC_TX_EP); // if (opt & XFLASH_OPT_RESET) { delay(3000); reset(); // } // return 0; }