07. More on memory
Previous topic chore: real physical page address in Linux:
On virtual memory
A bit of OS:
- Process
- Code (and data) with isolated address space, controlled by scheduler
A process has:
- An owner (also a group owner)
- PID (also parent with it's PID)
Command to show your processes:
ps
ps -ef — to show all processes in the system, including scheduled kernel parts
Special virtual file system /proc shows a lit of info about OS and processes (also /sys is about system architecture).
/proc/<PID>/ — info about process <PID>
Actually, linux ps gets all the stuff from /proc
So back to virtual memory. Let's run a program that does nothing, but sleeps on timer:
and compile it statically with gcc -static donothing.c -o donothing.
Run a pair of such program in background:
./donothing& and again ./donothing&
Find both of them running (actually sleeping) by ps -ef (or ps -el to see in which state programs are now; predictably the only running program is ps )
list of virtual pages is available in /proc/<PID>/maps
[george@sugon src]$ cat /proc/6663/maps 00400000-0047c000 r-xp 00000000 08:11 322530 /home/george/src/donothing 0048c000-00490000 rwxp 0007c000 08:11 322530 /home/george/src/donothing 00490000-00494000 rwxp 00000000 00:00 0 005bc000-005e4000 rwxp 00000000 00:00 0 [heap] 7f7e8000-7f80c000 rwxp 00000000 00:00 0 [stack] 7fbf8000-7fbfc000 rwxp 00000000 00:00 0 7fd78000-7fd7c000 r--p 00000000 00:00 0 [vvar] 7fd7c000-7fd80000 r-xp 00000000 00:00 0 [vdso]
The program, in it's own address space can reach only addresses listed above, but not others (gets «Page fault» error)
actual memory pages with their descriptors are (not) available in /proc/<PID>/pagemap
System administrator only, because of Row_hammer security exploit
Parser of pagemap written on C
- Far more simple parser (does not notice errors):
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdint.h> 4 5 6 int main(int argc, char *argv[]) { 7 uint64_t addr, file_offset; 8 unsigned long long metadata; 9 FILE *f; 10 11 f = fopen(argv[1], "rb"); 12 sscanf(argv[2], "%llx", &addr); 13 14 file_offset = addr / getpagesize() * 8; 15 fseek(f, file_offset, SEEK_SET); 16 fread(&metadata, 8, 1, f); 17 printf("%llx\n", metadata); 18 19 return 0; 20 }
uint64_t — unsigned 64-bit int, fixed size int
fopen() — open file
fread() — read bytes from file
fseek() — move «read head» to specified position without data transfer
getpagesize() guess what
metadata is 64-bit length long long int, if it safe to read it as 8 sequential bytes?
spoiler:
So compare ./pg /proc/<PID>/pagemap 0x0048c000 for both donothing
- The're diferent
And for readonly section (0x400000) they're equal (so the same memory is used to store code of both processes!)
See filename? So kernel needs not to swap/page out this memory, because it's already on disk