2440--linux2.6.30.4的的虚拟地址和物理地址的关系

1

想一次修改某个目录下所有文件的权限,包括子目录中的文件权限也要修改,要使用参数-R表示启动递归处理。

刚开始学字符设备驱动,感觉最难的是驱动和底层硬件的连接。linux上的驱动程序,是基于操作系统之上的,他并不直接和底层的硬件打交道,但是我们写的驱动必须能使硬件“跑”起来,即与硬件紧密相连。

就拿最简单的LED驱动来说,我们的驱动程序是在虚拟的内存上面跑的,但是最终,LED的点亮还是必须靠GPIO管脚的高低电平来控制。那么,我们的虚拟的内存怎么才能和实际的硬件上面的寄存器对应起来呢?

这篇要写的就是ioremap这个映射函数,他可以将我们硬件上面的寄存器,映射为虚拟的内存,从而使驱动程序在我们的虚拟的内存中运行。

#include <linux/module.h>

#include <linux/device.h>

#include <linux/types.h>

#include <linux/fs.h>

#include <linux/errno.h>

#include <linux/mm.h>

#include <linux/sched.h>

#include <linux/init.h>

#include <linux/cdev.h>

#include <asm/io.h>

#include <asm/system.h>

#include <asm/uaccess.h>

2

#include <linux/module.h>

#include <linux/init.h>

#include <asm/io.h>

//#include <linux/io.h>

volatile unsigned long virt, phys;//用于存放虚拟地址和物理地址

volatile unsigned long *GPBCON, *GPBDAT, *GPBUP;//用与存放三个寄存器的地址

void led_device_init(void)

{

// 0x56000010 + 0x10 包揽全所有的IO引脚寄存器地址

phys = 0x56000010; // 0x56000010=GPBCON

//在虚拟地址空间中申请一块长度为0x10的连续空间

//这样,物理地址phys到phys+0x10对应虚拟地址virt到virt+0x10

virt =(unsigned long)ioremap(phys, 0x10);

GPBCON = (unsigned long *)(virt + 0x00);//指定需要操作的三个寄存器的地址

GPBDAT = (unsigned long *)(virt + 0x04);

GPBUP  = (unsigned long *)(virt + 0x08);

}

//led配置函数,配置开发板的GPIO的寄存器

void led_configure(void)

{

*GPBCON &= ~(3 << 10)&~(3<<12)&~(3 << 16)&~(3<<20);//GPB12 defaule 清零

*GPBCON |= (1 << 10)|(1<<12)|(1<<16)|(1<<20); //output  输出模式

*GPBUP |= (1 << 5)|(1 <<6)|(1 <<8)|(1 <<10);  //禁止上拉电阻

}

void led_off(void) //点亮led

{

*GPBDAT &= ~(1 << 5)&~(1 << 6)&~(1 << 8)&~(1 << 7);

}

void led_on(void) //灭掉led

{

*GPBDAT |= (1 << 5)|(1 << 6)|(1 << 8)|(1 << 7);

}

static int __init led_init(void) //模块初始化函数

{

led_device_init(); //实现IO内存的映射

led_configure();  //配置GPB5 6 8 10为输出

led_on();

printk("hello ON!\n");

return 0;

}

static void __exit led_exit(void) //模块卸载函数

{

led_off();

iounmap((void *)virt); //撤销映射关系

printk("led OFF!\n");

}

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("litingting<>");

MODULE_VERSION("2015-5-26");

3 makefile

ifneq ($(KERNELRELEASE),)

obj-m :=vir.o

else

KERNELDIR :=/home/litingting/gec2440/linux-2.6.30.4

all:

make -C $(KERNELDIR) M=$(PWD)  modules  ARCH=arm  CROSS_COMPILE=arm-linux-

clean:

rm -f *.o *.ko *.mod.o *.mod.c *.symvers modul* *.*~

endif

时间: 2024-10-29 03:18:55

2440--linux2.6.30.4的的虚拟地址和物理地址的关系的相关文章

编译天嵌官方的linux-2.6.30.4内核下载到TQ2440开发板不断重启的解决办法

编译天嵌官方的linux-2.6.30.4内核下载到TQ2440开发板不断重启的解决办法 查看了一下开发板启动打印的 LOG 信息,和官方启动 LOG 一对比发现交叉编译器版本不一致.我用的编译器版本是:arm-linux-gcc-4.5.1,而天嵌官方的 zImage.bin 是用arm-linux-gcc-4.3.3编译的.于是网上找了半天arm-linux-gcc-4.3.3没找到,便下载了一个 4.3.2 版本的. 重新编译下载,板子竟然奇迹般可以正常启动了. 但是又出现了新的问题,进入

linux2.6.30.4内核中platform_get_resource函数

今天看到下面这两个函数: struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num){ int i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; if (type == resource_type(r) &

【Linux驱动】TQ2440 DM9000E网卡驱动移植(Linux-2.6.30.4)

花了一天的时间研究了一下Linux-2.6.30.4版本号内核下关于TQ2440 DM9000E的网卡驱动移植.总结一下自己的收获. 事实上.在Linux-2.6.30.4版本号内核下有关于网卡驱动,可是这个网卡驱动不是针对于 DM9000E.而是针对于 DM9000的. 因此要在此基础之上改动一些參数.而且打上必要的相关代码.这个网卡驱动移植是參照了"天嵌科技出品-Linux移植之Step By Step_V4.6"的文档.但就是这样.还是花费了将近一天的时间.事实上这里的难点在于:

针对TQ2440开发板上linux2.6.30.4内核的交叉编译和驱动程序的移植

最近由于要做TQ2440(ARM9)开发板上的驱动实验,所以要在主机(ubuntu13.10)上针对前面的目标板上的系统内核进行交叉编译. 一,内核的交叉编译: 1.准备2.6.30.4版本的内核源码包,这个我使用的是天嵌公司提供的内核源码包linux-2.6.30.4_20121214.tar.bz2. 2.打开终端输入指令:tar vxjf linux-2.6.30.4_20121214.tar.bz2 解压内核源码包得到一个名字为opt的文件夹,然后输入指令:sudo mv opt /us

LED_9261在linux2.6.30中tick_led的实现

在linux2.6.30内核中,内核也提供了相关的平台驱动来操作gpio或LED,但更简便的方法是直接操作GPIO来控制led. 网上一博文中介绍直接封装led_on和led_off()函数直接调用即可. void led1_on() { s3c_gpio_cfgpin(LED_ID1, S3C_GPIO_OUTPUT); s3c_gpio_setpull(LED_ID1, S3C_GPIO_PULL_NONE); gpio_set_value(LED_ID1, 1); } void led1_

Linux驱动学习之TQ2440 DM9000E网卡驱动移植(Linux-2.6.30.4)

引言 在之前的文章中,我们介绍了如何使用Scala IDE也就是eclipse中集成的Scala开发插件来进行Scala语言程序的开发,在使用了一段时间之后,发现eclipse对Scala的支持并不是很好.用户体验比较差,比如联想速度比较慢等.由于在公司一直使用的Scala开发工具是Intellij IDEA(好吧,其实我使用Scala IDE的目的就是想试一下这两个各有什么优缺点),各方面感觉还不错,所以在此介绍一下这个开发环境. Intellij IDEA是jetbrain开发的一个IDE,

linux2.6.30.4 s3c2440 platform总线 led驱动

1  basic 在设备驱动程序中经常会见到和platform相关的字段,分布在驱动程序的多个角落,这也是2.6内核中比较重要的一种机制,把它的原理弄懂了,对以后分析驱动程序很有帮助,下面简单介绍一下:    在linux2.6设备模型中,关心总线,设备,驱动这三个实体,总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动.相反,在系统每注册一个驱动的时候,寻找与之匹配的设备,匹配是由总线来完成的. 一个现实的Linux 设备和驱动通常都需要挂接在一种总线上,对于本身依附于PC

自己学驱动13——内存管理单元MMU(虚拟地址和物理地址)

1.MMU简介 MMU负责完成虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查.现代的多用户多进程操作系统通过MMU使得各个用户进程都拥有自己独立的地址空间:地址映射功能使得各个进程拥有"看起来"一样的地址空间,而内存访问权限的检查可以保护每个进程所使用的内存不会被其他进程所破坏.MMU增加了底层的复杂性,但是为上层程序开发提供了极大的方便. 2.虚拟地址与物理地址 虚拟地址最终需要转换为物理地址才能读写实际的数据,这通过将虚拟地址空间.物理地址空间划分为同样大小的一块块空间

启用PAE后虚拟地址到物理地址的转换

34 [原创]启用PAE后虚拟地址到物理地址的转换 安于此生 2013-11-3 20:54 16073 由常规的两级页表转换得不到物理地址的引发的思考? 可能你会发现一个郁闷的事情--按照通常的两级页表的转化得不到正确物理地址,到底是哪个环节出了问题咧,其实一切都是PAE惹的祸! PAE是神马? PAE:全称Phyiscal Address Extension,物理地址扩展. 如何判断PAE是否开启了PAE. 一般两个特点: ?我的电脑=>属性=>常规面板中有物理地址扩展的字样. CR4寄存