Halium
介绍

Halium 是一个合作项目,旨在在预装 Android 的移动设备,统一硬件抽象层(Hardware Abstraction Layer,HAL),从而运行 GNU/Linux。
Halium 项目包含:
- Linux Kernel(由设备厂商提供的源码)
- 与硬件交互的 Android 服务
- Libhybris
除此之外,Halium 项目还旨在使各个项目使用的中间软件标准化,以便与 Android 守护进程对话,并利用硬件,比如:
- OFono/RILd
- 相机服务
- Pulseaudio / Audiofingerglue
- GPS
- 媒体解码器
该项目不控制整体技术栈的以下高级部分。以下方面由发行版控制:
- 显示服务器
- 工具链
- 用户界面
- 应用程序
基于 Halium 的发行版:
- Plasma Mobile
- LuneOS
- Ubuntu Touch
背景
多年以来,人们为了将 GNU/Linux 移植到移动设备做出了各种努力(Maemo, Meego, Mer, SailfishOS, Ubuntu Touch, Plasma Mobile)。他们有的人做到了,有的人还在努力。
在这些项目的发展过程中,有人建议这些社区,应该一起工作,因为他们的最终目标是一致的。在 Halium 之前,没有进行这样的合作,因此由 Halium 来做这件事情。
概念
libhybris
与 Android 二进制 Blobs 打交道的库。
移植
假设你的设备是一辆汽车。你有一个汽油车(Android)。你想把它换成电动引擎(目标系统)。在车库里,你被告知可以装上柴油机(例如 Lineage OS)。不错,这说明你的车是能够换引擎的。
现在你需要收集新引擎的所有部分(内核、固件、……),把这些部分组装起来,装到新车中(移植)。
而且,由于每辆车的底盘不同,没法把福特的零件放到保时捷里用。
选择 Android 目标设备
被移植的设备需要满足以下要求:
- 源码可获取
- 设备的 Linux 内核源码必须开源
- 构建 LineageOS 12.1 或 14.1 的源码页必须要有
- 这两部分源码都需要
- 内核
- 内核版本要高于 3.10.0
- 低于这个版本的内核跟 systemd v217 不兼容
- 在 Android 关于页能看到内核版本
- 在内核根目录的 Makefile 也能看到版本
- 内存
- 1GB 内存足够启动大多数 Halium 发行版
- 2GB 或者更高能达到更好的用户体验
- 存储
- 16GB 是最低要求,再少不够 Halium 发行版安装了
如果设备不满足这些需求,就没法构建和运行了。
开发环境准备
为了构建 Halium,需要在电脑上配置开发环境。需要 Python3.6 以上版本。
Arch Linux
安装 64 系统的,需要开启 32 为支持,即开启 [multilib]。
安装 base-devel 系列包。
编译 Halium:
git clone https://aur.archlinux.org/halium-devel.git && cd halium-devel && makepkg -i
Halium 源码准备
选中目标设备之后,接下来是获取设备源码。
初始化代码树
创建一个新目录用于存放代码:
mkdir halium && cd halium
这个目录被称为 BUILDDIR 。 如果目标设备有 Android 9.0 (Pie) 或者 LineageOS 16.0,建议选择 halium-9.0:
repo init -u https://github.com/Halium/android -b halium-9.0 --depth=1
如果设备有 Android 7.1 或者 LineageOS 14.1,建议选择 halium-7.1:
repo init -u https://github.com/Halium/android -b halium-7.1 --depth=1
如果设备有 Android 5.1 或者 CyanogenMod 12.1,选择 halium-5.1:
repo init -u https://github.com/Halium/android -b halium-5.1 --depth=1
Halium tree 准备好之后,接下来开始拉代码,要拉几个 GB:
repo sync -c -j 16
如果你想在未来的某个时间点获得完整的版本库历史,因为你想打补丁、做贡献等等。你可以在版本库目录中执行以下命令:
git remote -v # The leftmost word is the remote name
git fetch --unshallow [remote_name]
添加设备专门代码
上一步有了 Halium 默认 manifest,也拉取了用于构建 Halium 的基本 Android 源码,但是还缺设备特定的文件。
如果说有什么地方会导致你犯错的话,那就是这个地方了。找到这些文件并不难,但你可能需要尝试几次才能正确创建 repo 的本地清单。
首先要找你的设备的 LineageOS 源,源仓库的命名方法是:android_device_[manufacturer]_[device]
源中会有 cm.dependencies 或者 lineage.dependencies 文件,告诉你设备依赖的其它源的位置。
进入 Halium 目录创建文件:halium/devices/manifests/[manufacturer]_[device].xml
粘贴以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
</manifest>
在其中填入项目: Device Repository 项:
<project path="device/[manufacturer]/[device]" name="[repository name]" remote="[remote]" revision="[revision]" />
如果不指定 revision 的话,它可省略。
依赖项:
这里用到 cm.dependencies 或者 lineage.dependencies。这个文件列出了用于构建所选设备所需要的其它源。
每个条目都按照以下模板插入:
<project path="[target_path]" name="[repository]" remote="[remote]" revision="[revision]" />
target path 根据源名字按以下规律得到:把 android、proprietary 省略掉,下划线变成斜杠。比如:android_device_lge_bullhead 变成 device/lge/bullhead。
厂商二进制:
厂商二进制放到 Halium 源码树的 vendor/ 目录下。这些文件有的在源中,有的要自己添加进去。
remote 项:
remote 指定了源码名称、位置、CR 服务器、默认分支(branch/tag):
<remote name="aosp"
fetch="https://android.googlesource.com"
review="android-review.googlesource.com"
revision="refs/tags/android-7.1.1_r25" />
只有名称、fetch 和 revision 是必须的。 举例来说,你在 https://github.com/MyUserName/ 下有一堆源,他们的分支都是 cm-14.1,可以这么写:
<remote name="mun"
fetch="https://github.com/MyUserName"
revision="cm-14.1" />
默认 remote:
halium-7.1:
Remote Name | Remote Description, URL |
aosp | Android Open Source Project, https://android.googlesource.com |
los | LineageOS, http://github.com/LineageOS |
hal | Halium (link to GitHub root for legacy reasons), http://github.com |
them | TheMuppets, http://github.com/TheMuppets |
them2 | TheMuppets (for some xiaomi vendor repos) https://gitlab.com/the-muppets |
如果不指定,默认用 AOSP。
halium-5.1:
Remote Name | Remote Description, URL |
phablet | Canonical Ubuntu Phone compatibility, https://code-review.phablet.ubuntu.com |
aosp | Android Open Source Project, https://android.googlesource.com |
cm | CyanogenMod, https://github.com/CyanogenMod |
ubp | UBports (link to GitHub root for legacy reasons), https://github.com |
halium | Halium (link to GitHub root for legacy reasons), https://github.com |
ab2ut | Vendor blobs for UBports builds, https://github.com/ab2ut |
如果不指定,默认用 phablet。
代码同步
执行下面脚本,DEVICE 换成设备代号:
./halium/devices/setup DEVICE
首先把你的 Halium 设备下的 manifest 连接到 .repo/local_manifests/device.xml,之后拉取所有源。
这会下载最多 2GB 源码。
适配好了的设备都在这个目录下:https://github.com/Halium/halium-devices
构建 Halium
上一步把所有代码准备好了,这一步开始构建。
首先初始化环境,进入BUILDDIR 执行:
source build/envsetup.sh
会有类似下面的输出:
including device/lge/bullhead/vendorsetup.sh
including vendor/cm/vendorsetup.sh
including sdk/bash_completion/adb.bash
including vendor/cm/bash_completion/git.bash
including vendor/cm/bash_completion/repo.bash
For Halium-5.1
通过 lunch 命令选择构建目标,并开始构建。
选择这种类型的:cm_[your device]-userdebug
For Halium-7.1
LineageOS 14.1 以上使用的是 breakfast 命令:
breakfast [codename]
修改内核配置
Halium 使用 Systemd 作为 init 系统,这需要设置一些内核配置。
检查需要哪些选项,需要使用 mer-hybris 提供的 mer-kernel-check 工具:
git clone https://github.com/mer-hybris/mer-kernel-check
cd mer-kernel-check
./mer_verify_kernel_config <path to kernel configuration>
如果你不知道你的内核配置的路径,执行:grep "TARGET_KERNEL_CONFIG" device/<VENDOR>/<CODENAME>/BoardConfig.mk
结果应该是 arch/arm/configs/<CONFIG>或者 arch/arm64/configs/<CONFIG>
注意:CONFIG_IKCONFIG、CONFIG_IKCONFIG_PROC 这两个要开启,要不然 Halium 启动不起来。
As of systemd 233 the 3.4 kernel needs to have a patch in order to boot (tmpmnt not being created)
Fixup-mountpoints
Fixup-mountpoints 将 /dev/block/by-name 中的块设备节点的别名替换为 /dev/block 中的字面节点。这可以避免因 systemd 没有填入 by-name 而引起的问题。
首先检查你的设备的代号是否已经包含在<BUILDDIR>/halium/hybris-boot/fixup-mountpoints脚本中。
如果没有添加,你需要添加。你的设备应该运行LineageOS或其他ROM,你可以通过ADB获得root权限:
- 找到设备的 fstab 文件。例如 Moto G5 Plus,位于 device/motorola/potter/rootdir/etc 下的 fstab.qcom
- 启动 adb root access
- 在 fixup-mountpoints 中为你的设备创建骨架,就在*)之前:
"[codename]") sed -i \ [replacements, one per line] "$@" ;;
- 对于fstab中的每一行,如果类型不是 auto、emmc或swap,通过 ADB 在目标设备上执行 readlink -f [src],src 是 fstab 最左一列
- 写下我们所有的替换,每个挂载点都有一个。下面是其中一个的骨架。
-e 's [src] [return] ' \
构建 system.img 和 hybris-boot.img
Halium 使用 mkbootimg 工具创建启动映像。 在大多数情况下,它不在本地硬盘上,所以它可以通过发行来建立:
mka mkbootimg
要建立 Halium 所需的 system.img 和 hybris-boot.img,请使用以下命令:
export USE_HOST_LEX=yes
mka hybris-boot
mka systemimage
编译可能会遇到报错,问题记录。
安装
发行版选择
你可以选择安装下面的发行版,通过 Halium 提供的脚本和源码。推荐先使用 Halium reference rootfs 来测试一下:
还有的发行版,没法用 Halium 提供的脚本适配,需要用其它脚本。
网络资源
- Blog 页面:Halium is in the air!
- 文档页