主题 : 关于字符设备mmap内存映射的问题 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 6147
精华: 0
发帖: 91
金钱: 640 两
威望: 241 点
综合积分: 182 分
注册时间: 2009-05-21
最后登录: 2011-06-23
楼主  发表于: 2010-04-07 21:49

 关于字符设备mmap内存映射的问题

各位好!
       请教大家个问题,我一个打印机驱动, 为字符设备,我现在想实现mmap将底层的内存空间,映射到用户空间,通过向用户空间写数据,底层读取数据进行打印,现在mmap实现出现了问题,我用vmlloc申请了内存,但是在申请时出现了内核oops,size大小为262080,经过页对齐,为64个PAGE
代码:
/*print buffer length*/
#define    PRINT_DATA_LEN  262080
static void *rvmalloc( unsigned long size )
{
    void *mem;
    unsigned long adr;

    size = PAGE_ALIGN(size);
    mem = vmalloc_32(size);

    if ( !mem )
        return NULL;
    memset( mem,0x0,size );
    adr = (unsigned long )mem;

    while( size > 0 )
    {
        SetPageReserved(vmalloc_to_page((void *)adr ));
        adr += PAGE_SIZE;
        size -= PAGE_SIZE;
    }
    return mem;
}

static int print_mmap(struct file *file,struct vm_area_struct *vma )
{
    unsigned long start = vma->vm_start;
    unsigned long size = vma->vm_end-vma->vm_start;
    unsigned long page,pos;

    if ( !print_stp.printbuf )
        return -ENOMEM;
    
    pos = (unsigned long)print_stp.printbuf;
    while ( size > 0 )
    {
        page = vmalloc_to_pfn((void *)pos );
        if ( remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED ))
        {
#ifdef _DEBUG_VER
            printk("print remap pfn page failed \n");
#endif
            return -EAGAIN;
        }
        start += PAGE_SIZE;
        pos += PAGE_SIZE;
        if ( size > PAGE_SIZE )
            size -= PAGE_SIZE;
        else
            size = 0;
    }
    
    return 0;
}
我将vmalloc_32尽为__get_free_pages后,问题一样存在,经过调试确认为分配内存的问题,我想问下大家,这个方法应该是可以的吧,我见内核代码中也有类似的代码,但是看见书上也有说使用nopage方法来一个一个申请PAGE,这两种方法到底哪种正确,请教下大家,下面贴出内核oops的信息
print device opening
Unable to handle kernel NULL pointer dereference at virtual address 00000025
pgd = c3b88000
[00000025] *pgd=33b6d031, *pte=00000000, *ppte=00000000
Internal error: Oops: 13 [#1]
Modules linked in: prndrv
CPU: 0    Not tainted  (2.6.30.1sunnico #277)
PC is at sys_read+0x3c/0x84
LR is at sys_read+0x20/0x84
pc : [<c0094954>]    lr : [<c0094938>]    psr: 20000013
sp : c3b67f78  ip : c3ab1600  fp : c3b67fa4
r10: 00000000  r9 : c3b66000  r8 : c0026008
r7 : 00000003  r6 : 00000001  r5 : 00000021  r4 : 00001000
r3 : c3b67f78  r2 : 00001000  r1 : bef97bb0  r0 : 00000001
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c000717f  Table: 33b88000  DAC: 00000015
Process cat (pid: 545, stack limit = 0xc3b66268)
Stack: (0xc3b67f78 to 0xc3b68000)
7f60:                                                       00000005 c0026008
7f80: c3b66000 00000000 ffffffff 00001000 bef97bb0 00000003 00000000 c3b67fa8
7fa0: c0025e60 c0094928 00001000 bef97bb0 00000003 bef97bb0 00001000 001cf944
7fc0: 00001000 bef97bb0 00000003 00000003 00000000 00000001 00000001 00000003
7fe0: 001f04c0 bef97b98 0001b8e8 00008dac 60000010 00000003 30476031 30476431
Backtrace:
[<c0094918>] (sys_read+0x0/0x84) from [<c0025e60>] (ret_fast_syscall+0x0/0x2c)
r6:00000003 r5:bef97bb0 r4:00001000
Code: e1a02004 e1a01005 e24b302c e2865020 (e8950030)
---[ end trace be2872766151f694 ]---
Unable to handle kernel NULL pointer dereference at virtual address 00000015
pgd = c3b88000
[00000015] *pgd=33b6d031, *pte=00000000, *ppte=00000000
Internal error: Oops: 13 [#2]
Modules linked in: prndrv
CPU: 0    Tainted: G      D     (2.6.30.1sunnico #277)
PC is at filp_close+0xc/0x7c
LR is at put_files_struct+0xbc/0xe0
pc : [<c0091a74>]    lr : [<c0046408>]    psr: 20000013
sp : c3b67cf8  ip : c3b67d18  fp : c3b67d14
r10: 00000000  r9 : 00000025  r8 : c3ab1600
r7 : 0000000c  r6 : c3ab1608  r5 : 00000001  r4 : 00000000
r3 : c3ab163c  r2 : c3b66000  r1 : c3ab1600  r0 : 00000001
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c000717f  Table: 33b88000  DAC: 00000015
Process cat (pid: 545, stack limit = 0xc3b66268)
Stack: (0xc3b67cf8 to 0xc3b68000)
7ce0:                                                       00000000 00000001
7d00: c3ab1608 0000000c c3b67d3c c3b67d18 c0046408 c0091a78 0000000b c0094954
7d20: c3b66000 c0094958 c383b200 bf000000 c3b67d4c c3b67d40 c0046454 c004635c
7d40: c3b67d6c c3b67d50 c0047d5c c004643c c3b66000 00000001 6151f694 be287276
7d60: c3b67d7c c3b67d70 c002a32c c00478c0 c3b67d9c c3b67d80 c002c5dc c002a164
7d80: c3b67f30 00000003 c3b67f30 c03b87a8 c3b67e34 c3b67da0 c002c890 c002c580
7da0: e8950030 00000000 c3b67e34 c3b67db8 c0025a00 c00251b8 00000010 00000021
7dc0: 00000010 00001021 00000003 00000021 00100000 c3b67f30 e8950030 00000005
7de0: 00000000 c3b67e34 00000021 c3b67e00 00000001 c02b9014 20000013 ffffffff
7e00: c016c0f8 00000029 bf000418 c3b66000 e8950030 c3b67f30 c03b87a8 c3b67f30
7e20: c3b66000 e8950030 c3b67e7c c3b67e38 c002dfd8 c002c858 c002c7c8 c005d608
7e40: c00a96f8 00000800 00000817 00000013 c3a797e0 c0396724 c3b67f64 00000013
7e60: c0396754 c3b67f30 20000013 00000025 c3b67f2c c3b67e80 c00251e4 c002df44
7e80: c3b67eac c3b67e90 c00920c0 c0091d68 00000000 c393d720 00000000 00000000
7ea0: c3b67f64 c3b67eb0 c009f0cc c009206c c3b67f7c c3b67ec0 c002c7c8 c005d608
7ec0: 00100077 00000000 00000000 00000000 c3b67f1c c0396724 00000000 00000817
7ee0: c0396794 c3b67fb0 00000001 bef97b98 c3b67fac c3b67f00 c00251e4 c002c5fc
7f00: c3883238 c3883230 ffffffff c3b67f64 00000001 00000003 c0026008 00000000
7f20: c3b67fa4 c3b67f30 c0025a00 c00251b8 00000001 bef97bb0 00001000 c3b67f78
7f40: 00001000 00000021 00000001 00000003 c0026008 c3b66000 00000000 c3b67fa4
7f60: c3ab1600 c3b67f78 c0094938 c0094954 20000013 ffffffff 00000005 c0026008
7f80: c3b66000 00000000 ffffffff 00001000 bef97bb0 00000003 00000000 c3b67fa8
7fa0: c0025e60 c0094928 00001000 bef97bb0 00000003 bef97bb0 00001000 001cf944
7fc0: 00001000 bef97bb0 00000003 00000003 00000000 00000001 00000001 00000003
7fe0: 001f04c0 bef97b98 0001b8e8 00008dac 60000010 00000003 30476031 30476431
Backtrace:
[<c0091a68>] (filp_close+0x0/0x7c) from [<c0046408>] (put_files_struct+0xbc/0xe0
)
r7:0000000c r6:c3ab1608 r5:00000001 r4:00000000
[<c004634c>] (put_files_struct+0x0/0xe0) from [<c0046454>] (exit_files+0x28/0x2c
)
[<c004642c>] (exit_files+0x0/0x2c) from [<c0047d5c>] (do_exit+0x4ac/0x620)
[<c00478b0>] (do_exit+0x0/0x620) from [<c002a32c>] (die+0x1d8/0x214)
[<c002a154>] (die+0x0/0x214) from [<c002c5dc>] (__do_kernel_fault+0x6c/0x7c)
[<c002c570>] (__do_kernel_fault+0x0/0x7c) from [<c002c890>] (do_bad_area+0x48/0x
90)
r7:c03b87a8 r6:c3b67f30 r5:00000003 r4:c3b67f30
[<c002c848>] (do_bad_area+0x0/0x90) from [<c002dfd8>] (do_alignment+0xa4/0x354)
r5:e8950030 r4:c3b66000
[<c002df34>] (do_alignment+0x0/0x354) from [<c00251e4>] (do_DataAbort+0x3c/0xa0)

[<c00251a8>] (do_DataAbort+0x0/0xa0) from [<c0025a00>] (__dabt_svc+0x40/0x60)
Exception stack(0xc3b67f30 to 0xc3b67f78)
7f20:                                     00000001 bef97bb0 00001000 c3b67f78
7f40: 00001000 00000021 00000001 00000003 c0026008 c3b66000 00000000 c3b67fa4
7f60: c3ab1600 c3b67f78 c0094938 c0094954 20000013 ffffffff
[<c0094918>] (sys_read+0x0/0x84) from [<c0025e60>] (ret_fast_syscall+0x0/0x2c)
r6:00000003 r5:bef97bb0 r4:00001000
Code: e89da800 e1a0c00d e92dd8f0 e24cb004 (e5903014)
---[ end trace be2872766151f695 ]---
Fixing recursive fault but reboot is needed!
级别: 侠客
UID: 6147
精华: 0
发帖: 91
金钱: 640 两
威望: 241 点
综合积分: 182 分
注册时间: 2009-05-21
最后登录: 2011-06-23
1楼  发表于: 2010-04-07 21:53
自己先顶下,下午思考了下,这个size可能是过大引起内核oops,但是oops信息显示出的是virtual address 0x00000025,这个低地址申请时就出现了失败