小談 mmap() 與 VMA

jollen 發表於 March 16, 2007 5:38 PM

最近在 program loader 專欄裡,整理並分享了 kernel 的 ELF loader 主題;接著下來就是 dynamic linking 的議題了。在正式介紹 dynamic linking 前,先來簡單提一下「memory mapping」的觀念;近期在進行 Linux programming 的教育訓練,正好可以跟同學做個小討論。

在 IPC 的課程中提到 mapped memory 的行程間通訊機制,是透過「shared file」來做訊息的傳遞;將 shared file mapping 到 process address space 的 system call 為 'mmap()'。以下是其中一個簡單的程式範例 (mmap_write.c):

#include <stdio.h> 
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define FILE_LENGTH 0x400

int main(int argc, char *argv[])
{
   int fd;
   void *map_memory;

   /* Open a file to be mapped. */
   fd = open("/tmp/shared_file", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
   lseek(fd, FILE_LENGTH+1, SEEK_SET);
   write(fd, "", 1);
   lseek(fd, 0, SEEK_SET);

   /* Create map memory. */
   map_memory = mmap(0, FILE_LENGTH, PROT_WRITE, MAP_SHARED, fd, 0);
   close(fd);

   /* Write to mapped memory. */
   if (strlen(argv[1]) < FILE_LENGTH)
      sprintf((char *)map_memory, "%s", argv[1]);

   sleep(10);

   exit(0);
}

當程式將檔案 mapping 到自己的記憶體空間(process address space)時,mmap system call 便會建立相對應的 VMA 區段;觀念上來說,只要透過 mmap system call 將檔案 mapping 到記憶體,便會產生對應的 VMA。

修改一下範例程式,讓程式在結束前小睡 10 秒鐘,並做觀察:

# ./mmap_write hello&
[1] 14667
# cat /proc/14667/maps
08048000-08049000 r-xp 00000000 16:42 213757     /tmp/mmap_write
08049000-0804a000 rw-p 00000000 16:42 213757     /tmp/mmap_write
40000000-40015000 r-xp 00000000 16:42 12828674   /lib/ld-2.3.2.so
40015000-40016000 rw-p 00014000 16:42 12828674   /lib/ld-2.3.2.so
40016000-40017000 rw-p 00000000 00:00 0
40017000-40018000 -w-s 00000000 16:42 213753     /tmp/shared_file
42000000-4212e000 r-xp 00000000 16:42 13991938   /lib/tls/libc-2.3.2.so
4212e000-42131000 rw-p 0012e000 16:42 13991938   /lib/tls/libc-2.3.2.so
42131000-42133000 rw-p 00000000 00:00 0
bfffe000-c0000000 rwxp fffff000 00:00 0

除了 mmap system call 外,IPC 技術中的 'shared memory' 同樣也能觀察到對應的 VMA 區段。

延伸閱讀

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw