[solved] Reading memory map from multiboot.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
uzytkownik
Posts: 14
Joined: Sat Nov 15, 2008 3:39 pm

[solved] Reading memory map from multiboot.

Post by uzytkownik »

I try to read a memory map from grub:

Code: Select all

#include <iapi/kernel/memory.h>

#pragma pack(1)
struct multiboot_memory_map
{
  unsigned int size;
  unsigned long long addr;
  unsigned long long length;
  unsigned int type;
};

struct multiboot_drive
{
  unsigned int size;
  unsigned char number;
  unsigned char mode;
  unsigned short cylinders;
  unsigned char heads;
  unsigned char sectors;
  unsigned short ports[];
};

struct multiboot_info
{
  unsigned int flags;
  struct {
    unsigned int lower;
    unsigned int upper;
  } memory;
  struct {
    char drive;
    char part1;
    char part2;
    char part3;
  } boot_device;
  char *commandline;
  struct {
    unsigned int length;
    void *address;
  } modules;
  char padding[4];
  struct {
    unsigned int length;
    struct multiboot_memory_map *addr;
  } mmap;
  void *config_table;
  char *boot_loader_name;
  struct
  {
    unsigned short version;
    unsigned short cseg;
    unsigned int offset;
    unsigned short cseg_16;
    unsigned short dseg;
    unsigned short flags;
    unsigned short cseg_len;
    unsigned short cseg_16_len;
    unsigned short dseg_len;
  } apm;
};

#pragma pack()

void
kstart (unsigned long magic, struct multiboot_info *info)
{
  void *usable[64];
  unsigned int usable_lengths[64];
  unsigned int usable_length;
  struct multiboot_memory_map *mmap;

  usable_length = 0;
  mmap = info->mmap.addr;
  while(usable_length < 64 && (int)mmap < (int)info->mmap.addr + info->mmap.length)
    {
      if (mmap->type == 1)
	{
	  usable[usable_length] = (void *)((unsigned int)mmap->addr);
	  usable_lengths[usable_length] = (unsigned int)mmap->length;
	  usable_length++;
	}
      
      mmap = (struct multiboot_memory_map *)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
    }
  
  iapi_kernel_memory_init (usable_length, usable, usable_lengths);
  
  while(1)
    __asm__("hlt");
}
The readings are strange. First entry is:

Code: Select all

Breakpoint 4, kstart (magic=0x2badb002, info=0x2d3c8) at arch/i386/start.c:74
74	  while(usable_length < 64 && (int)mmap < (int)info->mmap.addr + info->mmap.length)
gdb> p mmap
$1 = (struct multiboot_memory_map *) 0x10a000
gdb> p *mmap
$2 = {size = 0x0, addr = 0x0, length = 0x0, type = 0x0}
What is wrong?

PS. Read from boche

Edit: It has been solved on alt.os.development. The problem is padding in place of ELF/a.out header. It should have been 16B not 4B.
Last edited by uzytkownik on Sun Dec 28, 2008 3:20 am, edited 1 time in total.
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: Reading memory map from multiboot.

Post by JohnnyTheDon »

What about the other entries? I sometimes get empty/invalid entries when reading memory regions from grub.If you are detecting usable memory, you can ignore anything with a type other than 1.
Post Reply