/* Copyright (C) 2012, Aaron Lindsay This file is part of Aedrix. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include struct multiboot_mmap { unsigned int size; unsigned int base_addr_low, base_addr_high; unsigned int length_low, length_high; unsigned int type; }; extern multiboot_info_t* multiboot_mbd; extern uint32 multiboot_magic; int detect_memory_mmap() { struct multiboot_mmap* mmap = (struct multiboot_mmap*)multiboot_mbd->mmap_addr; int found_region = 0; while ((char*)mmap < (char*)multiboot_mbd->mmap_addr + multiboot_mbd->mmap_length) { if (mmap->base_addr_high || mmap->length_high) return -1; if (mmap->type == 0x1) { /* ignore non-usable memory */ declare_memory_region((void*)mmap->base_addr_low, (void*)(mmap->base_addr_low + mmap->length_low)); found_region = 1; } mmap = (struct multiboot_mmap*) ((unsigned int)mmap + mmap->size + sizeof(unsigned int)); } return !found_region; } int detect_memory_contiguous() { declare_memory_region((void*)0x0, (void*)((uint32)multiboot_mbd->mem_lower * 1024)); declare_memory_region((void*)0x1000000, (void*)((uint32)multiboot_mbd->mem_upper*1024 + 0x100000)); return 0; } int detect_memory() { if (multiboot_mbd->flags & (1<<6)) return detect_memory_mmap(); else if (multiboot_mbd->flags & (1<<0)) return detect_memory_contiguous(); return -1; }