分类
联系方式
  1. 新浪微博
  2. E-mail

Halium

介绍

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/ 目录下。这些文件有的在源中,有的要自己添加进去。

TheMuppets 收集了好多。

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权限:

  1. 找到设备的 fstab 文件。例如 Moto G5 Plus,位于 device/motorola/potter/rootdir/etc 下的 fstab.qcom
  2. 启动 adb root access
  3. 在 fixup-mountpoints 中为你的设备创建骨架,就在*)之前:
    "[codename]")
        sed -i \
            [replacements, one per line]
            "$@"
        ;;
    
  4. 对于fstab中的每一行,如果类型不是 auto、emmc或swap,通过 ADB 在目标设备上执行 readlink -f [src],src 是 fstab 最左一列
  5. 写下我们所有的替换,每个挂载点都有一个。下面是其中一个的骨架。
    -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 提供的脚本适配,需要用其它脚本。

网络资源

Halium Project

GitHub 首页