示例#1
0
文件: hw.c 项目: webcraft13/grub-1
/*
 * grub_uboot_probe_memory():
 *   Queries U-Boot for available memory regions.
 *
 *   Sets up heap near the image in memory and sets up "start_of_ram".
 */
void
grub_uboot_mm_init (void)
{
  struct sys_info *si = grub_uboot_get_sys_info ();

  grub_mm_init_region ((void *) grub_modules_get_end (),
		       GRUB_KERNEL_MACHINE_HEAP_SIZE);

  if (si && (si->mr_no != 0))
    {
      int i;
      start_of_ram = GRUB_UINT_MAX;

      // first, search for the start address
      for (i = 0; i < si->mr_no; i++)
	if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM)
	  if (si->mr[i].start < start_of_ram)
	    start_of_ram = si->mr[i].start;

      // then init memory regions for the others
      for (i = 0; i < si->mr_no; i++)
	if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM)
	  if (si->mr[i].start != start_of_ram)
	    grub_mm_init_region ((void *) si->mr[i].start, si->mr[i].size);
    }
}
示例#2
0
/* Helper for grub_claim_heap.  */
static int
heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
	   void *data)
{
  unsigned long *total = data;

  if (type != GRUB_MEMORY_AVAILABLE)
    return 0;

  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
    {
      if (addr + len <= 0x180000)
	return 0;

      if (addr < 0x180000)
	{
	  len = addr + len - 0x180000;
	  addr = 0x180000;
	}
    }
  len -= 1; /* Required for some firmware.  */

  /* Never exceed HEAP_MAX_SIZE  */
  if (*total + len > HEAP_MAX_SIZE)
    len = HEAP_MAX_SIZE - *total;

  /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
  if ((addr < HEAP_MAX_ADDR) &&				/* if it's too late, don't bother */
      (addr + len > HEAP_MAX_ADDR) &&				/* if it wasn't available anyway, don't bother */
      (*total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE))	/* only limit ourselves when we can afford to */
     len = HEAP_MAX_ADDR - addr;

  /* In theory, firmware should already prevent this from happening by not
     listing our own image in /memory/available.  The check below is intended
     as a safeguard in case that doesn't happen.  However, it doesn't protect
     us from corrupting our module area, which extends up to a
     yet-undetermined region above _end.  */
  if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
    {
      grub_printf ("Warning: attempt to claim over our own code!\n");
      len = 0;
    }

  if (len)
    {
      grub_err_t err;
      /* Claim and use it.  */
      err = grub_claimmap (addr, len);
      if (err)
	return err;
      grub_mm_init_region ((void *) (grub_addr_t) addr, len);
    }

  *total += len;
  if (*total >= HEAP_MAX_SIZE)
    return 1;

  return 0;
}
示例#3
0
文件: init.c 项目: Spacy/grub-fuse
void
grub_machine_init (void)
{
#ifdef GRUB_MACHINE_QEMU
  grub_qemu_init_cirrus ();
#endif
  /* Initialize the console as early as possible.  */
  grub_vga_text_init ();

  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, 
				       grub_memory_type_t);
  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size,
				  grub_memory_type_t type)
  {
#if GRUB_CPU_SIZEOF_VOID_P == 4
    /* Restrict ourselves to 32-bit memory space.  */
    if (addr > GRUB_ULONG_MAX)
      return 0;
    if (addr + size > GRUB_ULONG_MAX)
      size = GRUB_ULONG_MAX - addr;
#endif

    if (type != GRUB_MEMORY_AVAILABLE)
      return 0;

    /* Avoid the lower memory.  */
    if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
      {
	if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
	  return 0;
	else
	  {
	    size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
	    addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
	  }
      }

    grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);

    return 0;
  }

#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
  grub_machine_mmap_init ();
#endif
  grub_machine_mmap_iterate (heap_init);

  grub_tsc_init ();
}
示例#4
0
void
grub_machine_init (void)
{
#ifdef GRUB_MACHINE_QEMU
  grub_qemu_init_cirrus ();
#endif
  /* Initialize the console as early as possible.  */
  grub_vga_text_init ();

  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t);
  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
  {
#if GRUB_CPU_SIZEOF_VOID_P == 4
    /* Restrict ourselves to 32-bit memory space.  */
    if (addr > GRUB_ULONG_MAX)
      return 0;
    if (addr + size > GRUB_ULONG_MAX)
      size = GRUB_ULONG_MAX - addr;
#endif

    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
      return 0;

    /* Avoid the lower memory.  */
    if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
      {
	if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
	  return 0;
	else
	  {
	    size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
	    addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
	  }
      }

    if (addr == GRUB_MEMORY_MACHINE_UPPER_START
	|| (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE
	    && addr <= GRUB_MEMORY_MACHINE_UPPER_START
	    && (addr + size > GRUB_MEMORY_MACHINE_UPPER_START)))
      {
	grub_size_t quarter = size >> 2;

	grub_os_area_addr = addr;
	grub_os_area_size = size - quarter;
	grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
			     quarter);
      }
    else
示例#5
0
/* Claim some available memory in the first /memory node. */
static void grub_claim_heap (void)
{
  unsigned long total = 0;

  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
  {
    if (type != 1)
      return 0;

    if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
      {
	if (addr + len <= 0x180000)
	  return 0;

	if (addr < 0x180000)
	  {
	    len = addr + len - 0x180000;
	    addr = 0x180000;
	  }
      }
    len -= 1; /* Required for some firmware.  */

    /* Never exceed HEAP_MAX_SIZE  */
    if (total + len > HEAP_MAX_SIZE)
      len = HEAP_MAX_SIZE - total;

    /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
    if ((addr < HEAP_MAX_ADDR) &&				/* if it's too late, don't bother */
        (addr + len > HEAP_MAX_ADDR) &&				/* if it wasn't available anyway, don't bother */
        (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE))	/* only limit ourselves when we can afford to */
       len = HEAP_MAX_ADDR - addr;

    /* In theory, firmware should already prevent this from happening by not
       listing our own image in /memory/available.  The check below is intended
       as a safeguard in case that doesn't happen.  However, it doesn't protect
       us from corrupting our module area, which extends up to a
       yet-undetermined region above _end.  */
    if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
      {
        grub_printf ("Warning: attempt to claim over our own code!\n");
        len = 0;
      }

    if (len)
      {
	/* Claim and use it.  */
	if (grub_claimmap (addr, len) < 0)
	  return grub_error (GRUB_ERR_OUT_OF_MEMORY,
			     "failed to claim heap at 0x%llx, len 0x%llx",
			     addr, len);
	grub_mm_init_region ((void *) (grub_addr_t) addr, len);
      }

    total += len;
    if (total >= HEAP_MAX_SIZE)
      return 1;

    return 0;
  }

  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
    heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1);
  else
    grub_machine_mmap_iterate (heap_init);
}
示例#6
0
文件: init.c 项目: Spacy/grub-fuse
void
grub_machine_init (void)
{
  int i;
  int grub_lower_mem;

  /* Initialize the console as early as possible.  */
  grub_console_init ();

  grub_lower_mem = grub_get_conv_memsize () << 10;

  /* Sanity check.  */
  if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
    grub_fatal ("too small memory");

/* FIXME: This prevents loader/i386/linux.c from using low memory.  When our
   heap implements support for requesting a chunk in low memory, this should
   no longer be a problem.  */
#if 0
  /* Add the lower memory into free memory.  */
  if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
    add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
		    grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
#endif

  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
				  grub_memory_type_t);
  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
			     grub_memory_type_t type)
    {
      /* Avoid the lower memory.  */
      if (addr < 0x100000)
	{
	  if (size <= 0x100000 - addr)
	    return 0;

	  size -= 0x100000 - addr;
	  addr = 0x100000;
	}

      /* Ignore >4GB.  */
      if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE)
	{
	  grub_size_t len;

	  len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
		 ? 0xFFFFFFFF - addr
		 : size);
	  add_mem_region (addr, len);
	}

      return 0;
    }

  grub_machine_mmap_iterate (hook);

  compact_mem_regions ();

  for (i = 0; i < num_regions; i++)
      grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);

  grub_tsc_init ();
}
示例#7
0
文件: init.c 项目: Firef0x/burg-new
static void
grub_heap_init (void)
{
  grub_mm_init_region ((void *) (grub_modules_get_end ()
				 + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}