#include <linux/module.h> //module_init() & module_exit()
#include <linux/init.h> //__init() & __exit()
#include <linux/fs.h> //register_chrdev() & unregister_chrdev()
#include <asm/uaccess.h> //copy_from_user() & copy_from_user()
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h> // arch/arm/mach-s5pv210/include/mach/gpio-bank.h
#include <linux/string.h> //strcmp()
#include <linux/io.h> ioremap() & iounmap() #include <asm/io.h>
#include <linux/ioport.h> request_mem_region() & release_mem_region()
#include <linux/cdev.h> //cdev_init
#include <linux/device.h> //class_create & device_create & device_destroy & calss_destroy
三星版本内核中的静态映射表
(1)主映射表位于:arch/arm/plat-s5p/include/plat/map-s5p.h
/***************************************************************/
#define S5P_VA_GPIO S3C_ADDR(0x00500000) // 0xFD500000
/***************************************************************/
CPU在安排寄存器地址时不是随意乱序分布的,而是按照模块去区分的。每一个模块内部的很多个寄存器的地址是连续的。所以内核在定义寄存器地址时都是先找到基地址,然后再用基地址+偏移量来寻找具体的一个寄存器。
map-s5p.h中定义的就是要用到的几个模块的寄存器基地址。
map-s5p.h中定义的是模块的寄存器基地址的虚拟地址。
(2)虚拟地址基地址定义在:arch/arm/plat-samsung/include/plat/map-base.h
/***************************************************************/
#define S3C_ADDR_BASE (0xFD000000)
//三星移植时确定的静态映射表的基地址,表中的所有虚拟地址都是以这个地址+偏移量来指定的
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
#else
#define S3C_ADDR(x) (S3C_ADDR_BASE + (x))
#endif
/***************************************************************/
(3)GPIO相关的主映射表位于:arch/arm/mach-s5pv210/include/mach/regs-gpio.h
表中是GPIO的各个端口的基地址的定义
#define S5PV210_GPJ0_BASE (S5P_VA_GPIO + 0x240)
(4)GPIO的具体寄存器定义位于:arch/arm/mach-s5pv210/include/mach/gpio-bank.h
映射表:头文件中的宏定义,
硬件驱动的操作相关:
1——硬件操作中的不变量:
(1)硬件物理原理不变
(2)硬件操作接口(寄存器)不变
(3)硬件操作代码不变
2——硬件操作中的变量:
(1)寄存器地址不同。原来是直接用物理地址,现在需要用该物理地址在内核虚拟地址空间相对应的虚拟地址。寄存器的物理地址是CPU设计时决定的,从datasheet中查找到的。
(2)编程方法不同。裸机中习惯直接用函数指针操作寄存器地址,而kernel中习惯用封装好的io读写函数来操作寄存器,以实现最大程度可移植性。
3——内核的虚拟地址映射方法
(1)为什么需要虚拟地址映射
(2)内核中有2套虚拟地址映射方法:动态和静态
(3)静态映射方法的特点:
内核移植时以代码的形式硬编码,如果要更改必须改源代码后重新编译内核
在内核启动时建立静态映射表,到内核关机时销毁,中间一直有效
对于移植好的内核,你用不用他都在那里
(4)动态映射方法的特点:
驱动程序根据需要随时动态的建立映射、使用、销毁映射
映射是短期临时的
4、如何选择虚拟地址映射方法
(1)2种映射并不排他,可以同时使用
(2)静态映射类似于C语言中全局变量,动态方式类似于C语言中malloc堆内存
(3)静态映射的好处是执行效率高,坏处是始终占用虚拟地址空间;动态映射的好处是按需使用虚拟地址空间,坏处是每次使用前后都需要代码去建立映射&销毁映射(还得学会使用那些内核函数的使用)