Linux内核的学习(一)

Linux内核里mmu已经启动,不能直接访问物理地址。

mmu,全称Memory Manage Unit, 中文名————存储器管理单元。

  • 地址范围—— 计算机上的地址集合。(大小是由CPU的位数决定)32位——0 ~ 0xFFFFFFFF(4G), 64位——0~0xFFFFFFFFFFFFFFFF(64T)。地址范围也叫虚拟地址空间,该空间的某一个地址我们称之为虚拟地址。
  • 物理地址———真实地址空间。

  MMU是如何工作?

进程X开始运行时,访问到VPRN0,是虚拟地址。VPFN0是指向页表(页表分为page index(页号索引),offset(偏移位)。页表的详细说明 http://blog.csdn.net/seanyxie/article/details/5728772)。通过页表,会发现该部分的虚拟内存实际上是位于PFN0区域,所以程序实际上访问的就是物理内存的PFN0区域。VPFN3----->PFN4。 当我的Y进程也在运行时 Y的虚拟内存VPFN1——>PFN4。

由此,我们得出以下结论:

  1. 物理地址,和虚拟地址没什么关系。
  2. 不同进程会被分配同一个物理内存
  3. 不同的进程的虚拟内存,其对应的物理内存实际上没有多大关系

////////////////////////////////

Linux内核的MMU已经启动,我们如何去直接访问物理地址?

 #include <asm/io.h>
void
*ioremap(cookie,size) //该函数用于把指定的物理地址映射到一个虚拟地址上
//cookie 指定物理地址, size表示映射的大小范围
//返回值为映射得到的虚拟地址

iounmap(void *addr) //用于取消虚拟地址的映射关系。
 ioread8(地址)/readb() // 读地址上的8位值, readb是比较老的函数
 ioread16(地址)/readw()// 读16位
ioread32(地址)/readl()//读32位

iowrite8(值,地址)/writeb//写8位,writeb是比较老的函数

iowrite16(值,地址)/writew//写16位

iowrite32(值,地址)/writel//写32位
 1 #include <linux/init.h>
 2  #include <linux/module.h>
 3  #include <asm/io.h>
 4 
 5 #define BADDR 0x01c20800
 6 u8 *vaddr; //用于记录映射的虚拟地址
 7 
 8 static int __init myinit(void)
 9 {
10     u32 val;
11     vaddr = ioremap(BADDR, SZ_4K);
12     
13     printk("myinit.......");
14     return 0;
15 }
16 
17 static void __exit myexit(void)
18 {
19     printk("myexit");
20 
21     iounmap(vaddr);
22 }
23 
24 module_init(myinit);
25 module_exit(myexit);
26 
27 MODULE_ILCENSE("GPL");

Linux 内核提供gpio口的操作的函数

linux内核里有标准的GPIO操作方法. 其中有对芯片厂商的要求,芯片厂商需要在内核里实现相关的GPIO控制器的驱动配置, 让内核里的gpiolib(drivers/gpio/目录下)可以统一管理整个芯片的gpio口, 让我们驱动人员可以用内核提供的gpio标准操作函数通过gpiolib来调用控制芯片的io口.

#include <linux/gpio.h>

int gpio_request(unsigned gpio, const char *label);//用于io口申请,每个io只能一次
void gpio_free(unsigned gpio); //释放已请求的io口
 
int gpio_direction_input(unsigned gpio);//把io作为输入功能
int gpio_direction_output(unsigned gpio, int value);//作输出,并根据value的值输出高低电平

int gpio_get_value(unsigned gpio);//获取指定io的电平
void gpio_set_value(unsigned gpio, int value);//设置io的电平

int gpio_to_irq(unsigned gpio);//获取到gpio的中断号

如何在内核里找到GPIO口的定义。有两种方法:

  • 一般情况下, io口的定义是在内核源码arch/arm/mach-xxxx/include/mach/gpio.h.(mach-xxxx是和板有关)
  • 我们可以反着来,查找谁在用GPIO口。例如:我们查gpio_request,看看GPIO口的定义。

我们可以不用看CPU的芯片手册,直接控制GPIO。

 

posted on 2017-12-12 16:16  131927  阅读(368)  评论(0)    收藏  举报

导航