Page 1 of 1

Help Counting RAM

Posted: Mon Jul 21, 2003 7:42 pm
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!

Re:Help Counting RAM

Posted: Mon Jul 21, 2003 8:05 pm
by pleasepaymybills
Here is an application that will get the RAM:

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

Re:Help Counting RAM

Posted: Mon Jul 21, 2003 8:07 pm
by TheChuckster
:o

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

Re:Help Counting RAM

Posted: Mon Jul 21, 2003 8:09 pm
by pleasepaymybills
IT WORKS! IWROTE IT IN QBASIC! Do you want the binary? IT REALLY WORKS! You doubt that it works?!

Re:Help Counting RAM

Posted: Mon Jul 21, 2003 10:16 pm
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

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 12:59 am
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.

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 9:17 am
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'
?

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 11:00 am
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;
}


Re:Help Counting RAM

Posted: Tue Jul 22, 2003 1:30 pm
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...

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 2:38 pm
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 ...

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 5:26 pm
by TheChuckster
gedeon: Your function does not work. It returns that I have 64kb, when in fact, I have 256 MB of RAM.

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 5:48 pm
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*

Re:Help Counting RAM

Posted: Tue Jul 22, 2003 6:40 pm
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;
    }
  }
}