How to get total RAM size of a device?
Standard unix command: $ cat /proc/meminfo
Note that /proc/meminfo
is a file. You don't actually have to run cat
, you can simply read the file.
Python - Getting Total RAM Size
There is no way to get the information you want without digging into the BIOS information, which requires modules you don't have.
How do you get total amount of RAM the computer has?
The Windows API function GlobalMemoryStatusEx
can be called with p/invoke:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private class MEMORYSTATUSEX
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
public MEMORYSTATUSEX()
{
this.dwLength = (uint)Marshal.SizeOf(typeof(NativeMethods.MEMORYSTATUSEX));
}
}
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
Then use like:
ulong installedMemory;
MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
if( GlobalMemoryStatusEx( memStatus))
{
installedMemory = memStatus.ullTotalPhys;
}
Or you can use WMI (managed but slower) to query TotalPhysicalMemory
in the Win32_ComputerSystem
class.
Get total installed RAM in C# on Windows 10
The TotalPhysicalMemory
is expressed in bytes.
If you want the memory to be converted to GB use this sample:
Convert.ToInt32(InstalledRam/(1024*1024*1024));
How do I get total physical memory size using PowerShell without WMI?
If you don't want to use WMI, I can suggest systeminfo.exe. But, there may be a better way to do that.
(systeminfo | Select-String 'Total Physical Memory:').ToString().Split(':')[1].Trim()
How I can get the installed RAM and CPU details c# .Net Core?
Looks like you're using the wrong class. Try the Win32_PhysicalMemory
class and the Capacity
property
var query = "SELECT Capacity FROM Win32_PhysicalMemory";
var searcher = new ManagementObjectSearcher(query);
foreach (var WniPART in searcher.Get())
{
var capacity = Convert.ToUInt64(WniPART.Properties["Capacity"].Value);
var capacityKB = capacity / 1024;
var capacityMB = capacityKB / 1024;
var capacityGB = capacityMB / 1024;
System.Console.WriteLine("Size in KB: {0}, Size in MB: {1}, Size in GB: {2}", capacityKB, capacityMB, capacityGB);
}
The MaxCapacity
property in the Win32_PhysicalMemoryArray
class will give you the maximum amount of RAM installable on your machine, not the amount of memory that is actually installed.
Total RAM size of an iOS device
The simplest solution to find total RAM in a device is to use NSProcessInfo
:
Objective C:
[NSProcessInfo processInfo].physicalMemory
Swift 3:
NSProcessInfo.processInfo().physicalMemory
Swift 5:
ProcessInfo.processInfo.physicalMemory
Note: physicalMemory
gives us the information at bytes, to calculate GB, divide by the constant 1073741824
.
As documented here.
How to get RAM Size , bootloader
Though the question stated in the body of your post is more about printing the value of a register than it is about detecting the memory available to the system, I'll just be loyal to the title question, and present an example of how to detect the system memory map.
As a bonus, a function to display a 32 bit unsigned integer as hex numeral is supplied, along with a very primitive print that supports placeholders.
Detecting memory is not an easy task, it requires full knowledge of the hardware installed1 and cannot be done without it (see Detecting memory on OSDev).
As a simple example think of an aliased memory, the software cannot detect that without any involved and slow method.
Having acknowledged that a cooperation with the BIOS is mandatory, we can see what services are available to a 16 bit real mode bootloader.
The above mentioned page of OSDev about detecting memory already have a list of services dedicated to the titled purpose, to which reference is made.
We will focus on the Int 15/AX=E820h service.
It's use is to return a list of memory range along with their description.
Each call return the next descriptor, using ebx
to keep track of the advancement. The register ebx
should be treated as an opaque value.
Despite the description in the Ralf's Brown Interrupt List, descriptors can be 24 bytes long, so it's better to use that length and eventually check the value returned in ecx
to tell 20/24 bytes descriptors apart.
Once we have the list of descriptors they can be used by the routine dictated to allocating memory2.
It is worth nothing tow things:
The descriptors are not ordered. Some buggy BIOS may return overlapped areas (in such case make the most conservative choice).
There may be gaps even once the descriptors are ordered. Ranges where there is no memory mapped are not reported, this is the case for the standard hole (ranging from 0a0000h to 0fffffh).
Areas explicitly reserved by the BIOS (e.g. the shadow area from 0f0000h to 0fffffh) are reported though.
In the example below the descriptors are printed on the screen along with the total amount of non reserved memory3.
By the way, you can use the itoa16
function to print a 32 bit value in EAX
, supposed you changed the the way characters are printed on the screen.
BITS 16
;Set CS to a known value
;This makes the offsets in memory and in source match
;(e.g. __START__ is at offset 5h in the binary image and at addres 7c0h:0005h)
jmp 7c0h:__START__
__START__:
;Set all the segments to CS
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor sp, sp
;Clear the screen
mov ax, 03h
int 10h
;FS will be used to write into the text buffer
push 0b800h
pop fs
;SI is the pointer in the text buffer
xor si, si
;These are for the INT 15 service
mov di, baseAddress ;Offset in ES where to save the result
xor ebx, ebx ;Start from beginning
mov ecx, 18h ;Length of the output buffer (One descriptor at a time)
;EBP will count the available memory
xor ebp, ebp
_get_memory_range:
;Set up the rest of the registers for INT 15
mov eax, 0e820h
mov edx, 534D4150h
int 15h
jc _error
;Has somethig been returned actually?
test ecx, ecx
jz _next_memory_range
;Add length (just the lower 32 bits) to EBP if type = 1 or 3
mov eax, DWORD [length]
;Avoid a branch (just for the sake of less typing)
mov edx, DWORD [type] ;EDX = 1 | 2 | 3 | 4 (1 and 3 are available memory)
and dx, 01h ;EDX = 1 | 0 | 1 | 0
dec edx ;EDX = 0 | ffffffff | 0 | ffffffff
not edx ;EDX = ffffffff | 0 | ffffffff | 0
and eax, edx ;EAX = length | 0 | length | 0
add ebp, eax
;Show current memory descriptor
call show_memory_range
_next_memory_range:
test ebx, ebx
jnz _get_memory_range
;Print empty line
push WORD strNL
call print
;Print total memory available
push ebp
push WORD strTotal
call print
cli
hlt
_error:
;Print error
push WORD strError
call print
cli
hlt
;Memory descriptor returned by INT 15
baseAddress dq 0
length dq 0
type dd 0
extAttr dd 0
;This function just show the string strFormat with the appropriate values
;taken from the mem descriptor
show_memory_range:
push bp
mov bp, sp
;Extend SP into ESP so we can use ESP in memory operanda (SP is not valid in any addressing mode)
movzx esp, sp
;Last percent
push DWORD [type]
;Last percents pair
push DWORD [length]
push DWORD [length + 04h]
;Add baseAddress and length (64 bit addition)
push DWORD [baseAddress]
mov eax, DWORD [length]
add DWORD [esp], eax ;Add (lower DWORD)
push DWORD [baseAddress + 04h]
mov eax, DWORD [length + 04h]
adc DWORD [esp], 0 ;Add with carry (higher DWORD)
;First percents pair
push DWORD [baseAddress]
push DWORD [baseAddress + 04h]
push WORD strFormat
call print
mov sp, bp ;print is a mixed stdcall/cdecl, remove the arguments
pop bp
ret
;Strings, here % denote a 32 bit argument printed as hex
strFormat db "%% - %% (%%) - %", 0
strError db "Som'thing is wrong :(", 0
strTotal db "Total amount of memory: %", 0
;This is tricky, see below
strNL db 0
;Show a 32 bit hex number
itoa16:
push cx
push ebx
mov cl, 28d
.digits:
mov ebx, eax
shr ebx, cl
and bx, 0fh ;Get current nibble
;Translate nibble (digit to digital)
mov bl, BYTE [bx + hexDigits]
;Show it
mov bh, 0ch
mov WORD [fs:si], bx
add si, 02h
sub cl, 04h
jnc .digits
pop ebx
pop cx
ret
hexDigits db "0123456789abcdef"
;This function is a primitive printf, where the only format is % to show a 32 bit
;hex number
;The "cursor" is kept by SI.
;SI is always aligned to lines, so 1) never print anything bigger than 80 chars
;2) successive calls automatically print into their own lines
;3) SI is assumed at the beginning of a line
;Args
;Format
print:
push bp
mov bp, sp
push di
push cx
mov di, WORD [bp+04h] ;String
mov cx, 80*2 ;How much to add to SI to reach the next line
add bp, 06h ;Pointer to var arg
.scan:
;Read cur char
mov al, [di]
inc di
;Format?
cmp al, '%'
jne .print
;Get current arg and advance index
mov eax, DWORD [bp]
add bp, 04h
;Show the number
call itoa16
;We printed 8 chars (16 bytes)
sub cx, 10h
jmp .scan
.print:
;End of string?
test al, al
je .end
;Normal char, print it
mov ah, 0ch
mov WORD [fs:si], ax
add si, 02h
sub cx, 02h
jmp .scan
.end:
add si, cx
pop cx
pop di
pop bp
ret 02h
;Signature
TIMES 510 - ($-$$) db 0
dw 0aa55h
In a 64MiB Bochs emulated machine, the result is
Where the format is start - end (size) - type.
Using a picture we get
The total amount of memory computed is 66.711.552 bytes or 64 MiB - 1 KiB (EBDA) - 96 KiB (Shadow area) - 288 KiB (Standard Hole).
ACPI tables are considered available as they are reclaimable.
1 Particularly of what was the part of the north bridge, now iMC, dedicated to handling the DRAM. Information about installed modules (Mostly DIMM and mobile variants) can be retrieved through SPD using either a SMBus or I2C controller.
The BIOS then consider the enabled memory mapped devices and the bus topology (along with its routing and bridging information) and exposes all this through the the SMBios specification.
2 Since it will use some sort of range descriptors anyway, eventually a format conversion is performed.
3 This count includes the newly type 5 (Bad memory) range.
Related Topics
Android Getting Exact Scroll Position in Listview
Sending Message to a Handler on a Dead Thread When Getting a Location from an Intentservice
Android Imagegetter Images Overlapping Text
Zipalign - Command Not Found - MAC Terminal
Asynctaskloader Basic Example. (Android)
Android Studio Where Is Gradle.Properties File
Fragment in Viewpager Not Restored After Popbackstack
Coordinatorlayout Using The Viewpager's Recyclerview
Android - Setting Layoutparams Programmatically
How to Access Resource with Dynamic Name in My Case
Animation for Expandablelistview
Using Espresso to Unit Test Google Maps
How to Avoid Restarting Activity When Orientation Changes on Android
Mobile Chrome Fires Resize Event on Scroll
Putting Screen Densities into The Correct Bucket