Пример #1
0
/*!
    Copies the Multiboot info and any associated data (e.g. various strings and any multiboot modules)
    up to very high RAM (above 128 MB) to ensure it doesn't get clobbered by the booter.
 */
struct multiboot_info * copyMultibootInfo(int multiboot_magic, struct multiboot_info *mi_orig)
{
    void *hi_addr = determine_safe_hi_addr(multiboot_magic, mi_orig);
    if(hi_addr == NULL)
        return NULL;

    struct multiboot_info *mi_copy = hi_malloc(sizeof(*mi_copy));
    memcpy(mi_copy, mi_orig, sizeof(*mi_copy));
    
    // Copy the command line
    if(mi_orig->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE)
    {
        mi_copy->mi_cmdline = hi_strdup(mi_orig->mi_cmdline);
    }
    // Copy the loader name
    if(mi_orig->mi_flags & MULTIBOOT_INFO_HAS_LOADER_NAME)
    {
        mi_copy->mi_loader_name = hi_strdup(mi_orig->mi_loader_name);
    }
    // Copy the module info
    if(mi_orig->mi_flags & MULTIBOOT_INFO_HAS_MODS)
    {
        struct multiboot_module *dst_modules = hi_malloc(sizeof(*dst_modules)*mi_orig->mi_mods_count);
        struct multiboot_module *src_modules = (void*)mi_orig->mi_mods_addr;
        mi_copy->mi_mods_addr = (uint32_t)dst_modules;

        // Copy all of the module info plus the actual module into high memory
        int i;
        for(i=0; i < mi_orig->mi_mods_count; ++i)
        {
            // Assume mod_end is 1 past the actual end (i.e. it is start + size, not really end (i.e. start + size - 1))
            // This is what GRUB and mboot.c32 do although the spec is unclear on this.
            uint32_t mod_length = src_modules[i].mm_mod_end - src_modules[i].mm_mod_start;

            dst_modules[i].mm_mod_start = (uint32_t)hi_malloc(mod_length);
            dst_modules[i].mm_mod_end = (uint32_t)dst_modules[i].mm_mod_start + mod_length;
            memcpy((char*)dst_modules[i].mm_mod_start, (char*)src_modules[i].mm_mod_start, mod_length);
            
            dst_modules[i].mm_string = hi_strdup(src_modules[i].mm_string);
            dst_modules[i].mm_reserved = src_modules[i].mm_reserved;
        }
    }
    // Make sure that only stuff that didn't need to be copied or that we did deep copy is indicated in the copied struct.
    mi_copy->mi_flags &= MULTIBOOT_INFO_HAS_MEMORY | MULTIBOOT_INFO_HAS_BOOT_DEVICE | MULTIBOOT_INFO_HAS_CMDLINE | MULTIBOOT_INFO_HAS_LOADER_NAME | MULTIBOOT_INFO_HAS_MODS;

    return mi_copy;
}
Пример #2
0
/***************************************
* install the cache memory
* the largest available memory block must be size bytes
* return actual amount of memory available,
* ie size of largest available block
*/
uint32 install_cache( uint32 size )
{
register uint32 s = size;
uint32   a = MemAvail();	/* available memory */

   assert( head_mem == NULL );	/* must not already be installed !! */

   /* restrict size to range 60k .. (mem available - 60k) */
   if( s == 0 ) s = a/4;	/* default value */
   if( s < 60000 ) s = 60000;	/* min size */
   if( 60000+s > a ) s = a/2;	/* too big ==> use 50% available memory */

   s = ((s+3)&~3)+sizeof(tMemHdr);	/* round up to exact number of longs */
   assert( (sizeof(tMemHdr)&3) == 0 );	/* exact nr longs */

   head_free = head_mem = (tMemHdr*)hi_malloc( s );

   if( head_mem == NULL ) {
      /* pathological case ... */
      nr_blocks = 0;
      total_size = 0;
   }
   else {
      total_size = head_mem->size = s - sizeof(tMemHdr);
      #ifndef NDEBUG
      head_free->magic = MAGIC;
      head_free->data[0] = -1;
      #endif
      head_free->pbase = NULL;
      head_free->next_mem = NULL;
      head_free->prev_mem = NULL;
      head_free->next_list = NULL;
      head_free->prev_list = NULL;
      head_data = tail_data = NULL;
      nr_blocks = 1;
   } /* if */

   total_used = 0;
   total_free = total_size;

   assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );
   assert( check_block(head_free) );
   assert( check_cache() );

   return total_size;

} /* install_cache() */