amount of memory
-
ncsu121978
amount of memory
how can i get the total amount of memory installed on the system. I have seen some code that will read values from CMOS and it works fine but will only report up to 64MB. How can i determine more memory then this ?
Does someone have any code they would like to share ?
Does someone have any code they would like to share ?
-
ncsu121978
Re:amount of memory
Code: Select all
/*
* void count_memory (void)
*
* probes memory above 1mb
*
* last mod : 05sep98 - stuart george
* 08dec98 - "" ""
* 21feb99 - removed dummy calls
*
*/
void count_memory(void)
{
register ULONG *mem;
ULONG mem_count, a;
USHORT memkb;
UCHAR irq1, irq2;
ULONG cr0;
/* save IRQ's */
irq1=inb(0x21);
irq2=inb(0xA1);
/* kill all irq's */
outb(0x21, 0xFF);
outb(0xA1, 0xFF);
mem_count=0;
memkb=0;
// 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");
// 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");
do
{
memkb++;
mem_count+=1024*1024;
mem=(ULONG*)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);
__asm__ __volatile__("movl %%eax, %%cr0", :: "a" (cr0) : "eax");
mem_end=memkb<<20;
mem=(ULONG*)0x413;
bse_end=((*mem)&0xFFFF)<<6;
outb(0x21, irq1);
outb(0xA1, irq2);
}
here are the errors
kernel/kernel.c:183: parse error before ':' token
kernel/kernel.c:191: parse error before ':' token
kernel/kernel.c:220: parse error before ':' token
kernel/kernel.c:222: `mem_end' undeclared (first use in this function)
kernel/kernel.c:222: (Each undeclared identifier is reported only once
kernel/kernel.c:222: for each function it appears in.)
kernel/kernel.c:223: `ULONG' undeclared (first use in this function)
kernel/kernel.c:223: parse error before ')' token
kernel/kernel.c:224: `bse_end' undeclared (first use in this function)
the only ones i have problems with are the stuff in the asm(...)
i can work out the rest myself....but am unfamiliar with inline assembly in gcc.
i do understand you put assembly instructions in the asm(...) but all the other symbols confuse me
-
Tom
Re:amount of memory
try getting rid of the "'s with the :: and :'s and getting rid of all the : and :: without the quotes too...
-
ncsu121978
Re:amount of memory
sorry but i dont really understand what you are trying to say there.....could you just type out those couple of asm lines and how they should look ?
-
Paul
Re:amount of memory
If you are in protected mode, just probe the memory directly.... Start at 0x100000 and write a known byte sequence to memory and try reading it back to see if it changed. Once you can no longer write something and read the same thing back, you must have hit the end of memory. It's good to write two different values to make sure the first value wasn't already there. So like write 0x00ff00ff and then 0xff00ff00 to every dword.
Paul
Paul
-
ncsu121978
Re:amount of memory
ok.....i fixed the errors i mentioned in my previous post
but now the compiler gives me this
kernel/kernel.c:202: can't find a register in class `AREG' while reloading `asm
kernel/kernel.c:209: can't find a register in class `AREG' while reloading `asm
kernel/kernel.c:238: can't find a register in class `AREG' while reloading `asm
and i have no idea what that is
those lines refer to
but now the compiler gives me this
kernel/kernel.c:202: can't find a register in class `AREG' while reloading `asm
kernel/kernel.c:209: can't find a register in class `AREG' while reloading `asm
kernel/kernel.c:238: can't find a register in class `AREG' while reloading `asm
and i have no idea what that is
those lines refer to
Code: Select all
__asm__ __volatile("movl %%cr0, %%eax" : "=a"(cr0) : /* no input registers */ : "eax");
__asm__ __volatile__("movl %%eax, %%cr0": /* no output registers */ : "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) : "eax");
__asm__ __volatile__("movl %%eax, %%cr0": /* no output registers */ : "a" (cr0) : "eax");
-
ncsu121978
Re:amount of memory
ok....i got it working using a different example that i found in straight assembly code that i link with my c code
so you guys dont need to answer any more questions about it for me
thanks for all the help thus far
so you guys dont need to answer any more questions about it for me
thanks for all the help thus far
-
ncsu121978
Re:amount of memory
certainly
at the beginning of the execution of my kernel i call the kernel_probe_memory() function
where i set kernel_system_ram equal to its address is kind of a hack i guess
because the function in assembly stores the number of bytes into the memory location pointed to by kernel_system_ram....so i just make it point to itself so after the function kernel_system_ram is the number of bytes and no longer a pointer to itself. Does that make sense to anyone but me ?
Code: Select all
// in the assembly file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; name: get_amount_of_ram
; in: AL = 5
; out: (nothing)
; modifies: (nothing)
; minimum CPU: '386
; notes: gets the amount of ram on the system
; void get_amount_of_memory()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXPORT get_amount_of_ram
push ebx
push ecx
push edx
push es
push eax
mov ax, LINEAR_SEL
mov es, ax
xor eax, eax
cli ; make SURE interrupts are off
; this is only called once on system startup
; so interrupts should already be disabled
; but this will make SURE
@loop05:
add eax, 100000H ; 1MB
mov ebx, [es:eax]
mov edx, ebx
not ebx
mov [es:eax], ebx
mov ecx, [es:eax]
mov [es:eax], edx
cmp ebx, ecx
je @loop05
mov [_kernel_system_ram], eax ; _kernel_system_ram points to where you want
; the value containing the number of bytes stored
pop eax
pop es
pop edx
pop ecx
pop ebx
ret
// in the calling "C" file
uint kernel_system_ram; // as a global
/***********************************************************
gets amount of system memory
done on startup and amount stored in kernel_system_memory
***********************************************************/
void kernel_probe_memory()
{
kernel_system_ram = &kernel_system_ram;
get_amount_of_ram();
}
where i set kernel_system_ram equal to its address is kind of a hack i guess
because the function in assembly stores the number of bytes into the memory location pointed to by kernel_system_ram....so i just make it point to itself so after the function kernel_system_ram is the number of bytes and no longer a pointer to itself. Does that make sense to anyone but me ?
-
Tim
Re:amount of memory
I'm going to go against what the FAQ says, and what the others have been writing in this thread. Direct probing is a bad way to detect memory -- sure, it might tell you how much you have, but arbitrarily writing bytes into memory is bad.
Instead, you should ask the BIOS how much memory is installed, since it is the only piece of software which can interact directly with the motherboard. The best function to call is E820h, and you can do it in your boot loader. See "How do I determine RAM size with BIOS?" in the FAQ.
Instead, you should ask the BIOS how much memory is installed, since it is the only piece of software which can interact directly with the motherboard. The best function to call is E820h, and you can do it in your boot loader. See "How do I determine RAM size with BIOS?" in the FAQ.
-
pskyboy
Re:amount of memory
Im sorry Tim i disagree.
You are relying on the BIOS having the newer functions in order to be able to tell you how much memory it has and this can not be guaranteed. Also direct probing allows you to know how much memory you can actually get hold off. Ie if you have a dodgy memory chip and it doesn't work the bios might detect it (Depends how teh bios works out memory) where as probing tells you how much you can actually get hold of. Also its much more portable for moving between different platforms a must for my OS.
Peter
You are relying on the BIOS having the newer functions in order to be able to tell you how much memory it has and this can not be guaranteed. Also direct probing allows you to know how much memory you can actually get hold off. Ie if you have a dodgy memory chip and it doesn't work the bios might detect it (Depends how teh bios works out memory) where as probing tells you how much you can actually get hold of. Also its much more portable for moving between different platforms a must for my OS.
Peter
Re:amount of memory
I also go against direct memory probing
those nice PCI cards etc with mapped memory and memory mapped IO ports!!
i use the bios. (well I use grub, which uses the bios).
the next version of the faq (being written) removes the direct probing code.
i use the bios. (well I use grub, which uses the bios).
the next version of the faq (being written) removes the direct probing code.
-- Stu --
-
Tim
Re:amount of memory
pskyboy: The BIOS is the ultimate source of information about motherboard devices, memory included. It knows all the backdoor methods of interfacing with the chipset logic. If the BIOS says something, then treat that as correct -- if you can't trust the BIOS then you can't trust the motherboard.
Furthermore, any motherboard capable of using more than 64MB of RAM will support the new interfaces.
Furthermore, any motherboard capable of using more than 64MB of RAM will support the new interfaces.
-
K.J.
Re:amount of memory
I don't think Tim is planning for his OS to run primarrly on Pentiums or 486s.You are relying on the BIOS having the newer functions in order to be able to tell you how much memory it has and this can not be guaranteed.
Yup. Unless your OS is gonna be run on 386/486, PCI memory mapped stuff is rare.I also go against direct memory probing those nice PCI cards etc with mapped memory and memory mapped IO ports!!
K.J.
