Page 1 of 1

Memory manager by Memory Map

Posted: Mon May 16, 2016 7:47 am
by cklie97
Hello there,
while I tried to make a memory manager I wanted to use the mbs_mmap_* tags of the multiboot structure.
But there is something problematic in it.

While using the folowing code I got a mysterious output.

start.S

Code: Select all

.section multiboot
#define MB_MAGIC 0x1badb002
#define MB_FLAGS 0x0
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)

// Der Multiboot-Header
.align 4
.int    MB_MAGIC
.int    MB_FLAGS
.int    MB_CHECKSUM

.section .text

.extern main

.global _start
_start:
    mov $kernel_stack, %esp

    call main

_stop:
    cli
    hlt

    jmp _stop

.section .bss
.space 8192
kernel_stack:
main.c

Code: Select all

#include "descriptor_tables.h"

static void init(void);

int main(void)
{
    init();
    while(1);
    return 0;
}

static void init(void)
{
    asm volatile("push %ebx");
    init_gdt();
    init_idt();
    asm volatile("pop %ebx");
  clear();
    asm volatile("int $0x30");
}
Annotation: The interrupt 0x30 calls "init_memory" with the ebx as parameter.

memory_manager.c

Code: Select all

#include "memory_manager.h"
#include "console.h"

struct map_entry
{
    uint32_t size;
    uint64_t base_addr;
    uint64_t length;
    uint32_t type;
}__attribute__((packed));

void init_memory(void *pointer)
{
    uint32_t flags;
    uint32_t length;
    struct map_entry *map;

    uint8_t i;

    flags = *(uint32_t *)pointer;
    if(flags | 0x40)
    {
        length = *(uint32_t *)(pointer + 0x2c);
        map = *(struct map_entry **)(pointer + 0x30);
        kprintf("%d\n\r", map->length);
        do
        {
            kprintf("%d\n\r", map->size);
            kprintf("0x%x-0x%x-%d\n\r", map->base_addr, map->length, map->type);
            map++;
            i++;
        }
        while(i<7);
    }
    while(1);
}
Output of "init_memory"

Code: Select all

654336
20
0x0-0x0-654336
20
0x9fc00-0x0-1024
20
0xf0000-0x0-65536
20
0x100000-0x0-133160960
20
0x7ffe000-0x0-8192
20
0xfffc0000-0x0-262144
0
0x0-0x0-0
So there is no "free" ram and every ram block has a size of zero?

Re: Memory manager by Memory Map

Posted: Mon May 16, 2016 9:42 am
by BASICFreak
You are doing it wrong

Use the multiboot.h's structure, not a hard-codded and wrong offset.

e.g. should be 0x40 not 0x30 for "map" and 0x3C not 0x2C for "length" - there are 15 uint32_ts before mmap_length (if I counted correctly)
So your offsets into multiboot_info_t is off by 0x10 bytes.

Also do not use inline ASM to push and pop a register!
In fact you should have pushed ebx then called main(multiboot_info_t*), it would be in a place the compiler could handle and wouldn't have to rely on "hacks".




Best regards,

B!


P.S. I don't mean for this to come off offensively :wink:

Re: Memory manager by Memory Map

Posted: Mon May 16, 2016 9:57 am
by Velko
Another probable cause: are you sure your kprintf() handles 64-bit integers correctly?

If it interprets %x as 32-bit, then your second %x will print upper 32-bits from map->base_addr, not lowest from map->length.

Correct format specifier should be %llx, but if your kprintf() is not able to handle that, you may temporary try to down-cast the arguments: (uint32_t)map->base_addr

Re: Memory manager by Memory Map

Posted: Mon May 16, 2016 11:03 am
by cklie97
Velko wrote: Another probable cause: are you sure your kprintf() handles 64-bit integers correctly?

If it interprets %x as 32-bit, then your second %x will print upper 32-bits from map->base_addr, not lowest from map->length.
Thanks. That solved my problem. But in the memory map are several ram blocks missing.
Here is the memory map.

Code: Select all

start_addr  length     resulting_end
0x0         0x9fc00    0x9fc00
0x9fc00     0x400      0xa0000
0xf0000     0x10000    0x100000
0x100000    0x7efe000  0x7ffe000
0x7ffe000   0x2000     0x8000000
0xfffc0000  0x40000    0x0
The missing blocks are

Code: Select all

start_addr  length     resulting_end
0xa0000     0x50000    0xf0000
0x8000000   0xf7fc0000 0xfffc0000
Has anyone an idea why they are missing?

Re: Memory manager by Memory Map

Posted: Mon May 16, 2016 11:55 am
by FallenAvatar
1) Memory need not be contiguous.
2) There is almost always a hole at 0xa0000, it is the memory region reserved for the old graphics modes.

- Monk

Re: Memory manager by Memory Map

Posted: Thu May 19, 2016 2:04 am
by Combuster
There is "Memory" in RAM and ROM, but not in peripherals. Memory maps can't cover the entire space because the firmware doesn't know how to label all what devices do.