應對大文件讀寫,采用mmap內存映射可以減少IO訪問,提高讀寫效率。
int open(const char *pathname, int flags); void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int msync(void *addr, size_t length, int flags); int munmap(void *addr, size_t length); int close(int fd);
實際測試中出現Bus error錯誤
Bus error (core dumped)
使用valgrind 調試工具
valgrind ./pack_tool pack AirFly.fw kernel.img rootfs.img ==4308== Memcheck, a memory error detector ==4308== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==4308== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==4308== Command: ./pack_tool pack AirFly.fw kernel.img rootfs.img ==4308== ========ota_fw_name:[AirFly.fw]====== ==4308== ==4308== Process terminating with default action of signal 7 (SIGBUS) ==4308== Non-existent physical address at address 0x4027000 ==4308== at 0x401AF8: pack_fw (in /home/liuxueneng/code_exercise/ota_tool/fw_file/pack_tool) ==4308== by 0x4021D0: main (in /home/liuxueneng/code_exercise/ota_tool/fw_file/pack_tool) ==4308== ==4308== HEAP SUMMARY: ==4308== in use at exit: 0 bytes in 0 blocks ==4308== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ==4308== ==4308== All heap blocks were freed -- no leaks are possible ==4308== ==4308== For counts of detected and suppressed errors, rerun with: -v ==4308== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Bus error (core dumped)
查看man mmap的說明 有關SIGBUS有如下解釋
ERRORS EACCES A file descriptor refers to a non-regular file. Or a file mapping was requested, but fd is not open for reading. Or MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode. Or PROT_WRITE is set, but the file is append-only. EAGAIN The file has been locked, or too much memory has been locked (see setrlimit(2)). EBADF fd is not a valid file descriptor (and MAP_ANONYMOUS was not set). EINVAL We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary). EINVAL (since Linux 2.6.12) length was 0. EINVAL flags contained neither MAP_PRIVATE or MAP_SHARED, or contained both of these values. ENFILE The system-wide limit on the total number of open files has been reached. ENODEV The underlying filesystem of the specified file does not support memory mapping. ENOMEM No memory is available. ENOMEM The process's maximum number of mappings would have been exceeded. This error can also occur for munmap(2), when unmapping a region in the middle of an existing mapping, since this results in two smaller mappings on either side of the region being unmapped. EPERM The prot argument asks for PROT_EXEC but the mapped area belongs to a file on a filesystem that was mounted no-exec. EPERM The operation was prevented by a file seal; see fcntl(2). ETXTBSY MAP_DENYWRITE was set but the object specified by fd is open for writing. EOVERFLOW On 32-bit architecture together with the large file extension (i.e., using 64-bit off_t): the number of pages used for length plus number of pages used for offset would overflow unsigned long (32 bits). Use of a mapped region can result in these signals: SIGSEGV Attempted write into a region mapped as read-only. SIGBUS Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).
出現Bus error (core dumped)錯誤
出現了SIBUS錯誤,原因是beyond the end of the file ,因為新建的文件的size實際是0,必須先ftruncate大於將要寫入文件中大小的size,然后調用mmap進行映射,后開始訪問內存寫入數據。
int ftruncate(int fd, off_t length);