That only lists usable memory that is not taken by any other device. Not total memory of system.
Maybe memory goes to gpu or some IO mapped range. IO peripherals need to use some memory range for their own purposes.
You can look at dmesg output (kernel messages) to see how it assigns memory - it will list there exactly which address are available and which are not. Here's example how it looks on my ArchLinux, it shows various regions which are reserved and not usable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | [ +0.000000] BIOS-provided physical RAM map:
[ +0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009dfff] usable
[ +0.000000] BIOS-e820: [mem 0x000000000009e000-0x000000000009efff] reserved
[ +0.000000] BIOS-e820: [mem 0x000000000009f000-0x000000000009ffff] usable
[ +0.000000] BIOS-e820: [mem 0x00000000000a0000-0x00000000000fffff] reserved
[ +0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003fffffff] usable
[ +0.000000] BIOS-e820: [mem 0x0000000040000000-0x00000000403fffff] reserved
[ +0.000000] BIOS-e820: [mem 0x0000000040400000-0x000000008b918fff] usable
[ +0.000000] BIOS-e820: [mem 0x000000008b919000-0x000000008b919fff] ACPI NVS
[ +0.000000] BIOS-e820: [mem 0x000000008b91a000-0x000000008b93ffff] usable
[ +0.000000] BIOS-e820: [mem 0x000000008b940000-0x000000008b940fff] reserved
[ +0.000000] BIOS-e820: [mem 0x000000008b941000-0x000000008ba7ffff] usable
[ +0.000000] BIOS-e820: [mem 0x000000008ba80000-0x000000008d2ebfff] reserved
[ +0.000000] BIOS-e820: [mem 0x000000008d2ec000-0x000000008d368fff] ACPI data
[ +0.000000] BIOS-e820: [mem 0x000000008d369000-0x000000008d841fff] ACPI NVS
[ +0.000000] BIOS-e820: [mem 0x000000008d842000-0x000000008dffefff] reserved
[ +0.000000] BIOS-e820: [mem 0x000000008dfff000-0x000000008dffffff] usable
[ +0.000000] BIOS-e820: [mem 0x000000008e000000-0x000000009f7fffff] reserved
[ +0.000000] BIOS-e820: [mem 0x00000000e0000000-0x00000000efffffff] reserved
[ +0.000000] BIOS-e820: [mem 0x00000000fe000000-0x00000000fe010fff] reserved
[ +0.000000] BIOS-e820: [mem 0x00000000fec00000-0x00000000fec00fff] reserved
[ +0.000000] BIOS-e820: [mem 0x00000000fee00000-0x00000000fee00fff] reserved
[ +0.000000] BIOS-e820: [mem 0x00000000ff000000-0x00000000ffffffff] reserved
[ +0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000205f7fffff] usable
|
There are usually more messages listing more details. And also it shows exactly numbers it can use:
| [ +0.251604] Memory: 131464188K/133871732K available (14344K kernel code, 2032K rwdata, 8900K rodata, 1720K init, 4316K bss, 2407284K reserved, 0K cma-reserved)
|
It says here that it has 2.2GB of some reserved memory for me.
To get actual real hardware memory installed in system you can read DMI tables from BIOS. On linux commandline you can do that with
sudo dmidecode -t 17. dmidecode utility source is available, you can check it for details if you want to implement same functionality.