Implemented memory detection & BIOS memory map
authorBrian Palmer <brianp@sginet.com>
Tue, 12 Jun 2001 16:12:50 +0000 (16:12 +0000)
committerBrian Palmer <brianp@sginet.com>
Tue, 12 Jun 2001 16:12:50 +0000 (16:12 +0000)
Added memory management prototypes

svn path=/trunk/; revision=1961

freeldr/freeldr/Makefile
freeldr/freeldr/mb.S
freeldr/freeldr/mem.S [new file with mode: 0644]
freeldr/freeldr/memory.c [new file with mode: 0644]
freeldr/freeldr/memory.h [new file with mode: 0644]
freeldr/freeldr/multiboot.c
freeldr/freeldr/multiboot.h
freeldr/freeldr/reactos.c

index 06aedc5..06f16e8 100644 (file)
@@ -29,10 +29,11 @@ FLAGS = -Wall -fno-builtin
 
 # asmcode.o has to be first in the link line because it contains the startup code
 OBJS = asmcode.a asmcode.o mb.o boot.o freeldr.o stdlib.o fs.a fs.o fs_fat.o \
-       reactos.o tui.o menu.o miscboot.o options.o linux.o multiboot.o arcname.o
-ASM_OBJS = asmcode.o mb.o boot.o
+       reactos.o tui.o menu.o miscboot.o options.o linux.o multiboot.o arcname.o \
+       mem.o memory.o
+ASM_OBJS = asmcode.o mb.o boot.o mem.o
 C_OBJS = freeldr.o stdlib.o fs.a reactos.o tui.o menu.o miscboot.o options.o linux.o \
-       multiboot.o arcname.o
+       multiboot.o arcname.o memory.o
 
 all:   freeldr.sys
 
@@ -93,6 +94,12 @@ linux.o:     linux.c freeldr.h stdlib.h tui.h linux.h Makefile
 arcname.o:     arcname.c freeldr.h arcname.h stdlib.h Makefile
        $(CC) $(FLAGS) -o arcname.o -c arcname.c
 
+mem.o: mem.S asmcode.h Makefile
+       $(CC) $(FLAGS) -o mem.o -c mem.S
+
+memory.o:      memory.c asmcode.h memory.h Makefile
+       $(CC) $(FLAGS) -o memory.o -c memory.c
+
 clean:
        $(RM) *.o
        $(RM) *.a
index 5a0c273..15f9638 100644 (file)
@@ -248,11 +248,11 @@ EXTERN(_multiboot_module_strings)
        .byte   0
        .endr
 
-_multiboot_address_range_descriptor_size:
+EXTERN(_multiboot_memory_map_descriptor_size)
        .long   0
 
-_multiboot_address_ranges:
-       .rept   (64 * /*multiboot_address_range_size*/24)
+EXTERN(_multiboot_memory_map)
+       .rept   (64 * /*sizeof(memory_map_t)*/24)
        .byte   0
        .endr
 
diff --git a/freeldr/freeldr/mem.S b/freeldr/freeldr/mem.S
new file mode 100644 (file)
index 0000000..631eb35
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  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
+       .code16
+
+#define ASM
+#include "asmcode.h"
+#include "multiboot.h"
+
+
+
+       .code32
+EXTERN(_GetExtendedMemorySize)
+
+       //
+       // get extended memory size in KB
+       //
+       pushl   %edx
+       pushl   %ecx
+       pushl   %ebx
+
+       call    switch_to_real
+       .code16
+
+       movw    $0xe801,%ax
+       int             $0x15
+       jc              .oldstylemem
+
+       cmpw    $0,%ax
+       je              .cmem
+
+       andl    $0xffff,%ebx
+       shll    $6,%ebx
+       andl    $0xffff,%eax
+       add             %ebx,%eax
+       jmp             .done_mem
+
+.cmem:
+       cmpw    $0,%cx
+       je              .oldstylemem
+
+       andl    $0xffff,%edx
+       shll    $6,%edx
+       andl    $0xffff,%ecx
+       addl    %ecx,%edx
+       movl    %edx,%eax
+       jmp             .done_mem
+
+.oldstylemem:
+       // int 15h opt e801 don't work , try int 15h, option 88h
+       movb    $0x88,%ah
+       int             $0x15
+       cmp             $0,%ax
+       je              .cmosmem
+       movzwl  %ax,%eax
+       jmp             .done_mem
+
+.cmosmem:
+       // int 15h opt 88h don't work , try read cmos
+       xorl    %eax,%eax
+       movb    $0x31,%al
+       outb    %al,$0x70
+       inb             $0x71,%al
+       andl    $0xffff,%eax    // clear carry
+       shll    $8,%eax
+
+.done_mem:
+
+
+       /* Save return value */
+       movl    %eax,%edx
+
+       call    switch_to_prot
+
+       .code32
+
+       /* Restore return value */
+       movl    %edx,%eax
+
+       popl    %ebx
+       popl    %ecx
+       popl    %edx
+
+       ret
+
+
+
+       .code32
+EXTERN(_GetConventionalMemorySize)
+
+       //
+       // get conventional memory size in KB
+       //
+       pushl   %edx
+
+       call    switch_to_real
+       .code16
+
+       xorl    %eax,%eax
+       int             $0x12
+
+       /*xorl  %eax,%eax
+       movb    $0x30,%al
+       outb    %al,$0x70
+       inb             $0x71,%al
+       andl    $0xffff,%eax*/  // clear carry
+
+       /* Save return value */
+       movl    %eax,%edx
+
+       call    switch_to_prot
+
+       .code32
+
+       /* Restore return value */
+       movl    %edx,%eax
+
+       popl    %edx
+
+       ret
+
+
+
+       .code32
+_gbmm_mem_map_length:
+       .long 0
+_gbmm_memory_map_addr:
+       .long 0
+EXTERN(_GetBiosMemoryMap)
+       //
+       // Retrieve BIOS memory map if available
+       //
+       pushl   %edx
+       pushl   %ecx
+       pushl   %ebx
+       pushl   %edi
+
+       movl    $0,_gbmm_mem_map_length
+
+       /* Get memory map address off stack */
+       movl    0x10(%esp),%eax
+       movl    %eax,_gbmm_memory_map_addr
+
+       call    switch_to_real
+       .code16
+
+       xorl    %ebx,%ebx
+       movl    _gbmm_memory_map_addr,%edi
+
+.mmap_next:
+
+       movl    $0x534D4150,%edx        // 'SMAP'
+       movl    $/*sizeof(memory_map_t)*/24,%ecx
+       movl    0xE820,%eax
+       int             $0x15
+       jc              .done_mmap
+
+       cmpl    $0x534D4150,%eax        // 'SMAP'
+       jne             .done_mmap
+
+       addl    $/*sizeof(memory_map_t)*/24,%edi
+       addl    $/*sizeof(memory_map_t)*/24,_gbmm_mem_map_length
+
+       cmpl    $0,%ebx
+       jne             .mmap_next
+
+.done_mmap:
+
+       call    switch_to_prot
+
+       .code32
+
+       /* Get return value */
+       movl    _gbmm_mem_map_length,%eax
+
+       popl    %edi
+       popl    %ebx
+       popl    %ecx
+       popl    %edx
+
+       ret
diff --git a/freeldr/freeldr/memory.c b/freeldr/freeldr/memory.c
new file mode 100644 (file)
index 0000000..1d958e4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  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 "freeldr.h"
+#include "memory.h"
+
+
+void InitMemoryManager(void *HeapBaseAddress, unsigned long HeapLength)
+{
+}
+
+void *malloc(int size)
+{
+       return 0;
+}
+
+void free(void *memblock)
+{
+}
diff --git a/freeldr/freeldr/memory.h b/freeldr/freeldr/memory.h
new file mode 100644 (file)
index 0000000..5603d5c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  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 __MEMORY_H
+#define __MEMORY_H
+
+#include "multiboot.h"
+
+
+void   InitMemoryManager(void *HeapBaseAddress, unsigned long HeapLength);
+
+void*  malloc(int size);
+void   free(void *memblock);
+
+// These functions are implemented in mem.S
+int            GetExtendedMemorySize(void);                            // Returns extended memory size in KB
+int            GetConventionalMemorySize(void);                        // Returns conventional memory size in KB
+int            GetBiosMemoryMap(memory_map_t *mem_map);        // Fills mem_map structure with BIOS memory map and returns length of memory map
+
+
+#endif // defined __MEMORY_H
\ No newline at end of file
index 32cd67d..095bc98 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  FreeLoader
- *  Copyright (C) 1999, 2000, 2001  Brian Palmer  <brianp@sginet.com>
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
  *
  *  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
index e557d78..324fb66 100644 (file)
@@ -123,12 +123,13 @@ typedef struct module
    but no size. */
 typedef struct memory_map
 {
-  unsigned long size;
+  //unsigned long size;
   unsigned long base_addr_low;
   unsigned long base_addr_high;
   unsigned long length_low;
   unsigned long length_high;
   unsigned long type;
+  unsigned long reserved;
 } memory_map_t;
 
 
@@ -137,10 +138,14 @@ multiboot_info_t          mb_info;                                                        // Multiboot info structure passed to kernel
 char                                   multiboot_kernel_cmdline[255];          // Command line passed to kernel
 module_t                               multiboot_modules[64];                          // Array to hold boot module info loaded for the kernel
 char                                   multiboot_module_strings[64][256];      // Array to hold module names
+unsigned long                  multiboot_memory_map_descriptor_size;
+memory_map_t                   multiboot_memory_map;                           // Memory map
 
 
 void   boot_reactos(void);
 
+#include "fs.h"                // Included FILE structure definition
+
 BOOL   MultiBootLoadKernel(FILE *KernelImage);
 BOOL   MultiBootLoadModule(FILE *ModuleImage, char *ModuleName);
 int            GetBootPartition(char *OperatingSystemName);
index c44afa5..a18981d 100644 (file)
@@ -26,6 +26,7 @@
 #include "tui.h"
 #include "multiboot.h"
 #include "arcname.h"
+#include "memory.h"
 
 BOOL   LoadReactOSKernel(char *OperatingSystemName);
 BOOL   LoadReactOSDrivers(char *OperatingSystemName);
@@ -36,24 +37,37 @@ void LoadAndBootReactOS(char *OperatingSystemName)
        char            name[1024];
        char            value[1024];
        char            szFileName[1024];
-       char    szBootPath[256];
+       char            szBootPath[256];
        int                     i;
        int                     nNumDriverFiles=0;
        int                     nNumFilesLoaded=0;
-       char MsgBuffer[256];
+       char            MsgBuffer[256];
 
        /*
         * Setup multiboot information structure
         */
        mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
-       mb_info.mem_lower = 640;//(640 * 1024);
-       mb_info.mem_upper = (8 * 1024);
+       mb_info.mem_lower = GetConventionalMemorySize();
+       mb_info.mem_upper = GetExtendedMemorySize();
        mb_info.boot_device = 0xffffffff;
        mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
        mb_info.mods_count = 0;
        mb_info.mods_addr = (unsigned long)multiboot_modules;
-       mb_info.mmap_length = 0;
-       mb_info.mmap_addr = 0;
+       mb_info.mmap_length = GetBiosMemoryMap(&multiboot_memory_map);
+       if (mb_info.mmap_length)
+       {
+               mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
+               mb_info.flags |= MB_INFO_FLAG_MEMORY_MAP;
+               //printf("memory map length: %d\n", mb_info.mmap_length);
+               //printf("dumping memory map:\n");
+               //for (i=0; i<(mb_info.mmap_length / 4); i++)
+               //{
+               //      printf("0x%x\n", ((unsigned long *)&multiboot_memory_map)[i]);
+               //}
+               //getch();
+       }
+       //printf("low_mem = %d\n", mb_info.mem_lower);
+       //printf("high_mem = %d\n", mb_info.mem_upper);
 
        /*
         * Make sure the system path is set in the .ini file