Page 1 of 1

Weird mmap entries...

Posted: Mon Aug 16, 2010 4:45 am
by TylerH
This is my pmm's init function for multiboot memory maps. It's supposed to get the highest valid page in ver_page, then go through the mmap again to reserve all pages between the highest valid one and 0. It doesn't seem to work right, ver_page is always 0, because there are no valid(MULT..._AVAILABLE) entries. I know memory is limited to 64MB, but how do I determine that when the available memory ranges are not reported?

Code: Select all

void pmem_multiboot_init(multiboot_memory_map_t* mmap, int len)
{
	unsigned int i, ver_pages = 0;
	struct multiboot_mmap_entry* mmap_entry;
	for(i = 0;i < len;i += (mmap->size + sizeof(mmap->size)))
	{
		printf("Base: %x Len: %x Type: %d\n", (unsigned int)mmap_entry->addr, (unsigned int)mmap_entry->len, mmap->type);
		mmap_entry = (struct multiboot_mmap_entry*)((char*)(unsigned int)mmap->addr + i);
		/*if(mmap_entry->addr < MEM)
		{
			if(mmap_entry->addr + mmap_entry->len >= 0xffffffff)
				mmap_entry->len = 0xffffffff - mmap_entry->addr;
			mmap_entry->len += pagesize - (unsigned int)mmap_entry->len % pagesize;
			if(((unsigned int)((((unsigned int)mmap_entry->addr >> 12) + ((unsigned int)mmap_entry->len >> 12))) > ver_pages) && (mmap_entry->type == MULTIBOOT_MEMORY_AVAILABLE))
				ver_pages = ((mmap_entry->addr + mmap_entry->len) >> 12) + 1;
		}*/
	}
	/*printf("pages: %x\n", ver_pages);
	for(i = 0;i < len;i += mmap->size + sizeof(mmap->size))
		if(mmap_entry->addr < MEM)
			if(mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE)
			{
				pmem_alloc_block((void*)(unsigned int)mmap_entry->addr, (void*)(unsigned int)(mmap_entry->addr + mmap_entry->len));
				printf("Reserved: %x - %x\n", (unsigned int)mmap_entry->addr, (unsigned int)(mmap_entry->addr + mmap_entry->len));
			}
	pmem_alloc_block((void*)0, (void*)0x100000);*/
}
Notice that a lot is commented out. There are bugs :).
Output in attached image.[DELETED]

Re: Weird mmap entries...

Posted: Mon Aug 16, 2010 5:36 am
by gerryg400

Code: Select all

   struct multiboot_mmap_entry* mmap_entry;
   for(i = 0;i < len;i += (mmap->size + sizeof(mmap->size)))
   {
      printf("Base: %x Len: %x Type: %d\n", (unsigned int)mmap_entry->addr, (unsigned int)mmap_entry->len, mmap->type);
You are printing mmap_entry->addr, mmap_entry->len and mmap->type before you initialise mmap_entry. Fix that and you might at least see the first area printed correctly.

Re: Weird mmap entries...

Posted: Mon Aug 16, 2010 6:50 am
by jal
gerryg400 wrote:You are printing mmap_entry->addr, mmap_entry->len and mmap->type before you initialise mmap_entry. Fix that and you might at least see the first area printed correctly.
Lol, that's kinda embarassing. I mean, that could happen to any of us, but then not being able to solve it and feeling the need to ask for assistance, that's kinda...


JAL

Re: Weird mmap entries...

Posted: Mon Aug 16, 2010 7:33 am
by TylerH
Jal: Yep... I let it get too complex, and couldn't effectively step through what was happening.

Anyway, here's my revised base, from which I'll improve on, if it isn't screwed up:

Code: Select all

void pmem_multiboot_init(struct multiboot_mmap_entry* mmap, int len)
{
	struct multiboot_mmap_entry *mmap_entry = mmap;
	for(;(unsigned int)((char*)mmap_entry - (char*)mmap < len);)
	{
		printf("Base: %x Len: %x Type: %d - %s\n", (unsigned int)mmap_entry->addr, (unsigned int)mmap_entry->len, mmap_entry->type, (mmap_entry->type == MULTIBOOT_MEMORY_AVAILABLE) ? "Available" : "Reserved");
		mmap_entry += mmap_entry->size + sizeof(mmap_entry->size);
	}
}
Attached is the output.

It still isn't reporting all available memory(64MB - 0x4000000)...

Re: Weird mmap entries...

Posted: Mon Aug 16, 2010 7:43 am
by gerryg400

Code: Select all

      mmap_entry += mmap_entry->size + sizeof(mmap_entry->size);
Pointer arithmetic !

Re: Weird mmap entries...

Posted: Mon Aug 16, 2010 8:33 am
by gerryg400
A for loop without an initialiser or a counter is actually a while loop. Rather than

Code: Select all

   for(;(unsigned int)((char*)mmap_entry - (char*)mmap < len);)
this would be nicer

Code: Select all

   while ((unsigned int)((char*)mmap_entry - (char*)mmap < len))
There's no need to cast what is basically a boolean to an unsigned int. If you write this, others will understand it

Code: Select all

   while ((char*)mmap_entry - (char*)mmap < len)

Re: Weird mmap entries...

Posted: Mon Aug 16, 2010 9:22 am
by TylerH
Dude, thank you so much! I worked on this thing all night( #-o ), now it finally works correctly \:D/. You're an effing genius.

P.S. I'm going to delete the pics to save space.