Android系统的问题分析笔记(5) - Android上的C语言基础库Bionic里都有啥

问题

Android系统上的C语言基础库Bionic里都有啥?(此篇分析基础为Android 7.1.1系统源码)

1 概述

  Bionic 提供C 语言基础库(简称 C 库)的功能,它是一个专为嵌入式系统设计的轻量级标准库实现。Bionic的源码和头文件在 bionic/目录中。
  相对Linux操作系统中的 C 库实现glibc,Bionic 的体积和内存占用量更小。Bionic 支持标准C和 C++库的绝大部分功能,支持数学库及 NPTL 线程库。其中还有自己实现的 Linker 及 Loader,用于动态库的创建和加载。
  Bionic 提供的 C++的支持是一种最轻量级的支持,只支持了 C++语法,没有支持 STL(标准模板库)。Bionic 也有对标准 C 库进行了扩展,加入了 Android 独有的一些功能。例如,Android 特定的log 机制的底层支持、Android 中特定的 Property 系统支持。

2 Bionic 各部分的结构

Pedro@x86:bionic$ tree -L 1
.
├── Android.mk
├── benchmarks
├── build
├── CleanSpec.mk
├── CPPLINT.cfg
├── libc
├── libdl
├── libm
├── libstdc++
├── linker
├── README.md
├── tests
└── tools

Bionic目录当中的各个子目录中的内容如下所示。

  • libc:C 库,生成动态库 libc.so 和静态库 libc.a
  • libm:数学库,生成动态 libm.so 静态 libm.a
  • libdl:动态库使用工具,生成动态库 libdlso
  • libstdc++:C++库,生成动态库 libstdc++.so 和静态库libstdc++.a
  • libthread_db:线程库,生成动态库 libthread_db.so和静态lbthread_db.a

libc实际是C库的实现,目录中包含了 stdio、string、stdlib 和 binonic 等几个源代码的子目录,提供对各个部分 C 语言的实现支持。
libm 和libdl也是标准的名称。这两个库提供了标准的C语言运行环境。
libstdc++是 C++支持库,是一个Android 中的特定库。实际上,C++语言的支持库大部分是由编译器实现的。libstdc++是一个非常小的库,提供了 new 操作符等。
libthread_db 是一个基于 pthread 线程库的线程管理库,为Android 系统中的特殊实现。

3 Bionic 的头文件

  对于 Android 中大多数的开发,不需要关心 Bionic 的实现。但是可能需要直接使用Bionic 提供的功能,需要了解下 Bionic 的头文件。Bionic 的各个子目录中,一般都包含名称为 include 的子目录,这个子目录实际上就是这个库对应的头文件提供的支持。作为C 库功能的实现,Bionic 的头文件包括几个部分:C 语言标准头文件、UNIX 标准头文件、Linux内核中的头文件、Bionic特殊的头文件。

arch-XXX架构相关,包含汇编代码
bionic由C实现的功能,与架构无关
dnsdns相关操作
include头文件
kernelLinux内核头文件
malloc_debug内存泄漏调试相关
private私有头文件
stdiostdio函数实现
stdlibstdlib函数实现
tools工具
tzcode时区相关代码
zoneinfo时区信息

3.1 主要头文件

libc/include 目录中的各个文件为 C语言主要的头文件,例如 stdio.h、stdlib.h等。它们都是C语言标准的头文件。
libc/include/sys 目录中的各个文件是 Linux 系统以sys 为开头的头文件。例如:time.h、ioctl.h 等。

//在代码中,一般通过如下所示:
#include <sys/time.h>

其中的一部分文件是经过 Android 系统重写的,可能和标准的 Linux 系统的文件略有区别,但是它们定义的功能基本相同。

3.2 Linux特定头文件

在 Linux 中进行基于 C 语言的开发时,除了可以引用标准的头文件之外,有时还可以引用 Linux的头文件。Bionic 中的libc/kernel为 Linux 内核头文件目录。这个目录是对 Linux 源代码中各个部分头文件的重新组织。其结构如下所示:

dockdroid@zj-x86:kernel$ tree -L 2
.
├── common
│   └── scsi
├── README.TXT
├── tools
│   ├── clean_header.py
│   ├── cpp.py
│   ├── defaults.py
│   ├── generate_uapi_headers.sh
│   ├── kernel.py
│   ├── update_all.py
│   └── utils.py
└── uapi
    ├── asm-arm
    ├── asm-arm64
    ├── asm-generic
    ├── asm-mips
    ├── asm-x86
    ├── drm
    ├── linux
    ├── misc
    ├── mtd
    ├── rdma
    ├── scsi
    ├── sound
    ├── video
    └── xen

在Android 的本地开发过程中,如果使用<linux/xxx.h>等方式包含头文件,引用的是这里的头文件。

#include <linux/input.h>

  此时,实际上引用的是 Bionic中 libc/kernel/common/linux目录中的input.h。
  在一个 Android 系统中,由于内核和用户空间的内容是分别构建的。不同 kermel 版本中的头文件会略有不同。因此真正系统的内核头文件和 Bionic 中具有的内核头文件有可能具有不匹配的问题。
  在严格意义上,应该使用系统中真正的Linux内核头文件替换Bionic原本提供的Linux内核头文件。并且内核中定义的宏也应该是相同的,否则也存在着一定的风险。

  由于各个版本 Linux 内核的功能不会改变,在实际的操作过程中,即使这里直接使用风险也并不大。

4 属性系统的支持

  Android 的C库除了提供标准的功能之外,还提供了 Android 的属性系统的底层支持属性的本质是一块共享内存。其中 libc/include/sys/ 目录中的 system_properties.h 和 _system_properties.h 是属性机制的头文件,libc/bionic/目录中的 system_properties.c 是其源代码文件,两个宏用于定义属性名称和属性值的最大字符数:

//Android 中属性名称最大32字节,属性值92字节。
#define PROP_NAME_MAX   32
#define PROP_VALUE_MAX  92

_system_properties.h 属性相关的头文件中定义了重要的结构体:

struct prop_msg
{
    unsigned cmd;
    char name[PROP_NAME_MAX];
    char value[PROP_VALUE_MAX];
};

_system_properties.h 中关于默认的属性文件的定义如下所示:

#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_VENDOR_BUILD     "/vendor/build.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"
#define PROP_PATH_FACTORY          "/factory/factory.prop"

  几个扩展名为 prop 的属性文件是系统的默认属性定义文件,可以通过增加这几个文件的内容,定义系统的默认属性。Bionic 中实际上只是提供了属性机制最底层的支持,属性机制还需要依托 Android 其他部分才能使用(再往上有libcutil、libutil库的封装,以及init进程中的属性服务)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馬佩德罗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值