标签:
一:ioremap
在内核中有关与物理地址到虚拟地址的映射全都是有mmu,统一开启,而物理地址到虚拟地址的映射关系全都存在一张对应的表格里面,这张表,在开启mmu的时候一起建好,比如在建表的时候是将物理地址0x11111111映射到44444444,那么问题就是: 比如以后我们如果要将0x11111111的地址映射到66666666地址怎么办?在内核中,通过特定的物理地址到虚拟地址的自动对应映射通过ioremap()函数来实现
1 #include <linux/init.h> 2 #include <linux/thread_info.h> 3 #include <linux/module.h> 4 #include <linux/sched.h> 5 #include <linux/errno.h> 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/slab.h> 9 #include <linux/input.h> 10 #include <linux/init.h> 11 #include <linux/serio.h> 12 #include <linux/delay.h> 13 #include <linux/clk.h> 14 #include <linux/miscdevice.h> 15 #include <linux/io.h> 16 #include <linux/ioport.h> 17 #include <asm/uaccess.h> 18 19 #include <linux/gpio.h> 20 #include <mach/gpio.h> 21 #include <plat/gpio-cfg.h> 22 23 24 MODULE_LICENSE("GPL"); 25 MODULE_AUTHOR("bunfly"); 26 27 unsigned long gpio_virt = 0; 28 29 int test_init() 30 { 31 void __iomem *p; 32 33 p = request_mem_region(0x11000000,SZ_4K,"gpio");//注册内存的映射信息 34 if(p==NULL) 35 { 36 printk("request error!\n"); 37 return 1; 38 } 39 40 gpio_virt = ioremap(0x11000000,SZ_4K); 41 //ioremap物理内存到虚拟内存映射 42 *(unsigned long *)(gpio_virt + 0x2e0) =1; 43 *(unsigned long *)(gpio_virt + 0x2e4) =0; 44 printk("hello led!\n"); 45 46 printk("phys: %p\n",virt_to_phys(gpio_virt)); 47 48 return 0; 49 } 50 51 void test_exit() 52 { 53 printk("bye bye!\n"); 54 iounmap(gpio_virt); 55 release_mem_region(0x11000000,SZ_4K); 56 //退出的时候将映射的虚拟内存取消 57 } 58 59 module_init(test_init); 60 module_exit(test_exit); 61 62 63 64
以上是通过映射的方法,把物理内存映射到虚拟内存,然后通过操作虚拟内存来点灯
内核在分配的时候,注册分配的名字,其中的注册信息可以在板子的目录下面查看:
cat /proc/iomem
注意:
在模块运行之前,为了消除内核中自带的LED模块的影响,需要将自带的LED模块:
在linux_3 下make menuconfig
在保存退出之后,重新make成zImage文件,下载到板子,运行。
二:内部watch看门狗中断
LINUX内核中断(ioremap,内部watchdog中断,外部中断)
标签:
原文地址:http://www.cnblogs.com/hongzhunzhun/p/4523957.html