writel和readl,这两个个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据。先说一下writel:
 
在arch/alpha/kernel/io.c中有
  • 188 void writel(u32 b, volatile void __iomem *addr)
    189 {
    190     __raw_writel(b, addr);
    191     mb();
    192 }

这样一个writel函数的作用应该是向一个地址上写一个值,我想知道这个函数底下具体实现的细节,于是往下继续跟踪代码:__raw_writel(b, addr);(发现在同目录下)

  • 129 void __raw_writel(u32 b, volatile void __iomem *addr)
    130 {
    131     IO_CONCAT(__IO_PREFIX,writel)(b, addr);
    132 }

再往下跟踪 IO_CONCAT,在对应的io.h中的定义如下:
  • 134 #define IO_CONCAT(a,b)  _IO_CONCAT(a,b)
    135 #define _IO_CONCAT(a,b) a ## _ ## b

这段代码前几天问过了,是标示将两边的字符串连接起来的意思。
 
跟踪__IO_PREFIX 定义如下
  • 501 #undef __IO_PREFIX
    502 #define __IO_PREFIX     apecs

继续阅读代码,看看定义__IO_PREFIX之后紧接着包含了哪个头文件。在哪个头文
件里面寻找答案。对于你的apsec,看看以下代码段(linux-2.6.28-rc4)

arch/alpha/include/asm/core_apecs.h

  • #undef __IO_PREFIX
    #define __IO_PREFIX             apecs
    #define apecs_trivial_io_bw     0
    #define apecs_trivial_io_lq     0
    #define apecs_trivial_rw_bw     2
    #define apecs_trivial_rw_lq     1
    #define apecs_trivial_iounmap   1
    #include <asm/io_trivial.h>

前往arch/alpha/include/asm/io_trivial.h

  • __EXTERN_INLINE void
    IO_CONCAT(__IO_PREFIX,writel)(u32 b, volatile void __iomem *a)
    {*(volatile u32 __force *)a = b;
    } 

就是最终通过*(volatile u32 __force *)a = b;
来写入数据的。
同样的readl读取数据也和writel类似,这里就不重复了。
 
(如果在没有os,没有mmu的情况下,当开发板裸跑的时候,我们只需要一句话就一切ok:
  • *(unsigned long *)addr = value)

转载于:https://www.cnblogs.com/icefree/p/8539133.html

内核里面writel(readl)是如何实现的相关推荐

  1. readb(), readw(), readl(),writeb(), writew(), writel() 宏函数

    readb(), readw(), readl()函数 功能: 从内存映射的 I/O 空间读取数据. readb  从 I/O 读取 8 位数据 ( 1 字节 ): readw 从 I/O 读取 16 ...

  2. Exynos4412 内核移植(五)—— 驱动的移植

    以移植自己制作的驱动,学习内核移植中的驱动移植,及 驱动程序的动态编译和静态编译 硬件环境: Linux 内核版本:Linux 3.14 主机:Ubuntu 12.04发行版 目标机:FS4412平台 ...

  3. 支持v4l2 linux内核选项 s3c2440,linux内核移植-移植2.6.35.4内核到s3c2440

    原标题:linux内核移植-移植2.6.35.4内核到s3c2440 硬件平台:FL2440 主机平台:Ubuntu 11.04 交叉编译器: - -gcc 4.3.2 原创作品,转载请标明出处htt ...

  4. linux 内核2.6.35.3,linux-2.6.35.3内核移植(s3c2440)

    忙乎了一个下午,总算忙乎出来了,不过前期大量的搜索工作别人已经完成. 大量参考:http://blog.csdn.net /huihui1988/archive/2010/08/09/5799500. ...

  5. linux内核带usb驱动,Linux3.4内核USB驱动的移植

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 作者:李老师,华清远见嵌入式学院讲师. [实验目的] USB接口是现在计算机系统中最通用的一种接口,通过移植USB驱动,了解Linux3.4内核与Linu ...

  6. 创客exynos-fs4412系统移植-(uboot,内核,文件系统)

    fs4412系统移植学习笔记 环境: ubuntu 14.04 发行版 FS4412 实验平台 交叉编译工具:arm-none-linux-gnueabi- gcc: 4.8.5 目录 fs4412系 ...

  7. Linux内核---31.按键驱动分析(未完成)

    一. device的注册 1.0 按键设备的注册 按键设备的定义在arch/arm/mach-s3c64xx中 /* gpio buttons */ static struct gpio_keys_b ...

  8. Linux内核---30.触摸屏驱动分析

    查看input系统 root@OK6410:~# cat /proc/bus/input/devices I: Bus=0013 Vendor=dead Product=beef Version=01 ...

  9. Linux内核IOREMAP驱动

    1 Linux内核IOREMAP驱动 在内核驱动的代码中,存在大量代码使用ioremap进行物理地址和虚拟地址映射,使得内核更加容易操作硬件,对比于简单的gpio控制,实际的代码同样是使用了iorem ...

  10. Linux驱动之平台设备

    <平台设备设备驱动> a:背景: 平台总线是Linux2.6的设备驱动模型中,关心总线,设备和驱动这3个实体.一个现实的Linux设备和驱动通常需要挂接在一种总线上(比如本身依附于PCI, ...

最新文章

  1. SharePoint 2007 系列(4) -Site Settings
  2. 清华学生计划表上热搜,大写的服!
  3. 数据分析第一步--数据采集怎么进行埋点?
  4. 生成网页没有标题_网页设计公司有哪些?用这个快速建站!
  5. oracle 9i rac Linux,请教高手!能在linux下安装两套oracle 9i RAC 数据库软件与实例吗?...
  6. 用VIPER构建iOS应用
  7. 如何利用NLog输出结构化日志,并在Kibana优雅分析日志?
  8. 飞鸽传书:造假与成功
  9. IDEA配置使用阿里云maven仓库
  10. java hashset char_java集合之HashSet
  11. Bailian4132 四则运算表达式求值【文本处理】
  12. LVM 的创建,扩展,缩减及建立快照
  13. SEO超级外链留痕工具 最新SEO外链一键优化网站源码
  14. 判断是否为 retina屏幕
  15. GIF图像格式简介(87a和89a)(C语言生成GIF图像)
  16. CDay09 联合和枚举
  17. Squid代理服务器及配置
  18. 北邮机器人队2020预备队培训(一) —— 培训介绍以及基础知识
  19. 用Python吐槽国产综艺节目!
  20. AGC 012 E Camel and Oases - 状压dp

热门文章

  1. android系统结构与应用编程 实验报告_学习编程或编码的最佳Android应用程序
  2. colab 数据集_Google Colab上的YOLOv4:轻松训练您的自定义数据集(交通标志)
  3. 无监督模型 训练过程_监督使用训练模型
  4. python财经数据接口工具有哪些_Python财经数据接口包TuShare的使用
  5. 程序打成jar包路径不对、找不到配置文件的解决
  6. Java_脚本引擎_01_用法入门
  7. Maven发布工程到公共库
  8. 报道称三星与AMD/Nvidia商讨GPU技术授权:移动设备要起飞?
  9. spring StopWatch用法
  10. 用 WebSocket 实现一个简单的客服聊天系统