[Android] Android架构体系(2)

文章目录

  • Bionic
    • 精简对系统调用的支持:
    • 不支持 System V IPC:
    • 有限的 Pthread 功能:
    • 有限支持C++:
    • 不再支持本地化和/或宽字符:
    • Bionic新增的特性
      • 系统属性
      • 硬编码写死的UID/GID
      • 内置了DNS解析
      • 硬编码写死的服务和协议
  • 硬件抽象层
  • Linux内核
    • 匿名共享内存(ASHMem)
    • Binder-Binder
    • Logger
    • ION 内存管理
    • 内存不足时的进程终止器
    • RAM Console
    • Sync driver
    • 定时输出和 GPIO
    • wakelock
  • 参考

[Android] Android架构体系(1)

Bionic

抛开合法性问题不提,相对于GLibC,Bionic 也可以算是非常轻量级的了,而且对于Android所要达成的目标,Bionic 也更为有效。Bionic 中去掉的下列这些特性的原因或是认为没有必要或是认为太过复杂。

精简对系统调用的支持:

由于系统用是使用得非常频繁的,所以 Boinic 想要通过尽量减少对它们的封装的方式,降低因使用系统调用而引起的开销。系统调用的 stub 函数是在bionic/libc/SYSCALLS.TXT 的帮助下自动生成的,甚至有些系统调用都不会被导出。

不支持 System V IPC:

在 Boinic 没有导出的系统调用中,有一部分是用来处理UNIX System V 进程间通信(IPC,Inter-Process-Communication)和共享内存的。这是由于 Android 的设计使然,去掉这种形式的 IPC,而改用Android自己的IPC。

有限的 Pthread 功能:

一方面,Bionic 本身就支持 Pthread (即不需要一个单独的libpthread.so)。

但是另一方面,Bionic 对 Pthread 的支持也不是很全面,不少特性已经不再支持了,其中最值得注意的就是现在已经不能使用的pthread cancel()这个用来杀线程的函数了。

对 mutex 的支持也被阉割掉了,取而代之的是更为高效的内核快速 mutex(futex(2)系统调用),此外较为高级的IPC对象(比如rwlocks)也已经不复存在了。

有限支持C++:

尽管确实是支持 C++的(而且事实上Android 的大多数代码也是用C++写的),但是异常处理已经不支持了。与之类似,STL (Standard Template Library,标准模板库)也已经不再包含在其中了一一尽管也不是严格地不让使用 STL,不过得要手工添加一些代码才行(部分代码可以在external/stlport 项目中找到)。

不再支持本地化和/或宽字符:

Bionic 原生只需要ASCII–尽管通过 libutils.so还是可以使用Unicode的。

去掉这些东西还是很有道理的,特别是考虑到 Android 中大部分代码是跑在虚拟机里的,而使用虚拟机本身就意味着不需要 App
的开发者使用这些功能。 例如,虚拟机有自己的线程管理和 Unicode 支持 (通过ICU)。不过,去掉这些特性还是会给原生代码的开发者带来一些麻烦,特别是那些想要把一些库从 Linux 移植到 Androd 上来的程序员。

Bionic新增的特性

Bionic 也在标准 LibC 中新增了一些特性,这些都是为 Android 而特别优化的,这些新增的特性包括:

系统属性

系统属性是 Android 特有的特性,它支持系统或应用在一个简明的由“键/值”构成的存储空间中记录各种配置和操作参数。它类似于 Java 中“属性”的概念(而且事实上它是可以通过 Java 的 System.properties 访问的)。Android 极度依赖于这一机制,系统属性是在一段共享内存中实现的,系统中的所有进程都能以只读权限访问它,但只有 imit 进程才有对它进行设置(写)的权限。

硬编码写死的UID/GID

与传统的 UNIX系统中依赖于 passwd 和 group 文件进行权限管理的方式不同,Android 中选择使用硬编码写死的id,并模拟getpwnam(3)及其相关函数的方法进行权限管理。我们只要考虑一下 Android 的安全模型,就会觉得这一做法也不无道理:

Android 中每个应用都会被分配到它自己的UID 和GID (从10000 开始),而且这些ID会被映射为方便人来阅读的格式 ,例如:app_uxXX (或者从JellyBean 版起,这一格式改为:uX_aYYY)。

此外Android 把数字较小的UID/GID (1000-9999)保留了下来,供它自己的子系统使用。

内置了DNS解析

Bionic 中整合进了“名称-IP”的DNS 解析代码(在传统 Linux中,这部分代码是放在 libresolv.so 中的)。

Bionic 中使用的代码更为安全(源端口和Query ID都是随机的,这样做能有效地防范“生日攻击”),并且引入了一个新奇的特性一一每个进程都可以有自己的 DNS 解析服务器列表。

这使得特定的应用可以通过重新设置net.dns.pid系统属性的方式,抓取 DNS 解析的结果或者重定向解析 DNS 请求的服务器。
DNS 配置本身也是存储在系统属性中的(net.dns#)。

硬编码写死的服务和协议

因为已经把原来 libresolvso 做的事都给包圆了,Android 中就去掉了传统 UNIX 系统中通常是放在/etc 目录下的 protocols 和 services 这两个文件。

硬件抽象层

Android 会运行在许多不同种类的设备上 (平板电脑、手机、机顶盒、跑步机等),底层硬件在适用范围和支持方面都有极大的不同。

为了解决这个问题,Android 定义了一个硬件抽象层(HAL,Hardware Abstraction Layer),其目标是通过定义一个转换层,使对各种不同类型硬件的操作趋于标准化。

硬件厂商可以在内核态中随心所欲地使用它们自己生产的设备的驱动程序但是必须提供一个接口库 (shim),以Android (特别是 Dalvik) 预期的方式与操作系统对接。

硬件抽象层上定义了从 Android 的角度看来,摄像头、GPS、传感器以及其他的硬件组件应该是个什么样子。

这并不会妨碍厂商扩展或修改硬件的功能,只需要厂商把接口库放到/system/lib/hw 目录里去就行了,然后 HAL(硬件抽象层)(也就是 libhardwareso) 会自动加载它们。打印某台Android设备使用的HAL接口库,例如:
在这里插入图片描述

Linux内核

Linux 内核得益于它开源和免费授权的本质,为 Android 提供了一个极为出色的基底。

尽管它现在已经和 Linus Torvalds 最初的版本差了不止十万八千里,但是 Linux 内核仍在以不可思议的速度演进着一每个月,甚至每一周都会增加新的特性。Android 所能拥有的功能在很大程度上会受到内核的影响。

较为有名的例子当数 zRAM 和对 64 位的支持。后者有助于解释为什么表Lollipop版的Android 系统会有两个最低版本,因为 Linux 内核是从3.7 版开始才支持 ARM64(AArch64)的。

谷歌在选择内核版本时也会受到一些限制,因为它只能从http://www.kernel.org 网站中选择那些被标为长期支持 (long term)的内核版本。

与其他 Linux 内核相比,Android 内核被编译得稍有差异。因为配置文件生成时同时使用了Android 的基础配置和默认内核发布版本中的建议配置模板。

如 source.android.com 网站中 kernel

前文中已经提到过,Android 在内核中引入了一些它特有的特性(Androidism)。

其中的一些被放在内核的 core 中,用条件编译语句#ifdef 加了一层保护,而剩下的则被放在了drivers/staging/android 目录中。

这些Android 特有的特性包括:

匿名共享内存(ASHMem)

这是一种允许进程间共享内存的机制。应用可以打开一个字符设备节点 (/dev/ashmem)并创建一段内存空间,然后再把它映射 (map)到进程内存中去。这需要把工作限定在非全局可写(no world-writable)的目录中,并进行 SystemV进程间通信。

Binder-Binder

是 Android 中所有进程间通信的关键,它源自于 BeOS。Binder 表现为个所有进程都能够打开的字符设备节点 (/dev/binder)。Android 中的各种服务都注册在 Binder 这里,客户端可以在 servicemanager 的帮助下连上相应的服务。Binder 提供了一个有效的高级进程间通信机制。

Logger

提供基于内核的 ring buffer,用以高速记录日志。Android 的日志并不是记录在文件中的,而是由一个字符设备节点 (/dev/log)来承载的。

Android Lollipop 版中专门为此新增了一个用户态守护进程logd。

ION 内存管理

ION 内存管理器是在冰激凌三明治版中被引入的,其功能是向内核驱动和用户态下的类似模块(通过/dev/ion) 提供高效的内存分配服务。ION 替换掉了旧的Android 特有的组件 PMEM,ION 的设计目标是为各种不同的 SoC 构中的内存管理提供一个统一的标准。

内存不足时的进程终止器

这个组件改进自 Linux 原有的OOM(Out-Of-Memory)进程终止器一一它会在内存不足时,杀掉一些进程,以释放内存空间。

不过 Android 中的这个组件是使用启发式的方法来寻找要被杀掉的进程的,而 Linux 原有的进程终止器是以一种更具确定性的方式控制杀进程的行为的,而且还允许定义内存压力等级。AndroidLollipop 版中为此专门增加了一个用户态守护进程 Imkd

RAM Console

这是一种保存内核崩溃时输出的诊断用数据(程转储和最近的日志)的机制。不过较新版本的Android 系统已经弃用了这一特性,转而采用 Linux 内核中自有的一个功能了。

Sync driver

这是最新引入的 Android 特有的特性,引入它是为了快速同步基元(primitive),它主要是用在 Android 图形栈(特别是 surfaceflinger)中的。

定时输出和 GPIO

使得用户态程序在用户态空间里就能访问 GPIO 寄存器,并在间隔一段时间之后自动设置GPIO 寄存器的值。

它的主要客户端是设备中的振动器(vibrator)功能框架(通过硬件抽象层)可以把一个数值(单位为毫秒)写入/sys/classtimedoutput/vibrator/enable 中,这样就启动了振动器,并让振动器振动了这个值规定的时间之后停下来。

wakelock

最初这是一个单独的用来控制电源管理并阻止内核进入休眠状态的Android 特有的特性。不过 wakelocks 现在已经逐步被并入到内核自己的 wakeup source机制中去了。

参考

《最强Android书:架构大剖析》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/413452.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【经典算法】有趣的算法之---粒子群算法梳理

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 粒子群算法 粒子群算法(Particle Swarm Optimization,PSO)是一种用于解决优化问题的元启发式算法。它通过模拟鸟群或…

什么是车载信息娱乐系统和集成驾驶舱

什么是车载信息娱乐系统(IVI)? “车载信息娱乐(IVI)”通过向驾驶员和乘客提供信息和娱乐,为驾驶提供便利和舒适。为了理解这个概念,有必要知道“信息娱乐”的含义。“信息娱乐”是这个市场中使用的一个词,它结合了“信息”和“娱乐”两个词…

编译FFmpeg4.3.1 、x264并移植到Android

1、前言 FFmpeg 既是一款音视频编解码工具,同时也是一组音视频编解码开发套件。 2、准备工作 系统:LinuxNDK:android-ndk-r21b-linux-x86_64.zipFFmpeg:ffmpeg-snapshot.tar.bz2x264:x264 3、下载NDK 在linux环境中…

存内计算技术打破常规算力局限性

说明: 本文撰写人:三掌柜666 由三掌柜666原创首发:https://blog.csdn.net/CC1991_/article/details/135623056 文章目录 前言关于存内计算1、常规算力局限性2、存内计算诞生记3、存内计算核心 存内计算芯片研发历程及商业化1、存内计算芯片研…

Unix时间戳

时间戳,相信很多相关专业的人,计算机软件电子等等都会听过。由于最早是由Unix系统使用所以又叫Unix时间戳。 Unix 时间戳(Unix Timestamp)定义为从UTC(世界协调时)/GMT(格林尼治时)…

【Java】SpringBoot快速整合Redis

什么是Redis? 文末有源码gitee地址 【面试】浅学Redis_redis 广播-CSDN博客 Redis是一种高性能开源的基于内存的,采用键值对存储的非关系型数据库,它支持多种数据结构,包括字符串、哈希表、列表、集合、有序集合等。Redis的特点之…

机器学习--Matplotlib

机器学习–Matplotlib Matplotlib 是专门用于开发2D图表(包括3D图表)以渐进、交互式方式实现数据可视化 简单的Matplotlib画图 — 以折线图为例 matplotlib.pyplot模块 matplotlib.pytplot包含了一系列类似于matlab的画图函数。 import matplotlib.pyplot as plt图形绘制流…

STM32入门教程-2023版【4-1】OLED调试工具

关注 点赞 不错过精彩内容 大家好,我是硬核王同学,最近在做免费的嵌入式知识分享,帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 一、概述 在这一节先提前介绍一下,在以后的教程中我们会经常用到这个显示屏&#xff0…

HCIA的访问控制列表ACL

ACL -----access control-list 允许/拒绝 ACL作用: 1.实现访问控制 2.定义感兴趣流量 ACL分类: 标准ACL 2000-2999(只关注源IP地址,使用时应该尽量靠近目标) 扩展ACL 3000-3999:写ACL不能写在源上&…

Java基础知识整理,注释、关键字、运算符

写在开头 万丈高楼平地起,要想学好汉语首先学拼音,想学好英语首先学26个字母,对于编程语言来说,一样的道理,要想学好必须先掌握其基础语法和知识,今天我们就来唠一唠Java语言中那些出现频率极高&#xff0…

Linux:shell脚本:基础使用(8)《函数局部|全局变量函数传入位置变量return》

基本的函数定义 把一些重复调用的命令写进一个函数里,下次直接调用函数名,这样的既方便修改,又可以让思路清晰 function 函数名(){ 当调用这个函数时候执行的命令...... } 这个是一个基础的函数定义,当然你不加function也是可以的…

Three.js Tri-panner (三面贴图) 材质 两种实现方式

文章目录 介绍自定义shaderNodeMaterial修复:骨骼材质特殊处理修复:使用法相贴图时整体变色 介绍 Tri-panner 在babylonjs中有支持 但是three.js目前的基础材质并不支持 需要自己定义shader 或者使用目前还没有什么完善的文档的 NodeMaterial 下面展示两…