Problems with E820 Memory Detection

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
cthulhu
Posts: 3
Joined: Thu Jul 14, 2005 11:00 pm

Problems with E820 Memory Detection

Post by cthulhu »

I have spent the last couple of days trying everything I could think of to get memory detection through E820 to work. I have seen the recent thread on memory detection and, although that has helped to get me on the right path, I have run into problems. I have cobbled together some code after looking through various resources, but I cannot get it to work correctly.

Here is my code from inside my bootloader to get the memory map:

Code: Select all

         xor ax,ax
	mov es, ax
	mov ds, ax
 
	mov di,0x500 
	xor ebx,ebx 
	
	get_e820: 
	mov eax,0x0000E820 
	mov ecx,0x14 
	mov edx,0x534D4150 
	int 0x15 
	jc e820_end 
	
	cmp eax,0x534D4150 
	jne e820_end 
	
	add di,20 
	cmp ebx,0 
	jne get_e820 
	
	e820_end:
I am trying to store the memory map at 0x500 so I can access it from the kernel. From within the kernel, I am parsing the map with this code:

Code: Select all

struct e820entry
{
	unsigned long baseAddrLow;
	unsigned long baseAddrHigh;
	unsigned long lengthLow;
	unsigned long lengthHigh;
	unsigned long type;
} __attribute__((packed));

unsigned long reservedmemory; 
unsigned long useablememory; 

void getE820Map() 
{ 
   	unsigned long maplength; 
   	struct e820entry *mem = (struct e820entry *)0x500;
   	unsigned long a; 
    
   	puts("\nAddress\tLength\tType\n"); 

   	asm volatile("movl %%edi,%0" : "=r" (maplength) ); 
   	 
   	for(a=0;a<((maplength-0x500)/20);a++)
   	{  
		
		puti(mem[a].baseAddrLow);
		putch('\t');
		
		puti(mem[a].lengthLow);
		putch('\t');
	
		puti(mem[a].type);
		putch('\n');

		puti(maplength);	/* extra */
		putch('\n');
	
		timer_wait(100);	/* end extra */

      		if(mem[a].type==1) 
      		{ 
         		useablememory += mem[a].lengthLow; 
      		} 
      		else 
      		{ 
         		reservedmemory += mem[a].lengthLow; 
      		}         
   	} 
   	 
	puts("[RAM] Reserved: ");
	puti(reservedmemory/1024);
	puts("KB Usable: ");
	puti(useablememory/1024);
	puts("KB Total Memory: ");
	puti((reservedmemory+useablememory)/(1024*1024));
	puts("MB\n");

} 
This code doesn't work for me and has only printed out bogus information about the memory. I really am lost and fairly frustrated. I have no idea how to fix this because, to me, it seems correct. Any help and guidance would be greatly appreciated at this point. Thanks for your time.
Last edited by cthulhu on Thu Jul 14, 2005 11:00 pm, edited 1 time in total.
aymanmadkour
Posts: 11
Joined: Sat Feb 05, 2005 12:00 am

Re: Problems with E820 Memory Detection

Post by aymanmadkour »

I think the problem is in the "jc e820_end" instruction in your assembly code. As far as I know, int 15h does not set the carry flag on the first call if everything goes fine. But in the following calls, carry flag can be set on return (I don't know why. I think this is done to tell you that int 15h should be called one more time).

In the code, the function ends whenever CF is set after int 15h call. It should be checked after the first call only.
blackcatcoder
Member
Member
Posts: 132
Joined: Wed Nov 03, 2004 12:00 am
Location: Austria
Contact:

Re: Problems with E820 Memory Detection

Post by blackcatcoder »

this part of code is from my own boot loader with e820 detection try it, this works !


xor eax,eax
;xor edi,edi
;mov ds,ax
mov es,ax
mov di,0x100 ;so that we know where the table is in pm
xor ebx,ebx
mov ecx,20
e820:
mov edx,0x534d4150
mov eax,0x0000e820
int 0x15
jc e820failed ;take your own label if the e820 fails

cmp eax,0x534d4150
jne e820failed ;take your own label if the e820 fails

cmp ebx,0
je e820done ;we are done
cmp byte [e820nr],32
jnl e820done ;we are done
inc byte [e820nr]
mov ax,di
add ax,20
mov di,ax
jmp e820 ; do the e820 again!


've a lot of fun, don't forget to sort the memory map you will get on address 0x100 !
cthulhu
Posts: 3
Joined: Thu Jul 14, 2005 11:00 pm

Re: Problems with E820 Memory Detection

Post by cthulhu »

blackcatcoder:

I'm going to try and use your implementation but I was wondering about the e820nr variable. How is that used and what does that signify? Is that the number of entries recieved for the memory map? If it is, do you use it as an argument for the kernel? Thanks for the help, this memory detection task has become really annoying.
blackcatcoder
Member
Member
Posts: 132
Joined: Wed Nov 03, 2004 12:00 am
Location: Austria
Contact:

Re: Problems with E820 Memory Detection

Post by blackcatcoder »

the e820nr var, is only for counting how many cycles I've done and has no relevance for the kernel just for comparing as you see:

cmp byte [e820nr],32 ; max 32 cycles and then we are done!
cthulhu
Posts: 3
Joined: Thu Jul 14, 2005 11:00 pm

Re: Problems with E820 Memory Detection

Post by cthulhu »

Thanks for all the help. I now have the memory detection up and running.
blackcatcoder
Member
Member
Posts: 132
Joined: Wed Nov 03, 2004 12:00 am
Location: Austria
Contact:

Re: Problems with E820 Memory Detection

Post by blackcatcoder »

no prob!
Post Reply