diff --git a/contrib/bochs/README.qemu b/contrib/bochs/README.qemu index e72c8841..ee20eec4 100644 --- a/contrib/bochs/README.qemu +++ b/contrib/bochs/README.qemu @@ -54,15 +54,14 @@ To get qemu running is fairly simple: 8. Build Etherboot floppy disk images and pad to 1.44MB pushd ../../src - make bin/rtl8139.dsk - ./util/dskpad.pl bin/rtl8139.dsk + make bin/rtl8139.pdsk popd 9. Start qemu export SDL_VIDEO_X11_DGAMOUSE=0 ./qemu/i386-softmmu/qemu -L qemu/pc-bios \ -net nic,model=rtl8139 -net tap,ifname=tap0 \ - -boot a -fda ../../src/bin/rtl8139.dsk + -boot a -fda ../../src/bin/rtl8139.pdsk You should see qemu start up, load up Etherboot and attempt to boot from the network. diff --git a/src/Makefile b/src/Makefile index 2dd2a8d7..fe730424 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 bda22c8a..620cddd2 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 5eef5086..bfd62ef1 100644 --- a/src/arch/i386/core/umalloc.c +++ b/src/arch/i386/core/umalloc.c @@ -23,8 +23,11 @@ * */ +#include +#include #include #include +#include #include /** 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 ); }