- add Multiboot support (http://www.gnu.org/software/grub/manual/multiboot/)
- 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:
parent
ae08a68b42
commit
e184955a2b
8 changed files with 231 additions and 9 deletions
137
arch/x86/include/asm/multiboot.h
Normal file
137
arch/x86/include/asm/multiboot.h
Normal 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
|
|
@ -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)))
|
||||
|
|
|
@ -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 $
|
||||
|
|
38
arch/x86/kernel/multiboot.c
Normal file
38
arch/x86/kernel/multiboot.c
Normal 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
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
45
mm/alloc.c
45
mm/alloc.c
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue