From 4750bc0160dddc6a9e5e7e9939b7291337d04c33 Mon Sep 17 00:00:00 2001 From: Brian Palmer Date: Tue, 12 Jun 2001 16:12:50 +0000 Subject: [PATCH] Implemented memory detection & BIOS memory map Added memory management prototypes svn path=/trunk/; revision=1961 --- freeldr/freeldr/Makefile | 13 ++- freeldr/freeldr/mb.S | 6 +- freeldr/freeldr/mem.S | 198 ++++++++++++++++++++++++++++++++++++ freeldr/freeldr/memory.c | 35 +++++++ freeldr/freeldr/memory.h | 38 +++++++ freeldr/freeldr/multiboot.c | 2 +- freeldr/freeldr/multiboot.h | 7 +- freeldr/freeldr/reactos.c | 26 +++-- 8 files changed, 311 insertions(+), 14 deletions(-) create mode 100644 freeldr/freeldr/mem.S create mode 100644 freeldr/freeldr/memory.c create mode 100644 freeldr/freeldr/memory.h diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 06aedc5cc95..06f16e863d6 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -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 diff --git a/freeldr/freeldr/mb.S b/freeldr/freeldr/mb.S index 5a0c273ef64..15f96389809 100644 --- a/freeldr/freeldr/mb.S +++ b/freeldr/freeldr/mb.S @@ -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 index 00000000000..631eb3515da --- /dev/null +++ b/freeldr/freeldr/mem.S @@ -0,0 +1,198 @@ +/* + * FreeLoader + * Copyright (C) 2001 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 + .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 index 00000000000..1d958e416b5 --- /dev/null +++ b/freeldr/freeldr/memory.c @@ -0,0 +1,35 @@ +/* + * FreeLoader + * Copyright (C) 2001 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 "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 index 00000000000..5603d5cc039 --- /dev/null +++ b/freeldr/freeldr/memory.h @@ -0,0 +1,38 @@ +/* + * FreeLoader + * Copyright (C) 2001 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 __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 diff --git a/freeldr/freeldr/multiboot.c b/freeldr/freeldr/multiboot.c index 32cd67d40c8..095bc98c10c 100644 --- a/freeldr/freeldr/multiboot.c +++ b/freeldr/freeldr/multiboot.c @@ -1,6 +1,6 @@ /* * FreeLoader - * Copyright (C) 1999, 2000, 2001 Brian Palmer + * Copyright (C) 2001 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 diff --git a/freeldr/freeldr/multiboot.h b/freeldr/freeldr/multiboot.h index e557d78b607..324fb66bea2 100644 --- a/freeldr/freeldr/multiboot.h +++ b/freeldr/freeldr/multiboot.h @@ -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); diff --git a/freeldr/freeldr/reactos.c b/freeldr/freeldr/reactos.c index c44afa55705..a18981dc2b7 100644 --- a/freeldr/freeldr/reactos.c +++ b/freeldr/freeldr/reactos.c @@ -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 -- 2.17.1