From: Brian Palmer Date: Wed, 27 Feb 2002 21:33:59 +0000 (+0000) Subject: Improved memory management X-Git-Tag: backups/mpw@12443~285 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=b7644717863a495575d121c0f9bdc19be79c8bcb Improved memory management The heap now sets it's size at run time instead of being hard coded svn path=/trunk/; revision=2656 --- diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 2b095141d58..7b2e4127eaa 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -33,8 +33,8 @@ LIB_FILES2 = comm/comm.a disk/disk.a mm/mm.a cache/cache.a all: freeldr.sys -freeldr.sys: c_code.a - $(LD) -N -Ttext=0x8000 --oformat=binary -s -o f.sys c_code.a +freeldr.sys: c_code.a end.o + $(LD) -N -Ttext=0x8000 --oformat=binary -s -o f.sys c_code.a end.o ../bootsect/stubit ../bootsect/fatstub.bin f.sys freeldr.sys freeldr.exe: asmcode.a c_code.a @@ -73,6 +73,9 @@ parseini.o: parseini.c parseini.h oslist.o: oslist.c oslist.h $(CC) $(FLAGS) -o oslist.o -c oslist.c +end.o: end.S + $(CC) $(FLAGS) -o end.o -c end.S + arch: $(MAKE) -C arch diff --git a/freeldr/freeldr/arch.h b/freeldr/freeldr/arch.h index a420c152dc9..176b4878ce2 100644 --- a/freeldr/freeldr/arch.h +++ b/freeldr/freeldr/arch.h @@ -57,4 +57,6 @@ void enable_a20(void); void stop_floppy(void); +extern unsigned long FreeLoaderModuleEnd; + #endif /* ! ASM */ diff --git a/freeldr/freeldr/arch/i386/mem.S b/freeldr/freeldr/arch/i386/mem.S index 326ba0489fa..0744dd3d4de 100644 --- a/freeldr/freeldr/arch/i386/mem.S +++ b/freeldr/freeldr/arch/i386/mem.S @@ -106,7 +106,7 @@ EXTERN(_GetExtendedMemorySize) EXTERN(_GetConventionalMemorySize) // - // get conventional memory size in KB + // Get conventional memory size in KB // pushl %edx @@ -123,7 +123,7 @@ EXTERN(_GetConventionalMemorySize) andl $0xffff,%eax*/ // clear carry /* Save return value */ - movl %eax,%edx + movzwl %ax,%edx call switch_to_prot diff --git a/freeldr/freeldr/end.S b/freeldr/freeldr/end.S new file mode 100644 index 00000000000..531940d8f08 --- /dev/null +++ b/freeldr/freeldr/end.S @@ -0,0 +1,27 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + .text + +#define ASM +#include "arch.h" + + +EXTERN(_FreeLoaderModuleEnd) + .long _FreeLoaderModuleEnd diff --git a/freeldr/freeldr/freeldr.c b/freeldr/freeldr/freeldr.c index eb1598eb154..7ed45be6a80 100644 --- a/freeldr/freeldr/freeldr.c +++ b/freeldr/freeldr/freeldr.c @@ -40,7 +40,6 @@ LONG GetTimeOut(VOID); VOID BootMain(VOID) { - ULONG Idx; UCHAR SettingName[80]; UCHAR SettingValue[80]; ULONG SectionId; @@ -57,7 +56,7 @@ VOID BootMain(VOID) DebugInit(); #endif - InitMemoryManager( (PVOID) 0x20000 /* BaseAddress */, 0x58000 /* Length */); + InitMemoryManager(); if (!ParseIniFile()) { diff --git a/freeldr/freeldr/mm.h b/freeldr/freeldr/mm.h index 1252ed7b369..8b1a30e65e9 100644 --- a/freeldr/freeldr/mm.h +++ b/freeldr/freeldr/mm.h @@ -24,7 +24,7 @@ #include -VOID InitMemoryManager(PVOID BaseAddress, ULONG Length); +VOID InitMemoryManager(VOID); PVOID AllocateMemory(ULONG NumberOfBytes); VOID FreeMemory(PVOID MemBlock); diff --git a/freeldr/freeldr/mm/Makefile b/freeldr/freeldr/mm/Makefile index 2da1fb04fdd..1e05a751c28 100644 --- a/freeldr/freeldr/mm/Makefile +++ b/freeldr/freeldr/mm/Makefile @@ -19,7 +19,7 @@ include ../rules.mk -OBJS = mm.o +OBJS = mm.o init.o .PHONY : clean @@ -28,9 +28,12 @@ all: mm.a mm.a: $(OBJS) $(LD) -r -o mm.a $(OBJS) -mm.o: mm.c ../mm.h +mm.o: mm.c ../mm.h mem.h $(CC) $(FLAGS) -o mm.o -c mm.c +init.o: init.c ../mm.h mem.h + $(CC) $(FLAGS) -o init.o -c init.c + clean: - $(RM) *.o - $(RM) *.a diff --git a/freeldr/freeldr/mm/init.c b/freeldr/freeldr/mm/init.c new file mode 100644 index 00000000000..17cda07dca5 --- /dev/null +++ b/freeldr/freeldr/mm/init.c @@ -0,0 +1,81 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "mem.h" +#include +#include +#include + + +ULONG RealFreeLoaderModuleEnd = 0; + +PVOID HeapBaseAddress = NULL; +ULONG HeapLengthInBytes = 0; +ULONG HeapMemBlockCount = 0; +PMEMBLOCK HeapMemBlockArray = NULL; + +VOID InitMemoryManager(VOID) +{ + ULONG MemBlocks; + ULONG BaseAddress; + ULONG Length; + + // Round up to the next page of memory + RealFreeLoaderModuleEnd = ((FreeLoaderModuleEnd + 4095) / 4096) * 4096; + BaseAddress = RealFreeLoaderModuleEnd; + Length = (MAXLOWMEMADDR - RealFreeLoaderModuleEnd); + + DbgPrint((DPRINT_MEMORY, "Initializing Memory Manager.\n")); + DbgPrint((DPRINT_MEMORY, "Conventional memory size: %d KB\n", GetConventionalMemorySize())); + DbgPrint((DPRINT_MEMORY, "Low memory map:\n")); + DbgPrint((DPRINT_MEMORY, "00000\t1000\tReserved\n")); + DbgPrint((DPRINT_MEMORY, "01000\t6000\t16-bit stack\n")); + DbgPrint((DPRINT_MEMORY, "07000\t1000\tUnused\n")); + DbgPrint((DPRINT_MEMORY, "08000\t%x\tFreeLoader program code\n", (RealFreeLoaderModuleEnd - 0x8000))); + DbgPrint((DPRINT_MEMORY, "%x\t%x\tLow memory heap\n", BaseAddress, Length)); + DbgPrint((DPRINT_MEMORY, "78000\t8000\t32-bit stack\n")); + DbgPrint((DPRINT_MEMORY, "80000\t10000\tFile system read buffer\n")); + DbgPrint((DPRINT_MEMORY, "90000\t10000\tDisk read buffer\n")); + DbgPrint((DPRINT_MEMORY, "A0000\t60000\tReserved\n")); + + // Calculate how many memory blocks we have + MemBlocks = (Length / MEM_BLOCK_SIZE); + + // Adjust the heap length so we can reserve + // enough storage space for the MEMBLOCK array + Length -= (MemBlocks * sizeof(MEMBLOCK)); + + // Initialize our tracking variables + HeapBaseAddress = BaseAddress; + HeapLengthInBytes = Length; + HeapMemBlockCount = (HeapLengthInBytes / MEM_BLOCK_SIZE); + HeapMemBlockArray = (PMEMBLOCK)(HeapBaseAddress + HeapLengthInBytes); + + // Clear the memory + RtlZeroMemory(HeapBaseAddress, HeapLengthInBytes); + RtlZeroMemory(HeapMemBlockArray, (HeapMemBlockCount * sizeof(MEMBLOCK))); + +#ifdef DEBUG + DbgPrint((DPRINT_MEMORY, "Memory Manager initialized. BaseAddress = 0x%x Length = 0x%x. %d blocks in heap.\n", BaseAddress, Length, HeapMemBlockCount)); + //MemAllocTest(); +#endif +} diff --git a/freeldr/freeldr/mm/mem.h b/freeldr/freeldr/mm/mem.h new file mode 100644 index 00000000000..097fa095a71 --- /dev/null +++ b/freeldr/freeldr/mm/mem.h @@ -0,0 +1,48 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __MEM_H +#define __MEM_H + + +// +// Define this to 1 if you want the entire contents +// of the memory allocation bitmap displayed +// when a chunk is allocated or freed +// +#define DUMP_MEM_MAP_ON_VERIFY 0 + +#define MEM_BLOCK_SIZE 256 + +typedef struct +{ + BOOL MemBlockAllocated; // Is this block allocated or free + ULONG BlocksAllocated; // Block length, in multiples of MEM_BLOCK_SIZE +} MEMBLOCK, *PMEMBLOCK; + + +extern ULONG RealFreeLoaderModuleEnd; + +extern PVOID HeapBaseAddress; +extern ULONG HeapLengthInBytes; +extern ULONG HeapMemBlockCount; +extern PMEMBLOCK HeapMemBlockArray; + +#endif // defined __MEM_H diff --git a/freeldr/freeldr/mm/mm.c b/freeldr/freeldr/mm/mm.c index 67cff795e89..9b300ae14c2 100644 --- a/freeldr/freeldr/mm/mm.c +++ b/freeldr/freeldr/mm/mm.c @@ -19,31 +19,12 @@ #include #include +#include "mem.h" #include #include #include -// -// Define this to 1 if you want the entire contents -// of the memory allocation bitmap displayed -// when a chunk is allocated or freed -// -#define DUMP_MEM_MAP_ON_VERIFY 0 - -#define MEM_BLOCK_SIZE 256 - -typedef struct -{ - BOOL MemBlockAllocated; // Is this block allocated or free - ULONG BlocksAllocated; // Block length, in multiples of 256 bytes -} MEMBLOCK, *PMEMBLOCK; - -PVOID HeapBaseAddress = NULL; -ULONG HeapLengthInBytes = 0; -ULONG HeapMemBlockCount = 0; -PMEMBLOCK HeapMemBlockArray = NULL; - #ifdef DEBUG ULONG AllocationCount = 0; @@ -54,33 +35,6 @@ VOID DecrementAllocationCount(VOID); VOID MemAllocTest(VOID); #endif // DEBUG -VOID InitMemoryManager(PVOID BaseAddress, ULONG Length) -{ - ULONG MemBlocks; - - // Calculate how many memory blocks we have - MemBlocks = (Length / MEM_BLOCK_SIZE); - - // Adjust the heap length so we can reserve - // enough storage space for the MEMBLOCK array - Length -= (MemBlocks * sizeof(MEMBLOCK)); - - // Initialize our tracking variables - HeapBaseAddress = BaseAddress; - HeapLengthInBytes = Length; - HeapMemBlockCount = (HeapLengthInBytes / MEM_BLOCK_SIZE); - HeapMemBlockArray = (PMEMBLOCK)(HeapBaseAddress + HeapLengthInBytes); - - // Clear the memory - RtlZeroMemory(HeapBaseAddress, HeapLengthInBytes); - RtlZeroMemory(HeapMemBlockArray, (HeapMemBlockCount * sizeof(MEMBLOCK))); - -#ifdef DEBUG - DbgPrint((DPRINT_MEMORY, "Memory Manager initialized. BaseAddress = 0x%x Length = 0x%x. %d blocks in heap.\n", BaseAddress, Length, HeapMemBlockCount)); - //MemAllocTest(); -#endif -} - PVOID AllocateMemory(ULONG NumberOfBytes) { ULONG BlocksNeeded;