summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/arch/i386/Makefile7
-rw-r--r--src/arch/i386/core/umalloc.c75
3 files changed, 73 insertions, 11 deletions
diff --git a/src/Makefile b/src/Makefile
index 2dd2a8d72..fe7304242 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -162,7 +162,7 @@ NON_AUTO_SRCS += drivers/net/prism2.c
# "-p 0x1234,0x5678" string to set the PCI IDs.
#
FINALISE_rom = $(MAKEROM) $(MAKEROM_FLAGS) $(TGT_MAKEROM_FLAGS) \
- -i$(IDENT) $@
+ -i$(IDENT) -s 0 $@
# Some ROMs require specific flags to be passed to makerom.pl
#
diff --git a/src/arch/i386/Makefile b/src/arch/i386/Makefile
index bda22c8af..620cddd2d 100644
--- a/src/arch/i386/Makefile
+++ b/src/arch/i386/Makefile
@@ -111,6 +111,12 @@ NON_AUTO_MEDIA += fd0
dd if=$< bs=512 conv=sync of=/dev/fd0
sync
+# rule to create padded disk images
+NON_AUTO_MEDIA += pdsk
+%pdsk : %dsk
+ cp $< $@
+ $(PERL) ./util/dskpad.pl $@
+
# rule to make a non-emulation ISO boot image
NON_AUTO_MEDIA += iso
%iso: %lkrn util/geniso
@@ -125,6 +131,7 @@ NON_AUTO_MEDIA += liso
$(BIN)/usbdisk.bin : $(BIN)/usbdisk.o
$(OBJCOPY) -O binary $< $@
+NON_AUTO_MEDIA += usb
%usb: $(BIN)/usbdisk.bin %hd
cat $^ > $@
diff --git a/src/arch/i386/core/umalloc.c b/src/arch/i386/core/umalloc.c
index 5eef50866..bfd62ef16 100644
--- a/src/arch/i386/core/umalloc.c
+++ b/src/arch/i386/core/umalloc.c
@@ -23,8 +23,11 @@
*
*/
+#include <limits.h>
+#include <errno.h>
#include <gpxe/uaccess.h>
#include <gpxe/hidemem.h>
+#include <gpxe/memmap.h>
#include <gpxe/umalloc.h>
/** Alignment of external allocated memory */
@@ -36,9 +39,6 @@
/** Start of Etherboot text, as defined by the linker */
extern char _text[];
-/** Top of allocatable memory */
-#define TOP ( virt_to_user ( _text ) )
-
/** An external memory block */
struct external_memory {
/** Size of this memory block (excluding this header) */
@@ -47,11 +47,63 @@ struct external_memory {
int used;
};
-/** Current lowest allocated block
+/** Top of heap */
+static userptr_t top = UNULL;
+
+/** Bottom of heap (current lowest allocated block) */
+static userptr_t bottom = UNULL;
+
+/**
+ * Initialise external heap
*
- * A value of UNULL indicates that no blocks are currently allocated.
+ * @ret rc Return status code
*/
-userptr_t bottom = UNULL;
+static int init_eheap ( void ) {
+ struct memory_map memmap;
+ unsigned long heap_size = 0;
+ unsigned int i;
+
+ DBG ( "Allocating external heap\n" );
+
+ get_memmap ( &memmap );
+ for ( i = 0 ; i < memmap.count ; i++ ) {
+ struct memory_region *region = &memmap.regions[i];
+ unsigned long r_start, r_end;
+ unsigned long r_size;
+
+ DBG ( "Considering [%llx,%llx)\n", region->start, region->end);
+
+ /* Truncate block to 4GB */
+ if ( region->start > UINT_MAX ) {
+ DBG ( "...starts after 4GB\n" );
+ continue;
+ }
+ r_start = region->start;
+ if ( region->end > UINT_MAX ) {
+ DBG ( "...end truncated to 4GB\n" );
+ r_end = 0; /* =4GB, given the wraparound */
+ } else {
+ r_end = region->end;
+ }
+
+ /* Use largest block */
+ r_size = ( r_end - r_start );
+ if ( r_size > heap_size ) {
+ DBG ( "...new best block found\n" );
+ top = bottom = phys_to_user ( r_end );
+ heap_size = r_size;
+ }
+ }
+
+ if ( ! top ) {
+ DBG ( "No external heap available\n" );
+ return -ENOMEM;
+ }
+
+ DBG ( "External heap grows downwards from %lx\n",
+ user_to_phys ( top, 0 ) );
+ return 0;
+}
/**
* Collect free blocks
@@ -61,7 +113,7 @@ static void ecollect_free ( void ) {
struct external_memory extmem;
/* Walk the free list and collect empty blocks */
- while ( bottom != TOP ) {
+ while ( bottom != top ) {
copy_from_user ( &extmem, bottom, -sizeof ( extmem ),
sizeof ( extmem ) );
if ( extmem.used )
@@ -87,10 +139,13 @@ userptr_t urealloc ( userptr_t ptr, size_t new_size ) {
struct external_memory extmem;
userptr_t new = ptr;
size_t align;
+ int rc;
/* Initialise external memory allocator if necessary */
- if ( ! bottom )
- bottom = TOP;
+ if ( ! top ) {
+ if ( ( rc = init_eheap() ) != 0 )
+ return rc;
+ }
/* Get block properties into extmem */
if ( ptr && ( ptr != UNOWHERE ) ) {
@@ -140,7 +195,7 @@ userptr_t urealloc ( userptr_t ptr, size_t new_size ) {
/* Collect any free blocks and update hidden memory region */
ecollect_free();
hide_region ( EXTMEM, user_to_phys ( bottom, -sizeof ( extmem ) ),
- user_to_phys ( TOP, 0 ) );
+ user_to_phys ( top, 0 ) );
return ( new_size ? new : UNOWHERE );
}