Ejemplo n.º 1
0
/**
 * Perform a series of memory copies from a list in low memory
 */
static void shuffle ( unsigned int list_segment, unsigned int list_offset, unsigned int count )
{
	comboot_shuffle_descriptor shuf[COMBOOT_MAX_SHUFFLE_DESCRIPTORS];
	unsigned int i;

	/* Copy shuffle descriptor list so it doesn't get overwritten */
	copy_from_user ( shuf, real_to_user ( list_segment, list_offset ), 0,
	                 count * sizeof( comboot_shuffle_descriptor ) );

	/* Do the copies */
	for ( i = 0; i < count; i++ ) {
		userptr_t src_u = phys_to_user ( shuf[ i ].src );
		userptr_t dest_u = phys_to_user ( shuf[ i ].dest );

		if ( shuf[ i ].src == 0xFFFFFFFF ) {
			/* Fill with 0 instead of copying */
			memset_user ( dest_u, 0, 0, shuf[ i ].len );
		} else if ( shuf[ i ].dest == 0xFFFFFFFF ) {
			/* Copy new list of descriptors */
			count = shuf[ i ].len / sizeof( comboot_shuffle_descriptor );
			assert ( count <= COMBOOT_MAX_SHUFFLE_DESCRIPTORS );
			copy_from_user ( shuf, src_u, 0, shuf[ i ].len );
			i = -1;
		} else {
			/* Regular copy */
			memmove_user ( dest_u, 0, src_u, 0, shuf[ i ].len );
		}
	}
}
Ejemplo n.º 2
0
Archivo: segment.c Proyecto: 42wim/ipxe
/**
 * Prepare segment for loading
 *
 * @v segment		Segment start
 * @v filesz		Size of the "allocated bytes" portion of the segment
 * @v memsz		Size of the segment
 * @ret rc		Return status code
 */
int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ) {
	struct memory_map memmap;
	physaddr_t start = user_to_phys ( segment, 0 );
	physaddr_t mid = user_to_phys ( segment, filesz );
	physaddr_t end = user_to_phys ( segment, memsz );
	unsigned int i;

	DBG ( "Preparing segment [%lx,%lx,%lx)\n", start, mid, end );

	/* Sanity check */
	if ( filesz > memsz ) {
		DBG ( "Insane segment [%lx,%lx,%lx)\n", start, mid, end );
		return -EINVAL;
	}

	/* Get a fresh memory map.  This allows us to automatically
	 * avoid treading on any regions that Etherboot is currently
	 * editing out of the memory map.
	 */
	get_memmap ( &memmap );

	/* Look for a suitable memory region */
	for ( i = 0 ; i < memmap.count ; i++ ) {
		if ( ( start >= memmap.regions[i].start ) &&
		     ( end <= memmap.regions[i].end ) ) {
			/* Found valid region: zero bss and return */
			memset_user ( segment, filesz, 0, ( memsz - filesz ) );
			return 0;
		}
	}

	/* No suitable memory region found */
	DBG ( "Segment [%lx,%lx,%lx) does not fit into available memory\n",
	      start, mid, end );
	return -ERANGE_SEGMENT;
}