+ -
当前位置:首页 → 问答吧 → 请教一下arm linux中端口读写的方法

请教一下arm linux中端口读写的方法

时间:2005-07-10

来源:互联网

在arm上跑linux系统,现在想从arm的一IO口(此IO口是绝对空闲的)中读取数据,
假设此IO口所占的地址是0x12345,0x12346,0x12347,0x12348连续的地址.且此IO口是16位的.
我写的程序是:
(在write的入口函数中)

int error_io;

error_io=check_region(0x12345,4);

if(error_io<0)
{
return error_io;
}

request_region(0x12345,4,"ORT G");

outw(0xffff,0x12345);

...

但是运行的时候出现了错误:
Unable to handle kernel paging request at virtual address 0x12345
pgd = c3e14000
*pgd = 00000000, *pmd = 00000000
Internal error: Oops: ffffffff
CPU: 0
...
Segmentation fault

但是用cat /proc/ioports查看,得到12345-12348 : PORT G
应该是可以操作端口了,为什么还不行?
各位的任何意见我都感谢啊!      

作者: JAMESBONE   发布时间: 2005-07-10

估计是用户区和内核区的问题,弄成模块应该可以吧。      

作者: flag   发布时间: 2005-07-11

这个程序是在模块里的

struct file_operations led_fops={
owner : THIS_MODULE,
open : ledopen,
release : ledrelease,
write : ledwrite,
};


一楼所写的代码就是加在ledwrite函数里
这个驱动程序在成功insmod,成功mknod之后
在执行应用程序的时候就出现
Unable to handle kernel paging request at virtual address
......
该如何解决?      

作者: JAMESBONE   发布时间: 2005-07-11

因为你需要将0x12345-0x12348重新映射(ioremap),然后要用映射后的地址来访问。      

作者: 风雪狂客   发布时间: 2005-07-11

能够具体些吗?版主
或是提供些文档或链接让我看看      

作者: JAMESBONE   发布时间: 2005-07-11

是不是port有个偏移量0xF0000000 + (x)之类的      

作者: AIKO_sex   发布时间: 2005-07-11

谢谢各位的帮忙!
解决的方法在以下网址
http://www.linuxforum.net/forum/ ... d&Number=567374
&page=0&view=collapsed&sb=5&o=0&fpart=      

作者: JAMESBONE   发布时间: 2005-07-11

JAMESBONE看了你给的链接提供的方法,对第二个方法有点疑问,上面说:
(2)按照tdk888所介绍的,具体方法如下:
... ...
#include <asm/arch-s3c2410/S3C2410.h>
... ...

在S3C2410.h所定义的端口 = 数值 //写操作 例如:GPGDAT=0x0200
变量 = 在S3C2410.h所定义的端口 //读操作 例如:temp = GPGDAT

是不是这个也要在内核中进行(以驱动程序去访问)?而且是不是要用*((volatile unsigned long *)  (在S3C2410.h所定义的端口))去访问吧?我按照这个思路写了个去读S3C2410的ID的那个寄存器的驱动,好像不成功,能不能帮我指点一下?谢谢.
..........................
#include <asm/arch-s3c2410/S3C2410.h>

#define DEVICE_NAME        "chipid"
#define CHIPID_MAJOR 237

int matrix4_chipid_open(struct inode *inode,struct file *filp)
{
    int cpuname;

    cpuname = *((volatile unsigned long *) GSTATUS1); //GSTATUS1为有芯片ID的那个寄存器
    printk("CPUNAME is %X\n",cpuname);
   
    return 0;

}      

作者: cry126   发布时间: 2005-07-14

(1)  加上*((volatile unsigned long *)是可以的.不加这个直接用我说的方法也是可行的(参考了mizi所打patch的程序,实验也证明可行).可能不那么正统罢了
只要涉及到硬件,都只能在内核程序中访问.但有一种用户模式的虚拟机程序据说不要进入内核.

(2)你确定已经在应用程序中成功open( ),注意加上参数O_RDWR?
确定内核已经调用matrix4_chipid_open( )?如果连CPUNAME is字样那没有,证明还没有被调用到
暂时想到这么多,希望对你有提示      

作者: JAMESBONE   发布时间: 2005-07-14

今天又试了一下你说的方法,直接对S3C2410.H文件中定义的寄存器操作,可以读到芯片ID,但是用*((volatile unsigned long *)就不行,得到下面的结果:
I want to get cpuname
Unable to handle kernel paging request at virtual address 32410000
pgd = c3c70000
*pgd = 00000000, *pmd = 00000000
Internal error: Oops: 0
CPU: 0
pc : [<c4840080>]    lr : [<c0028e60>]    Tainted: P
sp : c3c75ed8  ip : c3c75e90  fp : c3c75ee4
r10: 40139280  r9 : c3c74000  r8 : c016c2e8
r7 : c3d5e3a8  r6 : c3d5ddc0  r5 : 00000000  r4 : c3d5fb80
r3 : 32410000  r2 : 00000001  r1 : 00000001  r0 : c484016c
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C000317F  Table: 33C70000  DAC: 00000015
Process myl (pid: 60, stackpage=c3c75000)
Stack: (0xc3c75ec8 to 0xc3c76000)
5ec0:                   c0028e60 c4840080 60000013 ffffffff c3c75f00 c3c75ee8
5ee0: c004940c c4840070 c3d5fb80 c3d5e3a0 c3d5ddc0 c3c75f30 c3c75f04 c007cdfc
5f00: c00493c8 c3c75f20 c3c75f14 c0052e10 c3d5ddc0 c3d5fb80 00000000 c02ff360
5f20: c3d70c20 c3c75f54 c3c75f34 c0047ff0 c007cd08 00000000 00000000 bffffebc
5f40: c03d4000 c001a804 c3c75f84 c3c75f58 c0047ee8 c0047efc c3d70c20 c02ff360
5f60: c0052be8 c003ff50 c03d4000 00000001 00000001 00000003 c3c75fa4 c3c75f88
5f80: c0048244 c0047eac 40020c34 bffffeb4 000082ec 00000005 00000000 c3c75fa8
5fa0: c001a680 c0048210 40020c34 c00207ac 0000856c 00000000 bffffebc 00000000
5fc0: 40020c34 bffffeb4 000082ec 4000ee5c 00000001 00008470 40139280 bffffe94
5fe0: 400e1240 bffffe7c 0000848c 400e1244 60000010 0000856c f9ffffff ffffbfff
Backtrace:
Function entered at [<c4840060>] from [<c004940c>]
Function entered at [<c00493b8>] from [<c007cdfc>]
r6 = C3D5DDC0  r5 = C3D5E3A0  r4 = C3D5FB80
Function entered at [<c007ccf8>] from [<c0047ff0>]
r8 = C3D70C20  r7 = C02FF360  r6 = 00000000  r5 = C3D5FB80
r4 = C3D5DDC0
Function entered at [<c0047eec>] from [<c0047ee8>]
r8 = C001A804  r7 = C03D4000  r6 = BFFFFEBC  r5 = 00000000
r4 = 00000000
Function entered at [<c0047e9c>] from [<c0048244>]
r4 = 00000003
Function entered at [<c0048200>] from [<c001a680>]
r7 = 00000005  r6 = 000082EC  r5 = BFFFFEB4  r4 = 40020C34
Code: eb000072 e3a034f6 e59330b0 e59f0010 (e5931000)
Segmentation fault

JAMESBONE能不能帮忙分析一下原因?      

作者: cry126   发布时间: 2005-07-15

我想是不是用了*((volatile unsigned long *) 就是把寄存器GSTATUS1里的内容作为地址去访问了的原因?      

作者: cry126   发布时间: 2005-07-15

[QUOTE=cry126]我想是不是用了*((volatile unsigned long *) 就是把寄存器GSTATUS1里的内容作为地址去访问了的原因?[/QUOTE]
我也是这么认为      

作者: AIKO_sex   发布时间: 2005-07-16

又试了另外一种方法,可以用ioremap()函数,在内核中对地址映射.      

作者: cry126   发布时间: 2005-07-18

我现在正写一个驱动程序,也遇到了地址映射的问题,查找JAMESBONE提供的网址“http://www.linuxforum.net/forum/ ... 鎏?犹?隼矗?恍唬

作者: newabc   发布时间: 2005-12-25

我现在正写一个驱动程序,也遇到了地址映射的问题,查找JAMESBONE提供的网址"http://www.linuxforum.net/forum/sho...d&Number=567374",但linuxforum正在维护不能访问,其它帖子也没指出有关函数定义的头文件,比如s3c2410.h或S3C2410.h有好几个,不知道该用哪个。各位大侠能不能再指点一二,或者把那个帖子帖出来,谢谢!      

作者: newabc   发布时间: 2005-12-25

我在做键盘驱动时遇到Unable to handle kernel paging request at virtual address 问题

请各位大虾看看!我邮箱:[email protected]
  我用nGCS4块地址(0x20800000)做回读信号地址

#define S3C2410_KEYBOARD_DATA            ((0x20800000)+0)

static struct unit keyboard_unit = {
        .GPA_CON                = (u32 *)S3C2410_GPACON,
        .GPB_CON                = (u32 *)S3C2410_GPBCON,
        .GPB_DAT                = (u32 *)S3C2410_GPBDAT,
        .GPB_UP                        = (u32 *)S3C2410_GPBUP,
       
        .f                                = (UINT8T *) S3C2410_KEYBOARD_DATA       
};

在 return *keyboard_unit.f;//0x20800000 读键盘返回
出现以下错误:

/etc/var # ./keyboard_test[2] -aa
Unable to handle kernel paging request at virtual address 20800000
pgd = c3e38000
*pgd = 00000000, *pmd = 00000000
Internal error: Oops: 0
CPU: 0
pc : [<c4880100>]    lr : [<c0028314>]    Not tainted
sp : c3e3ff48  ip : c3e3ff00  fp : c3e3ffa4
r10: 00000002  r9 : c3e3e000  r8 : bffffe68
r7 : c4880658  r6 : 00000000  r5 : 00000000  r4 : c4880788
r3 : c4880788  r2 : 20800000  r1 : 00000001  r0 : 0000001a
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C000317F  Table: 33E38000  DAC: 00000015
Process keyboard_test[2 (pid: 58, stackpage=c3e3f000)
Stack: (0xc3e3ff38 to 0xc3e40000)
ff20:                                                       c0028314 c4880100
ff40: 60000013 ffffffff c4880188 c4880788 c0356f20 ffffffea c4880788 c4880254
ff60: bffffe68 c48802a8 00000000 c0356f20 ffffffea 00000000 c00485b8 c3e3ff88
ff80: c0047f8c 00000003 bffffe68 000085f4 00000003 c001b7c4 00000000 c3e3ffa8
ffa0: c001b640 c00484ec 00000003 c002193c 00000003 bffffe68 00000000 00000000
ffc0: 00000003 bffffe68 000085f4 0001066c bffffeb4 00008470 00000002 bffffea8
ffe0: 40092f20 bffffe68 000084e4 40092f24 60000010 00000003 00000000 30002001
Backtrace:
Function entered at [<c00484dc>] from [<c001b640>]
r8 = C001B7C4  r7 = 00000003  r6 = 000085F4  r5 = BFFFFE68
r4 = 00000003
Code: e59f0010 eb000237 e59f300c e5932024 (e5d20000)
Segmentation fault      

作者: gaoghp   发布时间: 2006-05-30

可能是内核与用户空间的问题。      

作者: flag   发布时间: 2006-05-30