segment.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 /**
00022  * @file
00023  *
00024  * Executable image segments
00025  *
00026  */
00027 
00028 #include <errno.h>
00029 #include <gpxe/uaccess.h>
00030 #include <gpxe/memmap.h>
00031 #include <gpxe/errortab.h>
00032 #include <gpxe/segment.h>
00033 
00034 /**
00035  * Prepare segment for loading
00036  *
00037  * @v segment           Segment start
00038  * @v filesz            Size of the "allocated bytes" portion of the segment
00039  * @v memsz             Size of the segment
00040  * @ret rc              Return status code
00041  */
00042 int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ) {
00043         struct memory_map memmap;
00044         physaddr_t start = user_to_phys ( segment, 0 );
00045         physaddr_t mid = user_to_phys ( segment, filesz );
00046         physaddr_t end = user_to_phys ( segment, memsz );
00047         unsigned int i;
00048 
00049         DBG ( "Preparing segment [%lx,%lx,%lx)\n", start, mid, end );
00050 
00051         /* Sanity check */
00052         if ( filesz > memsz ) {
00053                 DBG ( "Insane segment [%lx,%lx,%lx)\n", start, mid, end );
00054                 return -EINVAL;
00055         }
00056 
00057         /* Get a fresh memory map.  This allows us to automatically
00058          * avoid treading on any regions that Etherboot is currently
00059          * editing out of the memory map.
00060          */
00061         get_memmap ( &memmap );
00062 
00063         /* Look for a suitable memory region */
00064         for ( i = 0 ; i < memmap.count ; i++ ) {
00065                 if ( ( start >= memmap.regions[i].start ) &&
00066                      ( end <= memmap.regions[i].end ) ) {
00067                         /* Found valid region: zero bss and return */
00068                         memset_user ( segment, filesz, 0, ( memsz - filesz ) );
00069                         return 0;
00070                 }
00071         }
00072 
00073         /* No suitable memory region found */
00074         DBG ( "Segment [%lx,%lx,%lx) does not fit into available memory\n",
00075               start, mid, end );
00076         return -ERANGE;
00077 }
00078 
00079 /**
00080  * Segment-specific error messages
00081  *
00082  * This error happens sufficiently often to merit a user-friendly
00083  * description.
00084  */
00085 struct errortab segment_errors[] __errortab = {
00086         { ERANGE, "Requested memory not available" },
00087 };

Generated on Tue Apr 6 20:01:06 2010 for gPXE by  doxygen 1.5.7.1