首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

ioremap内存映射 始终不能访问内存 求解,该怎么解决

2012-02-26 
ioremap内存映射 始终不能访问内存 求解ioremap内存映射,修改了数次,还是不能正常访问寄存器,基本问题是可

ioremap内存映射 始终不能访问内存 求解
ioremap内存映射,修改了数次,还是不能正常访问寄存器,基本问题是可以加载模块,但是只要lsmod就会出现段错误
unable to handle kernel paging request at virtual address 7fXXXXXX
望高手指教!!!

C/C++ code
#include <asm/io.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/irq.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <linux/device.h>#include <linux/gpio.h>static int led_major;static void *base;#define LED_CONTROLLER_BASE 0x56000050#define led_all_off    0#define led_all_on    1#define DEVICE_NAME    "zx_led"#define LED_CON (*(volatile u32*)(LED_CONTROLLER_BASE))#define LED_DAT (*(volatile u32*)(LED_CONTROLLER_BASE + 4))#define LED_UP    (*(volatile u32*)(LED_CONTROLLER_BASE + 8))#define LED_MEM_LEN    0x0cstatic int led_open(struct inode *inode,struct file *file){    printk("the led driver is open\n");    return 0;}static int led_close(struct inode *inode,struct file *file){    printk("the led driver is close\n");    return 0;}static int led_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg){    switch(cmd)    {    case led_all_off:     //iowrite16(0x00,base + 0x04);    iowrite16((ioread16(base + 0x04)&0xff)|0x0,base + 0x04);    break;    case led_all_on:    iowrite16(0x0f00,base + 0x04);    iowrite16((ioread16(base + 0x04)&0xff)|0xff00,base + 0x04);    break;    default:    return -EINVAL;    }    return 0;}static struct file_operations led_fops ={    .owner    =     THIS_MODULE,    .open    =    led_open,    .ioctl    =    led_ioctl,    .release=    led_close,};static struct class *led_class;static int led_init(void){    printk("led initialize\n");    led_major = register_chrdev(0, DEVICE_NAME, &led_fops);    if(led_major < 0)    {        printk("can't creat led_major\n");        return led_major;    }    printk("register zhengxu_led Driver OK! Major = %d\n", led_major);    led_class = class_create(THIS_MODULE,DEVICE_NAME);    if(IS_ERR(led_class))    {        printk("led_class create is failed\n");        return -1;    }    printk("class_create is ok\n");    device_create(led_class, NULL, MKDEV(led_major, 0), NULL, DEVICE_NAME);    printk("initialize is sucessful\n");    request_mem_region(LED_CONTROLLER_BASE,LED_MEM_LEN,"zx_led");    base=ioremap_nocache(LED_CONTROLLER_BASE,LED_MEM_LEN);    printk("%lx\n",base);    printk("ioremap is sucessful\n");    if(base < 0)    {        printk("ioremap is failed\n");    }//    iowrite16(0xff00,base);    iowrite16((ioread16(base)&0xff00)|0x00ff,base);//    iowrite16(0xff00,base + 0x08);    iowrite16((ioread16(base + 0x08)&0xff)|0xff00,base + 0x08);    return 0;}void led_exit(void){    unregister_chrdev(led_major,DEVICE_NAME);    device_destroy(led_class,MKDEV(led_major,0));    class_destroy(led_class);    iounmap(base);    release_mem_region(LED_CONTROLLER_BASE,LED_MEM_LEN);}module_init(led_init);module_exit(led_exit);MODULE_AUTHOR("zhengxu");MODULE_LICENSE("GPL");



[解决办法]
是可以用ioremap去映射物理内存的,不过base的类型好像是 void __iomem *啊!还有啊,最好多用printk打印程序执行到哪儿出问题了,我一般直接用ioremap。
可以这样定义后就可以直接读值和写值,就把它当做一个变量就可以了。不过你也可以直接搞成结构体类型也成。
#define ADCCON(*(volatile unsigned long *)(base_addr + 0x00))

热点排行