- Multiboot is needed to initialize our memory management


git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@14 315a16e6-25f9-4109-90ae-ca3045a26c18
This commit is contained in:
stefan 2010-08-02 12:32:58 +00:00
parent ae08a68b42
commit e184955a2b
8 changed files with 231 additions and 9 deletions

View file

@ -0,0 +1,137 @@
/*
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of MetalSVM.
*/
#ifndef __ARCH_MULTIBOOT_H__
#define __ARCH_MULTIBOOT_H__
#include <metalsvm/stddef.h>
#ifdef USE_MULTIBOOT
/*
* MetalSVM is able to use Multiboot (http://www.gnu.org/software/grub/manual/multiboot/),
* which specifies an interface between a boot loader and a operating system
*/
typedef uint16_t multiboot_uint16_t;
typedef uint32_t multiboot_uint32_t;
typedef uint64_t multiboot_uint64_t;
/* The symbol table for a.out. */
struct multiboot_aout_symbol_table
{
multiboot_uint32_t tabsize;
multiboot_uint32_t strsize;
multiboot_uint32_t addr;
multiboot_uint32_t reserved;
};
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
/* The section header table for ELF. */
struct multiboot_elf_section_header_table
{
multiboot_uint32_t num;
multiboot_uint32_t size;
multiboot_uint32_t addr;
multiboot_uint32_t shndx;
};
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
struct multiboot_info
{
/* Multiboot info version number */
multiboot_uint32_t flags;
/* Available memory from BIOS */
multiboot_uint32_t mem_lower;
multiboot_uint32_t mem_upper;
/* "root" partition */
multiboot_uint32_t boot_device;
/* Kernel command line */
multiboot_uint32_t cmdline;
/* Boot-Module list */
multiboot_uint32_t mods_count;
multiboot_uint32_t mods_addr;
union
{
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
/* Memory Mapping buffer */
multiboot_uint32_t mmap_length;
multiboot_uint32_t mmap_addr;
/* Drive Info buffer */
multiboot_uint32_t drives_length;
multiboot_uint32_t drives_addr;
/* ROM configuration table */
multiboot_uint32_t config_table;
/* Boot Loader Name */
multiboot_uint32_t boot_loader_name;
/* APM table */
multiboot_uint32_t apm_table;
/* Video */
multiboot_uint32_t vbe_control_info;
multiboot_uint32_t vbe_mode_info;
multiboot_uint16_t vbe_mode;
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
};
typedef struct multiboot_info multiboot_info_t;
struct multiboot_mmap_entry
{
multiboot_uint32_t size;
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
multiboot_uint32_t type;
} __attribute__((packed));
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
struct multiboot_mod_list
{
/* the memory used goes from bytes mod start to mod end-1 inclusive */
multiboot_uint32_t mod_start;
multiboot_uint32_t mod_end;
/* Module command line */
multiboot_uint32_t cmdline;
/* padding to take it to 16 bytes (must be zero) */
multiboot_uint32_t pad;
};
typedef struct multiboot_mod_list multiboot_module_t;
extern multiboot_info_t* mb_info;
#endif
#endif

View file

@ -1,4 +1,4 @@
C_source = gdt.c idt.c isrs.c irq.c vga.c kb.c timer.c
C_source = gdt.c idt.c isrs.c irq.c vga.c kb.c timer.c multiboot.c
ASM_source = schedule.asm
OBJS += $(patsubst %.c, %.o, $(filter %.c, $(C_source)))

View file

@ -55,10 +55,16 @@ mboot:
dd end
dd start
stublet:
; interpret multiboot information
extern multiboot_init
push ebx
call multiboot_init
pop ebp
; This is an endless loop here. Make a note of this: Later on, we
; will insert an 'extern _main', followed by 'call _main', right
; before the 'jmp $'.
stublet:
extern main
call main
jmp $

View file

@ -0,0 +1,38 @@
/*
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of MetalSVM.
*/
#include <metalsvm/stddef.h>
#ifdef USE_MULTIBOOT
#include <asm/multiboot.h>
/*
* MetalSVM is able to use Multiboot (http://www.gnu.org/software/grub/manual/multiboot/),
* which specifies an interface between a boot loader and a operating system
*/
multiboot_info_t* mb_info = NULL;
void multiboot_init(void* mb)
{
mb_info = (multiboot_info_t*) mb;
}
#endif

View file

@ -43,6 +43,8 @@ extern "C" {
//#undef USE_VGA
#define USE_KEYBOARD
//#undef USE_KEYBOARD
#define USE_MULTIBOOT
//#undef USE_MULTIBOOT
#define BUILTIN_EXPECT(exp, b) __builtin_expect((exp), (b))
//#define BUILTIN_EXPECT(exp, b) (exp)

View file

@ -28,7 +28,9 @@
extern "C" {
#endif
extern atomic_size_t total_usage;
extern atomic_size_t total_memory;
extern atomic_size_t total_allocated_memory;
extern atomic_size_t total_available_memory;
typedef struct {
atomic_size_t usage;

View file

@ -63,7 +63,9 @@ int main(void)
detect_cpu_frequency();
kprintf("Processor frequency: %d MHz\n", get_cpu_frequency()/1000000);
kprintf("Kernel size: %u KBytes\n", atomic_size_read(&total_usage)/1024);
kprintf("Total memory: %u MBytes\n", atomic_size_read(&total_memory)/(1024*1024));
kprintf("Current allocated memory: %u KBytes\n", atomic_size_read(&total_allocated_memory)/1024);
kprintf("Current available memory: %u MBytes\n", atomic_size_read(&total_available_memory)/(1024*1024));
timer_set_frequency(TIMER_FREQ);

View file

@ -21,6 +21,9 @@
#include <metalsvm/string.h>
#include <metalsvm/mmu.h>
#include <metalsvm/spinlocks.h>
#ifdef USE_MULTIBOOT
#include <asm/multiboot.h>
#endif
/*
* 0 => free
@ -29,7 +32,9 @@
static uint8_t bitmap[BITMAP_SIZE];
static spinlock_t bitmap_lock = SPINLOCK_INIT;
static size_t alloc_start;
atomic_size_t total_usage;
atomic_size_t total_memory = 0;
atomic_size_t total_allocated_memory = 0;
atomic_size_t total_available_memory = 0;
extern const void kernel_start;
extern const void kernel_end;
@ -71,12 +76,40 @@ void mmu_init(void)
size_t kernel_size;
unsigned int i;
memset(bitmap, 0x00, sizeof(uint8_t)*BITMAP_SIZE);
/* set whole address space as occupied */
memset(bitmap, 0xFF, sizeof(uint8_t)*BITMAP_SIZE);
#ifdef USE_MULTIBOOT
if (mb_info) {
multiboot_memory_map_t* mmap = (multiboot_memory_map_t*) mb_info->mmap_addr;
multiboot_memory_map_t* mmap_end = (void*) ((size_t) mb_info->mmap_addr + mb_info->mmap_length);
while (mmap < mmap_end) {
if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) {
/* set the available memory as "unused" */
size_t addr = mmap->addr;
size_t end_addr = addr + mmap->len;
while (addr < end_addr) {
page_unmarked(addr / PAGE_SIZE);
addr += PAGE_SIZE;
atomic_size_add(&total_memory, PAGE_SIZE);
atomic_size_add(&total_available_memory, PAGE_SIZE);
}
}
mmap++;
}
}
#else
#error Currently, MetalSVM needs multiboot!
#endif
/* kernel is aligned to page size */
kernel_size = (size_t) &kernel_end - (size_t) &kernel_start;
atomic_size_set(&total_usage, kernel_size);
atomic_size_set(&total_allocated_memory, kernel_size);
atomic_size_sub(&total_available_memory, kernel_size);
/* set kernel space as used */
for(i=(size_t) &kernel_start / PAGE_SIZE; i < (size_t) &kernel_end / PAGE_SIZE; i++)
page_marked(i);
@ -129,7 +162,8 @@ next_try:
page_marked(l);
alloc_start = i+j-1;
atomic_size_add(&total_usage, npages*PAGE_SIZE);
atomic_size_add(&total_allocated_memory, npages*PAGE_SIZE);
atomic_size_sub(&total_available_memory, npages*PAGE_SIZE);
if (task)
atomic_size_add(&(task->mm.usage), npages*PAGE_SIZE);
oom:
@ -168,7 +202,8 @@ static void task_free(task_t* task, void* addr, size_t sz)
for(i=index; i<index+npages; i++)
page_unmarked(i);
atomic_size_sub(&total_usage, npages*PAGE_SIZE);
atomic_size_sub(&total_allocated_memory, npages*PAGE_SIZE);
atomic_size_add(&total_available_memory, npages*PAGE_SIZE);
if (task)
atomic_size_sub(&(task->mm.usage), npages*PAGE_SIZE);