Ejemplo n.º 1
0
int hdd_io(int hdd_n, void *buff, u16 sectors, u64 start, int read)
{
	u8       sbuf[32];
	rm_ctx   ctx;
	u32      head, cyl;
	u8       dos_n = hdd2dos(hdd_n);
	hdd_inf *hdd   = &iodb.p_hdd[hdd_n];
	lba_p   *lba   = pv(0x580); /* this needed for avoid stupid actions by buggy BIOSes */	
	int      succs = 0;

	/* setup initial context */
	set_ctx(0, &ctx);

	if (hdd->flags & HDD_LBA)
	{
		/* save old buffer */
		mincpy(sbuf, lba, sizeof(sbuf));

		/* setup LBA block */
		lba->size    = sizeof(lba_p);
		lba->unk     = 0;
		lba->dst_sel = rm_seg(buff);
		lba->dst_off = rm_off(buff);
		lba->numb    = sectors; 
		lba->sector  = start;
		
		ctx.ah = read ? 0x42:0x43;
		ctx.dl = dos_n; 
		ctx.si = 0x180; 
		ctx.ds = 0x40; /* if DS can be 0x40, we can avoid AWARD BIOS bug of int13/AX=4B01 */ 
		/* set additional registers to serve buggy BIOSes. */
		ctx.es = ctx.ds;
		ctx.di = ctx.si;
		ctx.bx = ctx.si;
		ctx.cx = ctx.ds;
		/* do not check AH because some buggy USB BIOSes fail to clear AH on success */
		succs = bios_call(0x13, &ctx);

		/* restore saved buffer */
		mincpy(lba, sbuf, sizeof(sbuf));
	} else
	{
		head = d32(start) / hdd->max_sect;		
		cyl  = head / hdd->max_head;

		ctx.ah = read ? 0x02:0x03;
		ctx.al = d8(sectors);
		ctx.ch = d8(cyl);
		ctx.cl = d8(((cyl & 0x0300) >> 2) | (d32(start) % hdd->max_sect + 1));
		ctx.dh = head % hdd->max_head;
		ctx.dl = dos_n;
		ctx.es = rm_seg(buff);
		ctx.bx = rm_off(buff);

		/* do not check AH because some buggy USB BIOSes fail to clear AH on success */
		succs = bios_call(0x13, &ctx);
	}
	return succs;
}
Ejemplo n.º 2
0
static int get_memory_map_entry(uint32_t * token, struct memory_map_entry * entry)
{
    struct memory_map_entry buf;
    struct registers regs;

    regs.eax = 0xE820;
    regs.ebx = *token;
    regs.ecx = sizeof(struct memory_map_entry);
    regs.edx = 0x534D4150;
    regs.es = segment_of(&buf);
    regs.di = offset_of(&buf);

    bios_call(&regs, 0x15);
    if ((regs.flags & 1) != 0) /* CF set - error */
        return 1;
    if (regs.eax != 0x534D4150)
        return 2;

    *token = regs.ebx;
    entry->address = buf.address;
    entry->size = buf.size;
    entry->type = buf.type;
    entry->ext = buf.ext;

    return 0;
}
Ejemplo n.º 3
0
/**
 * Get the PXE entry point address.
 *
 * @return              Whether the entry point could be found.
 */
static bool get_entry_point(void) {
  bios_regs_t regs;
  pxenv_t *pxenv;
  pxe_t *pxe;

  /* Use the PXE installation check function. */
  bios_regs_init(&regs);
  regs.eax = INT1A_PXE_INSTALL_CHECK;
  bios_call(0x1a, &regs);
  if (regs.eax != INT1A_PXE_INSTALL_CHECK_RET || regs.eflags & X86_FLAGS_CF) {
    dprintf("pxe: loaded via PXE but PXE not available\n");
    return false;
  }

  /* Get the PXENV+ structure. */
  pxenv = (pxenv_t *)segoff_to_linear((regs.es << 16) | regs.bx);
  if (memcmp(pxenv->signature, PXENV_SIGNATURE, sizeof(pxenv->signature)) != 0) {
    boot_error("PXENV+ structure has incorrect signature");
  } else if (!checksum_range(pxenv, pxenv->length)) {
    boot_error("PXENV+ structure is corrupt");
  }

  /* Get the !PXE structure. */
  pxe = (pxe_t *)segoff_to_linear(pxenv->pxe_ptr);
  if (memcmp(pxe->signature, PXE_SIGNATURE, sizeof(pxe->signature)) != 0) {
    boot_error("!PXE structure has incorrect signature");
  } else if (!checksum_range(pxe, pxe->length)) {
    boot_error("!PXE structure is corrupt");
  }

  pxe_entry_point = pxe->entry_point_16;
  return true;
}
Ejemplo n.º 4
0
static void dc_password_error(prt_inf *active) 
{
	if (conf.error_type & ET_MESSAGE) {
		puts(conf.err_msg);
	}

	if (conf.error_type & ET_REBOOT) {
		bios_reboot();
	}

	if (conf.error_type & ET_BOOT_ACTIVE)
	{
		if (active == NULL) {
			puts("active partition not found\n");
		} else {
			boot_from_partition(active, 0);
		}
	}

	if (conf.error_type & ET_EXIT_TO_BIOS) {
		bios_call(0x18, NULL);
	}

	if (conf.error_type & ET_MBR_BOOT) {
		autocpy(pv(0x7C00), conf.save_mbr, SECTOR_SIZE);
		bios_jump_boot(boot_dsk, 0);
	}
}
Ejemplo n.º 5
0
uint32_t get_low_memory_limit()
{
    struct registers regs;
    bios_call(&regs, 0x12);
    return regs.ax * 1024;
}