mmap() 과 memcpy()의 대한 질문드립니다.
글쓴이: hypnosis / 작성시간: 수, 2019/04/03 - 10:40오전
mmap() 으로 파일을 메모리매핑 시켜 매핑된 메모리를 변수에 memcpy() 시키는 함수를 만들었습니다.
헌데, 물리적인 서버(pc) 리눅스(redhat 계열)에서 실행 하면 /sys/devices/pci0000:xx 하위 파일 중에
resource0 ~ 4 들이 매핑후 copy 하게 되면 kernel panic 과 같은 현상이 나타납니다. (검은 화면으로 변하거나 REBOOT)
resource 명을 가진 파일들은 물리적인 서버에서 확인해보면 입출력에러(errno 5) 나오는 파일들입니다.
mmap 으로 해당 파일들을 매핑시, map_failed 가 떨어지지 않고, 넘어가는것도 이해가 안됩니다.
읽어들일수 없는 파일이면 매핑도 안되야되는게 정상일 것 같은데..
아래는 간단하게 실행할수 있도록 예제 코드 작성해본 것이고, 혹시 소스 코드가 잘되었거나
/sys/devices/pci0000:xx 밑에 있는 파일들을 컨트롤 할때는 이와 같은 방법으로 하면 안되는 것인지..
경험 이나 지식을 가지고 계신 분이 계시다면.. 알려주시면 감사하겠습니다.. 너무 궁금하네요 ㅠㅠ
#include "errno.h" #include "fcntl.h" #include "unistd.h" #include "stdio.h" #include "stdlib.h" #include "string.h" #include "stddef.h" #include "sys/types.h" #include "sys/mman.h" #include "dirent.h" int recursive_dir(char *dir); int exec_file(char *file); main(void) { // error recursive_dir((char *)"/sys/devices"); // not error // recursive_dir((char *)"/tmp"); } int recursive_dir(char *dir) { DIR *pdir = NULL; char file[1024]; struct stat f_stat; struct dirent entry, *result = NULL; if ( (pdir = opendir(dir)) == NULL) { printf("opendir(%s) fail.\n", dir); return -1; } while (readdir_r(pdir, &entry, &result) == 0 && result != NULL) { if (entry.d_ino == 0) { printf("[scan_dir] entry [%s].d_ino is 0. continue\n", entry.d_name); continue; } if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) { continue; } if (strcmp(dir, "/") == 0) { snprintf(file, sizeof(file), "/%s", entry.d_name); } else { snprintf(file, sizeof(file), "%s/%s", dir, entry.d_name); } if (lstat(file, &f_stat) == -1) { continue; } if (S_ISLNK(f_stat.st_mode)) { printf("[%s] is symbolic link. continue\n", file); continue; } else if (S_ISDIR(f_stat.st_mode)) { recursive_dir(file); } else if (S_ISREG(f_stat.st_mode)) { exec_file(file); } } closedir(pdir); return 0; } int exec_file(char *file) { int my_offset = 0; char data[101] = {0,}; int fd; int len; void *address; struct stat f_stat; // occurrence error file //if ((fd = open("/sys/devices/pci0000:00/0000:00:1b.0/resource0", O_RDONLY)) == -1) { if ((fd = open(file, O_RDONLY)) == -1) { return -1; } if (lstat(file, &f_stat) == -1) { close(fd); return -1; } if ((len = f_stat.st_size) == 0) { close(fd); return -1; } printf("file [%s] size [%d]\n", file, len); my_offset = 0; memset(data, 0x00, sizeof(data)); address = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, my_offset); if ( address != MAP_FAILED ) { memcpy(data, address, 100); /* copy memory */ } munmap(address, len); close(fd); return 0; }
Forums:
댓글 달기