学习 Binder 的预备知识1 —— 虚拟内存与 Linux 文件访问接口

2,211 阅读4分钟

Binder 的学习需要了解以下三方面的基础内容:

  • 虚拟内存
  • Linux 文件访问接口
  • Linux 内核中的常用数据结构

出于篇幅考虑,本文先讲解虚拟内存与Linux 文件访问系统接口

1.什么是虚拟内存

一些简单的计算机系统,比如简单的单片机,cpu 是直接访问物理内存的,不存在虚拟内存,同时也不存在操作系统,我们的程序直接跑在硬件之上。

读内存的过程如下:

  • cpu 通过控制总线向内存发送读指令
  • 随后将内存地址通过地址总线发送给内存
  • 内存读到数据后,通过数据总线将数据发送给 cpu

物理内存的地址从 0 开始,我们编写的代码读写内存也是从 0 开始。

单片机上只跑一个程序的时候,一切安好。

如果我们要再跑一个程序,我们读写内存如果还是从 0 开始,就会和第一个程序“打架”,发生冲突。如果不从 0 开始,比如我们规定第一个程序使用 0 到 4k的内存,第二个程序使用 4k 到 8k 的内存 ,这样能解决问题,但是,我们的程序就只能在特定环境下使用。

那怎么办,加一层————虚拟内存。

我们的每个进程访问的是从 0 开始的虚拟内存,在通过 mmu (内存管理单元)映射到物理内存,mmu 可以理解为一张巨大的表格,里面记录着每个进程使用的虚拟内存地址与物理内存地址的映射关系:

  • 进程1 发出读内存信号
  • 进程1 向 MMU 发送一个虚拟地址
  • MMU 在自己的表格中找到对应的物理地址,并从物理内存上读出数据,将数据返回给进程 1

对于虚拟地址空间一般分为:

  • 内核地址空间
  • 用户地址空间

不同进程之间的内核地址空间映射到相同的物理地址,即不同的进程的内核地址空间是共享的。不同进程之间的用户地址空间映射到不同的物理地址,相互之间是隔离的,无法访问的。

以上是虚拟内存的一个形象理解,对于软件开发人员已经足够,实际情况要复杂很多,涉及了分段分页,一二级页表,快表等内容,更为详细的内容可以参考计算机组成,操作系统相关的书籍

2.Linux 文件访问系统接口

在 Linux 中一切皆文件,比如 Android 中的 binder 实际是一个字符驱动,其对应的文件是 /dev/binder。所以我们需要熟悉 Linux 中文件访问系统的接口。

访问文件常用的函数有下面几个:

open
close
read
write
ioctl
mmap

这些函数都是系统调用接口,由内核中的 VFS( Virtual Filesystem)提供,VFS 对上(应用层)提供统一的文件访问接口,对下(文件系统,设备文件)根据不同目标特点,实现具体的操作,比如打开,读写等:

实际上,我们应用层调用的 open read 等系统调用,通过内核部分的处理最终都是调用到驱动中实现的 xxx_open xxx_read 等函数。

关于 Linux 驱动更详细的入门内容,可以参考以下内容:

关于

我叫阿豪,2015 年毕业于国防科技大学,毕业后,在某单位从事信息化装备的研发工作。主要研究方向为 Android Framework 与 Linux Kernel。目前已退伍定居成都,主要做工程机械相关的投资,同时也在做 Android Framework 相关的技术分享。

如果你对 Framework 感兴趣或者正在学习 Framework,可以参考我总结的Android Framework 学习路线指南,也可关注我的微信公众号,我会在公众号上持续分享我的经验,帮助正在学习的你少走一些弯路。学习过程中如果你有疑问或者你的经验想要分享给大家可以添加我的微信,我拉你进技术交流群。