C 对于大型缓冲区,mmap失败

C 对于大型缓冲区,mmap失败,c,linux,linux-kernel,linux-device-driver,C,Linux,Linux Kernel,Linux Device Driver,我试图做一个简单的mmap驱动程序,涵盖了最基本的内容。更像是一个简单的示例驱动程序。但是我试图使用通过kzalloc分配的一大块内存(102页四舍五入到100页)。我不明白为什么我的mmap无法从用户空间访问页面。为什么我不能访问超过10-14页的内容?我们的司机必须手动处理页面错误吗 地图开发c 所以,我认为你担心的printk是: [ 7782.754711] i= 0 : Reserved: 18446719884479594496 dmem: 0x62a00000 [ 778

我试图做一个简单的mmap驱动程序,涵盖了最基本的内容。更像是一个简单的示例驱动程序。但是我试图使用通过kzalloc分配的一大块内存(102页四舍五入到100页)。我不明白为什么我的mmap无法从用户空间访问页面。为什么我不能访问超过10-14页的内容?我们的司机必须手动处理页面错误吗

地图开发c 所以,我认为你担心的printk是:

[ 7782.754711] i= 0     : Reserved: 18446719884479594496 dmem: 0x62a00000 
[ 7782.754714] i= 4096  : Reserved: 18446719884479594560 dmem: 0x62a00000
来自这里:

for(i = 0; i < NPAGES * PAGE_SIZE; i += PAGE_SIZE)
    printk("i= %d \t: Reserved: %lu dmem: 0x%x \n",
        i,
        (unsigned long)(virt_to_page(((unsigned long)dmem_area) + i)),
        (unsigned int)((unsigned long) dmem_area));
for(i=0;i
因为
i
每次增加4096,但是页面帧号(从
virt\u到
页面)不是。如果查看
virt\u to\u page
的定义,您将看到它将虚拟地址参数转换为物理地址,然后将其向右移位
page\u SHIFT
位。因此,您记录的PFN必须增加小于
i

您的系统上的
PAGE\u SHIFT
是什么?如果是
6
,则
4096>>6==64
,并解释您的混淆


这就是你在评论中提到的问题。你最初的问题是

我不明白为什么我的mmap无法从用户空间访问页面。为什么我不能访问超过10-14页的内容

但你还没说症状是什么。当您尝试访问第15页时,会发生什么情况

在用户空间中,您将以int的形式访问它。因此,您将一次访问4个字节,因此您必须为此调整for循环。
此外,您获得的地址是页面帧编号。不是完整的字节地址。

您的
printk
s是否起火?他们展示了什么?在您调用
mmap
失败后,
errno
是什么?我得到了打印码。内核转储了相隔64字节的地址。它们实际上应该相隔4096字节。我很困惑。什么地址相隔64字节?请显示实际输出如何在此处添加文件?您不能编辑您的问题吗?如果没有,请链接到pastebin或其他东西,有人会为您编辑它。我认为您在这一点上是正确的。但我在我的应用程序中也犯了一个错误。我分配了100个字节的页面。但要用语言表达。所以我会得到一点少于25%的文字。当我将int*mm\u addr更改为char*mm\u addr时,我几乎可以访问所有内存。但是返回的地址仍然有一些混乱。Kzalloc应该返回物理上连续的内存。在打印之前,我也在做一个从一页到另一页的翻译。那么,我真的不应该从一个页面对齐的地址开始获得连续的页面地址吗?你是在告诉我地址中有一些低位没有显示出来吗。只给我页面地址,但是对于32位系统,页面移位必须是11。是的,virt-to-page给出的是页面帧号,而不是地址。你是想用virt_to_phys吗?我想它会给出页面第一个字节的地址。现在我明白了。
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>

#define NPAGES  100
int main(void)
{
    int len = NPAGES * getpagesize();
    unsigned int *mm_addr;
    printf("page size = %d\n", getpagesize());
    printf("length = %d", len);
    int fd = open("/dev/mmap_dev", O_RDWR);
    getc(stdin);
    printf("Opening file...\n");
    printf("mmap ...\n");
    mm_addr = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0);
    if(mm_addr == MAP_FAILED) {
        printf("mmap failed\n");
        perror("mmap");
        exit(-1);
    }
    printf("mmap complete. \n");
    getc(stdin);
    printf("data @[0] : 0x%x\n", mm_addr[0]);
    close(fd);
    #if 1
    printf("um-mmap ...\n");
    munmap(mm_addr, len);
    printf("umap... done\n");
    #endif
    return 0;
}
[ 7782.754615] map_dev_open: open
[ 7782.754703] map_dev_open: PAGE_SIZE = 4096
[ 7782.754706] map_dev_open: dmem = 18446719884479594496
[ 7782.754711] i= 0     : Reserved: 18446719884479594496 dmem: 0x62a00000 
[ 7782.754714] i= 4096  : Reserved: 18446719884479594560 dmem: 0x62a00000 
[ 7782.754716] i= 8192  : Reserved: 18446719884479594624 dmem: 0x62a00000 
[ 7782.754719] i= 12288     : Reserved: 18446719884479594688 dmem: 0x62a00000 
[ 7782.754722] i= 16384     : Reserved: 18446719884479594752 dmem: 0x62a00000 
[ 7782.754725] i= 20480     : Reserved: 18446719884479594816 dmem: 0x62a00000 
[ 7782.754728] i= 24576     : Reserved: 18446719884479594880 dmem: 0x62a00000 
[ 7782.754731] i= 28672     : Reserved: 18446719884479594944 dmem: 0x62a00000 
[ 7782.754734] i= 32768     : Reserved: 18446719884479595008 dmem: 0x62a00000 
[ 7782.754736] i= 36864     : Reserved: 18446719884479595072 dmem: 0x62a00000 
[ 7782.754739] i= 40960     : Reserved: 18446719884479595136 dmem: 0x62a00000 
[ 7782.754742] i= 45056     : Reserved: 18446719884479595200 dmem: 0x62a00000 
[ 7782.754745] i= 49152     : Reserved: 18446719884479595264 dmem: 0x62a00000 
[ 7782.754748] i= 53248     : Reserved: 18446719884479595328 dmem: 0x62a00000 
[ 7782.754751] i= 57344     : Reserved: 18446719884479595392 dmem: 0x62a00000 
[ 7782.754753] i= 61440     : Reserved: 18446719884479595456 dmem: 0x62a00000 
[ 7782.754756] i= 65536     : Reserved: 18446719884479595520 dmem: 0x62a00000 
[ 7782.754759] i= 69632     : Reserved: 18446719884479595584 dmem: 0x62a00000 
[ 7782.754762] i= 73728     : Reserved: 18446719884479595648 dmem: 0x62a00000 
[ 7782.754765] i= 77824     : Reserved: 18446719884479595712 dmem: 0x62a00000 
[ 7782.754768] i= 81920     : Reserved: 18446719884479595776 dmem: 0x62a00000 
[ 7782.754770] i= 86016     : Reserved: 18446719884479595840 dmem: 0x62a00000 
[ 7782.754773] i= 90112     : Reserved: 18446719884479595904 dmem: 0x62a00000 
[ 7782.754776] i= 94208     : Reserved: 18446719884479595968 dmem: 0x62a00000 
[ 7782.754779] i= 98304     : Reserved: 18446719884479596032 dmem: 0x62a00000 
[ 7782.754782] i= 102400    : Reserved: 18446719884479596096 dmem: 0x62a00000 
[ 7782.754784] i= 106496    : Reserved: 18446719884479596160 dmem: 0x62a00000 
[ 7782.754787] i= 110592    : Reserved: 18446719884479596224 dmem: 0x62a00000 
[ 7782.754790] i= 114688    : Reserved: 18446719884479596288 dmem: 0x62a00000 
[ 7782.754793] i= 118784    : Reserved: 18446719884479596352 dmem: 0x62a00000 
[ 7782.754796] i= 122880    : Reserved: 18446719884479596416 dmem: 0x62a00000 
[ 7782.754798] i= 126976    : Reserved: 18446719884479596480 dmem: 0x62a00000 
[ 7782.754801] i= 131072    : Reserved: 18446719884479596544 dmem: 0x62a00000 
[ 7782.754804] i= 135168    : Reserved: 18446719884479596608 dmem: 0x62a00000 
[ 7782.754807] i= 139264    : Reserved: 18446719884479596672 dmem: 0x62a00000 
[ 7782.754810] i= 143360    : Reserved: 18446719884479596736 dmem: 0x62a00000 
[ 7782.754812] i= 147456    : Reserved: 18446719884479596800 dmem: 0x62a00000 
[ 7782.754815] i= 151552    : Reserved: 18446719884479596864 dmem: 0x62a00000 
[ 7782.754818] i= 155648    : Reserved: 18446719884479596928 dmem: 0x62a00000 
[ 7782.754821] i= 159744    : Reserved: 18446719884479596992 dmem: 0x62a00000 
[ 7782.754824] i= 163840    : Reserved: 18446719884479597056 dmem: 0x62a00000 
[ 7782.754826] i= 167936    : Reserved: 18446719884479597120 dmem: 0x62a00000 
[ 7782.754829] i= 172032    : Reserved: 18446719884479597184 dmem: 0x62a00000 
[ 7782.754832] i= 176128    : Reserved: 18446719884479597248 dmem: 0x62a00000 
[ 7782.754835] i= 180224    : Reserved: 18446719884479597312 dmem: 0x62a00000 
[ 7782.754837] i= 184320    : Reserved: 18446719884479597376 dmem: 0x62a00000 
[ 7782.754840] i= 188416    : Reserved: 18446719884479597440 dmem: 0x62a00000 
[ 7782.754843] i= 192512    : Reserved: 18446719884479597504 dmem: 0x62a00000 
[ 7782.754846] i= 196608    : Reserved: 18446719884479597568 dmem: 0x62a00000 
[ 7782.754849] i= 200704    : Reserved: 18446719884479597632 dmem: 0x62a00000 
[ 7782.754851] i= 204800    : Reserved: 18446719884479597696 dmem: 0x62a00000 
[ 7782.754854] i= 208896    : Reserved: 18446719884479597760 dmem: 0x62a00000 
[ 7782.754857] i= 212992    : Reserved: 18446719884479597824 dmem: 0x62a00000 
[ 7782.754860] i= 217088    : Reserved: 18446719884479597888 dmem: 0x62a00000 
[ 7782.754863] i= 221184    : Reserved: 18446719884479597952 dmem: 0x62a00000 
[ 7782.754865] i= 225280    : Reserved: 18446719884479598016 dmem: 0x62a00000 
[ 7782.754868] i= 229376    : Reserved: 18446719884479598080 dmem: 0x62a00000 
[ 7782.754871] i= 233472    : Reserved: 18446719884479598144 dmem: 0x62a00000 
[ 7782.754874] i= 237568    : Reserved: 18446719884479598208 dmem: 0x62a00000 
[ 7782.754877] i= 241664    : Reserved: 18446719884479598272 dmem: 0x62a00000 
[ 7782.754879] i= 245760    : Reserved: 18446719884479598336 dmem: 0x62a00000 
[ 7782.754882] i= 249856    : Reserved: 18446719884479598400 dmem: 0x62a00000 
[ 7782.754885] i= 253952    : Reserved: 18446719884479598464 dmem: 0x62a00000 
[ 7782.754888] i= 258048    : Reserved: 18446719884479598528 dmem: 0x62a00000 
[ 7782.754891] i= 262144    : Reserved: 18446719884479598592 dmem: 0x62a00000 
[ 7782.754893] i= 266240    : Reserved: 18446719884479598656 dmem: 0x62a00000 
[ 7782.754896] i= 270336    : Reserved: 18446719884479598720 dmem: 0x62a00000 
[ 7782.754899] i= 274432    : Reserved: 18446719884479598784 dmem: 0x62a00000 
[ 7782.754902] i= 278528    : Reserved: 18446719884479598848 dmem: 0x62a00000 
[ 7782.754905] i= 282624    : Reserved: 18446719884479598912 dmem: 0x62a00000 
[ 7782.754908] i= 286720    : Reserved: 18446719884479598976 dmem: 0x62a00000 
[ 7782.754910] i= 290816    : Reserved: 18446719884479599040 dmem: 0x62a00000 
[ 7782.754913] i= 294912    : Reserved: 18446719884479599104 dmem: 0x62a00000 
[ 7782.754916] i= 299008    : Reserved: 18446719884479599168 dmem: 0x62a00000 
[ 7782.754919] i= 303104    : Reserved: 18446719884479599232 dmem: 0x62a00000 
[ 7782.754922] i= 307200    : Reserved: 18446719884479599296 dmem: 0x62a00000 
[ 7782.754924] i= 311296    : Reserved: 18446719884479599360 dmem: 0x62a00000 
[ 7782.754927] i= 315392    : Reserved: 18446719884479599424 dmem: 0x62a00000 
[ 7782.754930] i= 319488    : Reserved: 18446719884479599488 dmem: 0x62a00000 
[ 7782.754933] i= 323584    : Reserved: 18446719884479599552 dmem: 0x62a00000 
[ 7782.754936] i= 327680    : Reserved: 18446719884479599616 dmem: 0x62a00000 
[ 7782.754938] i= 331776    : Reserved: 18446719884479599680 dmem: 0x62a00000 
[ 7782.754941] i= 335872    : Reserved: 18446719884479599744 dmem: 0x62a00000 
[ 7782.754944] i= 339968    : Reserved: 18446719884479599808 dmem: 0x62a00000 
[ 7782.754947] i= 344064    : Reserved: 18446719884479599872 dmem: 0x62a00000 
[ 7782.754950] i= 348160    : Reserved: 18446719884479599936 dmem: 0x62a00000 
[ 7782.754952] i= 352256    : Reserved: 18446719884479600000 dmem: 0x62a00000 
[ 7782.754955] i= 356352    : Reserved: 18446719884479600064 dmem: 0x62a00000 
[ 7782.754958] i= 360448    : Reserved: 18446719884479600128 dmem: 0x62a00000 
[ 7782.754961] i= 364544    : Reserved: 18446719884479600192 dmem: 0x62a00000 
[ 7782.754963] i= 368640    : Reserved: 18446719884479600256 dmem: 0x62a00000 
[ 7782.754966] i= 372736    : Reserved: 18446719884479600320 dmem: 0x62a00000 
[ 7782.754969] i= 376832    : Reserved: 18446719884479600384 dmem: 0x62a00000 
[ 7782.754972] i= 380928    : Reserved: 18446719884479600448 dmem: 0x62a00000 
[ 7782.754975] i= 385024    : Reserved: 18446719884479600512 dmem: 0x62a00000 
[ 7782.754977] i= 389120    : Reserved: 18446719884479600576 dmem: 0x62a00000 
[ 7782.754980] i= 393216    : Reserved: 18446719884479600640 dmem: 0x62a00000 
[ 7782.754983] i= 397312    : Reserved: 18446719884479600704 dmem: 0x62a00000 
[ 7782.754986] i= 401408    : Reserved: 18446719884479600768 dmem: 0x62a00000 
[ 7782.754989] i= 405504    : Reserved: 18446719884479600832 dmem: 0x62a00000 
[ 8304.656599] systemd-hostnamed[6482]: Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!
[ 8407.896365] BUG: Bad page state: 40 messages suppressed
[ 8407.896373] BUG: Bad page state in process a.out  pfn:62a00
[ 8407.896379] page:ffffea00018a8000 count:0 mapcount:0 mapping:          (null) index:0x0
[ 8407.896381] page flags: 0x1ffff0000004400(reserved|head)
[ 8407.896388] Modules linked in: map_dev(OF) map_device(OF) rfcomm bnep binfmt_misc arc4 brcmsmac cordic brcmutil btusb intel_powerclamp b43 bluetooth coretemp kvm_intel kvm mac80211 i915 crct10dif_pclmul crc32_pclmul snd_hda_codec_hdmi cfg80211 snd_hda_codec_realtek uvcvideo snd_hda_intel ssb snd_hda_codec ghash_clmulni_intel drm_kms_helper snd_hwdep aesni_intel snd_pcm videobuf2_vmalloc snd_page_alloc aes_x86_64 drm acer_wmi videobuf2_memops lrw snd_seq_midi i2c_algo_bit gf128mul parport_pc glue_helper snd_seq_midi_event sparse_keymap ppdev videobuf2_core ablk_helper snd_rawmidi cryptd joydev videodev serio_raw lp bcma snd_seq wmi mei_me mei snd_seq_device snd_timer snd intel_ips soundcore mac_hid lpc_ich video parport psmouse tg3 ahci ptp libahci pps_core [last unloaded: map_dev]
[ 8407.896482] CPU: 1 PID: 6444 Comm: a.out Tainted: GF   B      O 3.13.0-27-generic #50-Ubuntu
[ 8407.896485] Hardware name: Acer            TravelMate 4740                /TravelMate 4740                , BIOS V1.12           05/04/2010
[ 7782.754711] i= 0     : Reserved: 18446719884479594496 dmem: 0x62a00000 
[ 7782.754714] i= 4096  : Reserved: 18446719884479594560 dmem: 0x62a00000
for(i = 0; i < NPAGES * PAGE_SIZE; i += PAGE_SIZE)
    printk("i= %d \t: Reserved: %lu dmem: 0x%x \n",
        i,
        (unsigned long)(virt_to_page(((unsigned long)dmem_area) + i)),
        (unsigned int)((unsigned long) dmem_area));