Example #1
0
/* pi_gpt_ctor() - GPT iterator specific initialization */
static int pi_gpt_ctor(struct part_iter *iter,
	const struct disk_info *di, int flags,
	const struct disk_gpt_header *gpth, const struct disk_gpt_part_entry *gptl
)
{
    uint64_t siz;

    if (pi_ctor(iter, di, flags))
	return -1;

    siz = (uint64_t)gpth->part_count * gpth->part_size;

    if (!(iter->data = malloc((size_t)siz))) {
	critm();
	goto bail;
    }

    memcpy(iter->data, gptl, (size_t)siz);

    iter->gpt.pe_count = (int)gpth->part_count;
    iter->gpt.pe_size = (int)gpth->part_size;
    iter->gpt.ufirst = gpth->lba_first_usable;
    iter->gpt.ulast = gpth->lba_last_usable;

    memcpy(&iter->gpt.disk_guid, &gpth->disk_guid, sizeof gpth->disk_guid);
    memcpy(&iter->gpt.part_guid, &gpth->disk_guid, sizeof gpth->disk_guid);

    iter->type = typegpt;
    return 0;
bail:
    pi_dtor_(iter);
    return -1;
}
Example #2
0
static struct part_iter *pi_alloc(void)
{
    struct part_iter *iter;
    if (!(iter = malloc(sizeof *iter)))
	critm();
    else
	memset(iter, 0, sizeof *iter);
    return iter;
}
Example #3
0
/* pi_dos_ctor() - MBR/EBR iterator specific initialization */
static int pi_dos_ctor(struct part_iter *iter,
	const struct disk_info *di, int flags,
	const struct disk_dos_mbr *mbr
)
{
    if (pi_ctor(iter, di, flags))
	return -1;

    if (!(iter->data = malloc(sizeof *mbr))) {
	critm();
	goto bail;
    }

    memcpy(iter->data, mbr, sizeof *mbr);

    iter->dos.bebr_index0 = -1;
    iter->dos.disk_sig = mbr->disk_sig;

    iter->type = typedos;
    return 0;
bail:
    pi_dtor_(iter);
    return -1;
}
Example #4
0
int main(int argc, char *argv[])
{
    struct part_iter *iter = NULL;
    void *sbck = NULL;
    struct data_area fdat, hdat, sdat, data[3];
    int ndata = 0;

    console_ansi_raw();

    memset(&fdat, 0, sizeof fdat);
    memset(&hdat, 0, sizeof hdat);
    memset(&sdat, 0, sizeof sdat);

    opt_set_defs();
    if (opt_parse_args(argc, argv))
	goto bail;

#if 0
    /* Get max fixed disk number */
    fixed_cnt = *(uint8_t *)(0x475);

    /*
     * hmm, looks like we can't do that -
     * some bioses/vms just set it to 1
     * and go on living happily
     * any better options than hardcoded 0x80 - 0xFF ?
     */
#endif

    /* Get disk/part iterator matching user supplied options */
    if (find_dp(&iter))
	goto bail;

    /* Perform initial partition entry mangling */
    if (manglepe_fixchs(iter))
	goto bail;
    if (manglepe_hide(iter))
	goto bail;

    /* Load the boot file */
    if (opt.file) {
	fdat.base = (opt.fseg << 4) + opt.foff;

	if (loadfile(opt.file, &fdat.data, &fdat.size)) {
	    error("Couldn't read the boot file.");
	    goto bail;
	}
	if (fdat.base + fdat.size > dosmax) {
	    error("The boot file is too big to load at this address.");
	    goto bail;
	}
    }

    /* Load the sector */
    if (opt.sect) {
	sdat.base = (opt.sseg << 4) + opt.soff;
	sdat.size = iter->di.bps;

	if (sdat.base + sdat.size > dosmax) {
	    error("The sector cannot be loaded at such high address.");
	    goto bail;
	}
	if (!(sdat.data = disk_read_sectors(&iter->di, iter->abs_lba, 1))) {
	    error("Couldn't read the sector.");
	    goto bail;
	}
	if (opt.save) {
	    if (!(sbck = malloc(sdat.size))) {
		critm();
		goto bail;
	    }
	    memcpy(sbck, sdat.data, sdat.size);
	}
	if (opt.file && opt.maps && overlap(&fdat, &sdat)) {
	    warn("The sector won't be mmapped, as it would conflict with the boot file.");
	    opt.maps = false;
	}
    }

    /* Prep the handover */
    if (opt.hand) {
	if (setup_handover(iter, &hdat))
	    goto bail;
	/* Verify possible conflicts */
	if ( ( opt.file && overlap(&fdat, &hdat)) ||
	     ( opt.maps && overlap(&sdat, &hdat)) ) {
	    warn("Handover area won't be prepared,\n"
		  "as it would conflict with the boot file and/or the sector.");
	    opt.hand = false;
	}
    }

    /* Adjust registers */

    mangler_init(iter);
    mangler_handover(iter, &hdat);
    mangler_grldr(iter);

    /* Patching functions */

    if (manglef_isolinux(&fdat))
	goto bail;

    if (manglef_grub(iter, &fdat))
	goto bail;
#if 0
    if (manglef_drmk(&fdat))
	goto bail;
#endif
    if (manglef_bpb(iter, &fdat))
	goto bail;

    if (mangles_bpb(iter, &sdat))
	goto bail;

    if (mangles_save(iter, &sdat, sbck))
	goto bail;

    if (manglesf_bss(&sdat, &fdat))
	goto bail;

    /* This *must* be after BPB saving or copying */
    if (mangles_cmldr(&sdat))
	goto bail;

    /*
     * Prepare boot-time mmap data. We should to it here, as manglers could
     * potentially alter some of the data.
     */

    if (opt.file)
	memcpy(data + ndata++, &fdat, sizeof fdat);
    if (opt.maps)
	memcpy(data + ndata++, &sdat, sizeof sdat);
    if (opt.hand)
	memcpy(data + ndata++, &hdat, sizeof hdat);

#ifdef DEBUG
    dprintf("iter->di dsk, bps: %X, %u\niter->di lbacnt, C*H*S: %"PRIu64", %u\n"
	   "iter->di C, H, S: %u, %u, %u\n",
	iter->di.disk, iter->di.bps,
	iter->di.lbacnt, iter->di.cyl * iter->di.head * iter->di.spt,
	iter->di.cyl, iter->di.head, iter->di.spt);
    dprintf("iter idx: %d\n", iter->index);
    dprintf("iter lba: %"PRIu64"\n", iter->abs_lba);
    if (opt.hand)
	dprintf("hand lba: %u\n",
		((struct disk_dos_part_entry *)hdat.data)->start_lba);
#endif

    if (opt.warn) {
	puts("Press any key to continue booting...");
	wait_key();
    }

    if (ndata && !opt.brkchain) /* boot only if we actually chainload */
	do_boot(data, ndata);
    else
	puts("Service-only run completed, exiting.");
bail:
    pi_del(&iter);
    /* Free allocated areas */
    free(fdat.data);
    free(sdat.data);
    free(hdat.data);
    free(sbck);
    return 255;
}
Example #5
0
static int setup_handover(const struct part_iter *iter,
		   struct data_area *data)
{
    struct disk_dos_part_entry *ha;
    uint32_t synth_size = sizeof *ha;

    /*
     * we have to cover both non-iterated but otherwise properly detected
     * gpt/dos schemes as well as raw disks; checking index for 0 covers both
     */
    if (iter->index == 0) {
	uint32_t len;
	/* RAW handover protocol */
	ha = malloc(synth_size);
	if (!ha) {
	    critm();
	    goto bail;
	}
	len = ~0u;
	if (iter->length < len)
	    len = iter->length;
	lba2chs(&ha->start, &iter->di, 0, L2C_CADD);
	lba2chs(&ha->end, &iter->di, len - 1, L2C_CADD);
	ha->active_flag = 0x80;
	ha->ostype = 0xDA;	/* "Non-FS Data", anything is good here though ... */
	ha->start_lba = 0;
	ha->length = len;
    } else if (iter->type == typegpt) {
	uint32_t *plen;
	/* GPT handover protocol */
	synth_size += sizeof *plen + iter->gpt.pe_size;
	ha = malloc(synth_size);
	if (!ha) {
	    critm();
	    goto bail;
	}
	lba2chs(&ha->start, &iter->di, iter->abs_lba, L2C_CADD);
	lba2chs(&ha->end, &iter->di, iter->abs_lba + iter->length - 1, L2C_CADD);
	ha->active_flag = 0x80;
	ha->ostype = 0xED;
	/* All bits set by default */
	ha->start_lba = ~0u;
	ha->length = ~0u;
	/* If these fit the precision, pass them on */
	if (iter->abs_lba < ha->start_lba)
	    ha->start_lba = iter->abs_lba;
	if (iter->length < ha->length)
	    ha->length = iter->length;
	/* Next comes the GPT partition record length */
	plen = (uint32_t *)(ha + 1);
	plen[0] = iter->gpt.pe_size;
	/* Next comes the GPT partition record copy */
	memcpy(plen + 1, iter->record, plen[0]);
#ifdef DEBUG
	dprintf("GPT handover:\n");
	disk_dos_part_dump(ha);
	disk_gpt_part_dump((struct disk_gpt_part_entry *)(plen + 1));
#endif
    /* the only possible case left is dos scheme */
    } else if (iter->type == typedos) {
	/* MBR handover protocol */
	ha = malloc(synth_size);
	if (!ha) {
	    critm();
	    goto bail;
	}
	memcpy(ha, iter->record, synth_size);
	/* make sure these match bios imaginations and are ebr agnostic */
	lba2chs(&ha->start, &iter->di, iter->abs_lba, L2C_CADD);
	lba2chs(&ha->end, &iter->di, iter->abs_lba + iter->length - 1, L2C_CADD);
	ha->start_lba = iter->abs_lba;
	ha->length = iter->length;

#ifdef DEBUG
	dprintf("MBR handover:\n");
	disk_dos_part_dump(ha);
#endif
    } else {
	/* shouldn't ever happen */
	goto bail;
    }

    data->base = 0x7be;
    data->size = synth_size;
    data->data = (void *)ha;

    return 0;
bail:
    return -1;
}