Help Counting RAM

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
TheChuckster

Help Counting RAM

Post by TheChuckster »

Hello. I cannot compile my memory counting code and I can't seem to figure it out. Here is the code:

Code: Select all

void K_initmemman(void)
{
   register unsigned long *mem;
   unsigned long   mem_count, a;
   unsigned short   memkb;
   unsigned char   irq1, irq2;
   unsigned long   cr0;
   unsigned long   mem_end, bse_end;

   /* save IRQ's */
   irq1=inportb(0x21);
   irq2=inportb(0xA1);

   /* kill all irq's */
   outportb(0x21, 0xFF);
   outportb(0xA1, 0xFF);

   mem_count=0;
   memkb=0;

   // store a copy of CR0 -- LINE 73 IS NEXT!!!
   __asm__ __volatile("movl %%cr0, %%eax":"=a"(cr0))::"eax");

   // invalidate the cache
   // write-back and invalidate the cache
   __asm__ __volatile__ ("wbinvd");

   // plug cr0 with just PE/CD/NW
   // cache disable(486+), no-writeback(486+), 32bit mode(386+) -- LINE 81 IS NEXT!!!
   __asm__ __volatile__("movl %%eax, %%cr0", :: "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) : "eax");

   do
   {
      memkb++;
      mem_count+=1024*1024;
      mem=(unsigned long*)mem_count;

      a=*mem;

      *mem=0x55AA55AA;
      
      // the empty asm calls tell gcc not to rely on whats in its registers
      // as saved variables (this gets us around GCC optimisations)
      asm("":::"memory");
      if(*mem!=0x55AA55AA)
         mem_count=0;
      else
      {
         *mem=0xAA55AA55;
         asm("":::"memory");
         if(*mem!=0xAA55AA55)
            mem_count=0;
      }

      asm("":::"memory");
      *mem=a;
   }while(memkb<4096 && mem_count!=0);

   // LINE 110 IS NEXT!!!
   __asm__ __volatile__("movl %%eax, %%cr0", :: "a" (cr0) : "eax");

   mem_end=memkb<<20;
   mem=(unsigned long*)0x413;
   bse_end=((*mem)&0xFFFF)<<6;

   outportb(0x21, irq1);
   outportb(0xA1, irq2);

   kprintf("Mem: %d", mem_count);
}
And here is the DJGPP output:

Code: Select all

kernel.c: In function `K_initmemman':
kernel.c:73: syntax error before ':' token
kernel.c:81: syntax error before ':' token
kernel.c:110: syntax error before ':' token
I have commented in the code where these lines occur.

Thanks in advance for your help!
pleasepaymybills

Re:Help Counting RAM

Post by pleasepaymybills »

Here is an application that will get the RAM:

CLS
PRINT "How much RAM is installed?"
INPUT HOWMUCHRAM
'GOT RAM!
TheChuckster

Re:Help Counting RAM

Post by TheChuckster »

:o

Should I keep my sanity and let the mods here deal with this or cuss him out?
pleasepaymybills

Re:Help Counting RAM

Post by pleasepaymybills »

IT WORKS! IWROTE IT IN QBASIC! Do you want the binary? IT REALLY WORKS! You doubt that it works?!
bkilgore

Re:Help Counting RAM

Post by bkilgore »

TheChuckster wrote:

Code: Select all

   // store a copy of CR0 -- LINE 73 IS NEXT!!!
   __asm__ __volatile("movl %%cr0, %%eax":"=a"(cr0))::"eax");
I had to look carefully, but I noticed on this line that you close all of the parentheses before the second colon.

__asm__ __volatile("movl %%cr0, %%eax":"=a"(cr0))::"eax");

That bold parenthesis is closing the parenthesis following volatile, which you don't want. If you count, you'll notice you have a total of two opening and three closing parens. Also, note that there should be two more underscores after volatile, so it should be __volatile__

Hope this helps...

- Brandon
The Pro from Dover

Re:Help Counting RAM

Post by The Pro from Dover »

Just as a minor note, it may have been useful to use [tt]#line[/tt] directives rather than comments, in this case, as it would allow you to more specifically indicate the error locations, like this:

Code: Select all

#line 1 "store_cr0.c"
  // store a copy of CR0
  __asm__ __volatile("movl %%cr0, %%eax":"=a"(cr0))::"eax");

  // invalidate the cache
  // write-back and invalidate the cache
  __asm__ __volatile__ ("wbinvd");

#line 1 "disable_cache.c"
  // plug cr0 with just PE/CD/NW
  // cache disable(486+), no-writeback(486+), 32bit mode(386+)
  __asm__ __volatile__("movl %%eax, %%cr0", :: "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) : "eax");
This would have returned error codes something like this:

Code: Select all

kernel.c: In function `K_initmemman':
store_cr0.c:1: syntax error before ':' token
disable_cache.c:1: syntax error before ':' token
Just a suggestion, of course; use whatever works for you. HTH.
TheChuckster

Re:Help Counting RAM

Post by TheChuckster »

Ok, that's all sorted out. Any reason why

Code: Select all

kernel.c:73: can't find a register in class `AREG' while reloading `asm'
kernel.c:81: can't find a register in class `AREG' while reloading `asm'
kernel.c:110: can't find a register in class `AREG' while reloading `asm'
?
gedeon

Re:Help Counting RAM

Post by gedeon »

The same function a little bit modified
it works

Code: Select all


int count_memory(void)
{
   register unsigned long *mem;
   unsigned long bse_end;
   unsigned long   mem_count;
   unsigned long   a;
   unsigned short   memkb;
   unsigned long   mem_end;

   mem_count=0;
   memkb=0;

   do
   {
      memkb++;
      mem_count+=1024*1024;
      mem=(unsigned long*)mem_count;

      a=*mem;

      *mem=0x55AA55AA;

      // the empty asm calls tell gcc not to rely on whats in its registers
      // as saved variables (this gets us around GCC optimisations)
      asm("":::"memory");
      if(*mem!=0x55AA55AA)
         mem_count=0;
      else
      {
         *mem=0xAA55AA55;
         asm("":::"memory");
         if(*mem!=0xAA55AA55)
            mem_count=0;
      }
      asm("":::"memory");
      *mem=a;
   }while(memkb<4096 && mem_count!=0);
   mem_end=memkb<<20;
   mem=(unsigned long*)0x413;
   bse_end=((*mem)&0xFFFF)<<6;
   return   memkb;
}

bkilgore

Re:Help Counting RAM

Post by bkilgore »

TheChuckster wrote: Ok, that's all sorted out. Any reason why

Code: Select all

kernel.c:73: can't find a register in class `AREG' while reloading `asm'
kernel.c:81: can't find a register in class `AREG' while reloading `asm'
kernel.c:110: can't find a register in class `AREG' while reloading `asm'
?


I'm not sure the exact details, but basically it's because you're clobbering eax, and the compiler wants it. Why not just let gcc pick a register for you instead of forcing eax? Change the three lines to those that follow:

Code: Select all

// store a copy of CR0 -- LINE 73 IS NEXT!!!
  __asm__ __volatile__("movl %%cr0, 0":"=g"(cr0));

Code: Select all

// cache disable(486+), no-writeback(486+), 32bit mode(386+) -- LINE 81 IS NEXT!!!
  __asm__ __volatile__("movl %0, %%cr0" :: "g" (cr0 | 0x00000001 | 0x40000000 | 0x20000000));

Code: Select all

// LINE 110 IS NEXT!!!
  __asm__ __volatile__("movl %0, %%cr0" :: "g" (cr0));
Let me know if that works...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Help Counting RAM

Post by Pype.Clicker »

TheChuckster wrote: Ok, that's all sorted out. Any reason why

Code: Select all

kernel.c:73: can't find a register in class `AREG' while reloading `asm'
kernel.c:81: can't find a register in class `AREG' while reloading `asm'
kernel.c:110: can't find a register in class `AREG' while reloading `asm'
?
not sure, but it looks strange to me that you have "eax" declared as "clobbered register' and as "output register". It doesn't sound like a good idea to me ...
TheChuckster

Re:Help Counting RAM

Post by TheChuckster »

gedeon: Your function does not work. It returns that I have 64kb, when in fact, I have 256 MB of RAM.
TheChuckster

Re:Help Counting RAM

Post by TheChuckster »

:-[ AHHH NO! Don't correct me... I feel foolish. I had Bochs set up to emulate 64 MB. No wonder the value was so low! *bangs head on desk repeatedly*
Tux

Re:Help Counting RAM

Post by Tux »

While I was searching for tutorials, I found this page. If you want a memory probing function, here it is:

Code: Select all


//PC.h HALfix/PolarOS core
//Defects: doesn't detect memory wraps!!

int getmemory()
{
  int where=0x200000;
  char save;
  for(;;)
  {
    char * point=(char *) where;
    save=point[0];
    point[0]='L'; //L is for Linux :)
    if(point[0]=='L')
    {
      point[0]=save;
      where+=0x100000;
    }
    else
    {
      point[0]=save;
      return where;
    }
  }
}
Post Reply