示例#1
0
int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist,
			     struct syslinux_memmap *memmap,
			     uint16_t bootflags,
			     struct syslinux_pm_regs *regs)
{
  int nd;
  com32sys_t ireg;
  char *regbuf;
  uint8_t handoff_code[9*5], *p;
  const uint32_t *rp;
  int i, rv;
  struct syslinux_memmap *tmap;
  addr_t regstub, stublen, safe;

  tmap = syslinux_target_memmap(fraglist, memmap);
  if (!tmap)
    return -1;

  regstub = 0x800;		/* Locate anywhere above this point */
  stublen = sizeof handoff_code;
  rv = syslinux_memmap_find(tmap, SMT_FREE, &regstub, &stublen, 1);
  syslinux_free_memmap(tmap);
  if (rv)
    return -1;

  /* Build register-setting stub */
  p = handoff_code;
  rp = (const uint32_t *)regs;
  for (i = 0; i < 8; i++) {
    *p = 0xb8 + i;		/* MOV gpr,imm32 */
    *(uint32_t *)(p+1) = *rp++;
    p += 5;
  }
  *p = 0xe9;			/* JMP */
  *(uint32_t *)(p+1) = regs->eip - regstub - sizeof handoff_code;

  /* Add register-setting stub to shuffle list */
  if (syslinux_add_movelist(&fraglist, regstub, (addr_t)handoff_code,
			    sizeof handoff_code))
    return -1;

  return syslinux_do_shuffle(fraglist, memmap, regstub, 1, bootflags);
}
示例#2
0
文件: map.c 项目: 1stMaster/syslinux
/*
 * Note: although there is no such thing in the spec, at least Xen makes
 * assumptions as to where in the memory space Grub would have loaded
 * certain things.  To support that, if "high" is set, then allocate this
 * at an address strictly above any previous allocations.
 *
 * As a precaution, this also pads the data with zero up to the next
 * alignment datum.
 */
addr_t map_data(const void *data, size_t len, size_t align, int flags)
{
    addr_t start = (flags & MAP_HIGH) ? mboot_high_water_mark : 0x2000;
    addr_t pad = (flags & MAP_NOPAD) ? 0 : -len & (align - 1);
    addr_t xlen = len + pad;

    if (syslinux_memmap_find(amap, SMT_FREE, &start, &xlen, align) ||
	syslinux_add_memmap(&amap, start, len + pad, SMT_ALLOC) ||
	syslinux_add_movelist(&ml, start, (addr_t) data, len) ||
	(pad && syslinux_add_memmap(&mmap, start + len, pad, SMT_ZERO))) {
	printf("Cannot map %zu bytes\n", len + pad);
	return 0;
    }

    dprintf("Mapping 0x%08x bytes (%#x pad) at 0x%08x\n", len, pad, start);

    if (start + len + pad > mboot_high_water_mark)
	mboot_high_water_mark = start + len + pad;

    return start;
}