[Android]从零开始的内核编译

2023-11-07

从零开始的内核编译

本教程将基于小米 10S 的内核源码进行实例,其他型号的手机请自行寻找内核源码。具体内容可以参考我的内核编译项目

手机型号查询

1. 获取设备(手机)代号

在安卓设备终端(adb shell)上执行:

getprop | grep device

并寻找带有 ro.xx.device 这一行,里面的内容即为你的手机代号,例如:

# 手机代号为 thyme
[ro.product.device]: [thyme]

2. 获取设备架构

在安卓设备终端(adb shell)上执行:

uname -m

我的设备显示为 aarch64, 即可判断我的设备架构为 aarch64

3. 获取设备内核版本

在安卓设备终端(adb shell)上执行:

uname -r

输出内容的格式为:

  • [版本].[补丁版本].[子版本号]-[内核标识]-[提交记录]

例如我的设备显示为 4.19.157-Margatroid-gb1b98c3d4fd0

内核源码获取

内核源码的一般格式为 [android_]kernel_设备厂商_cpu/代号,例如,小米 10S(thyme)的代号为 thyme, CPU 型号为 sm8250,生产厂商为 xiaomi,则搜索格式应为下面几种:

kernel_xiaomi_thyme
kernel_xiaomi_sm8250
android_kernel_xiaomi_thyme
android_kernel_xiaomi_sm8250

以下是我收集的一些小米 10S(thyme)的源码仓库:

当然除此之外还有很多源码,但这些源码对于我来说是我前期学习的一个途径,因此在这里列出给大家。

途径 具体介绍
各厂商开源 小米内核开源
华为开源代码
去手机社区找源码 XDA 论坛

获取编译工具链

强烈推荐您学习[内核向] 交叉编译器的选择以及[白话文版] ClangBuiltLinux Clang 的使用来学习工具链的配置。

同时可以配合 Neutron-Clang 的说明文档来进行编译参数配置。

目前比较推荐的几个预编译工具链如下:

工具名称 简介
Neutron-Clang 这是为内核开发构建的 LLVM 和 Clang 编译器工具链。构建始终是从最新的 LLVM 源代码而不是稳定版本构建的,因此无法保证完全的稳定性
阿菌•未霜 Clang/LLVM Toolchain with Binutils 这是一个预构建的工具链,构建始终来自最新的 LLVM 和 Binutils 源而不是稳定版本,因此无法保证完全的稳定性。它是用 Full LTO、PGO 和 BOLT 构建的,以尽可能减少编译时间。
ClangBuiltLinux/tc-build 类似前两个工具,但是这个工具需要自己在本地从 LLVM 的源码进行构建,但编译时间较长。

除此之外,一个比较保险的方法是从预编译内核机器的 /proc/config.gz 提取`,需要对应版本的交叉编译器以及 Clang,自行选择合适版本下载即可,通过这种方式编译出来的内核一般是不会存在错误的。

1. Neutron-Clang 使用介绍

这是为内核开发构建的 LLVM 和 Clang 编译器工具链。构建始终是从最新的 LLVM 源代码而不是稳定版本构建的,因此不能保证完全的稳定性。目前该编译链工具使用 AntMan 来同步工具,具体使用方法如下:

mkdir -p "$HOME/toolchains/neutron-clang"
cd "$HOME/toolchains/neutron-clang"
bash <(curl -s "https://raw.githubusercontent.com/Neutron-Toolchains/antman/main/antman") -S

一些更多的 AntMan 命令:

功能 对应命令
同步最新的工具链构建 ./antman -S./antman -S=latest
同步特定的工具链版本 ./antman -S=<release tag>
检查更新 ./antman -U
检查更新和同步更新 ./antman -Uy
同步特定更新 ./antman -S=<release tag>
删除同步构建 ./antman -D
显示有关同步构建的信息 ./antman -I
同步特定的工具链版本 ./antman -S=<release tag>

如果需要更多细节介绍,请运行 ./antman --help 获取。

2. ClangBuiltLinux

如果您想要使用这个工具链的话,那么其中的编译工具则需要你自行编译,对应的编译脚本为 ClangBuiltLinux/tc-build

诚然,自行编译确实是一件造轮子且费时费力的方法,但是通过这种方式编译出来的工具是最适合您的系统的,不会发生其他的编译中的关于 glibc 等方面的错误。

3. 阿菌•未霜 Clang/LLVM Toolchain with Binutils

这是一个预构建的工具链,构建始终来自最新的 LLVM 和 Binutils 源而不是稳定版本,因此无法保证完全的稳定性。它是用 Full LTO、PGO 和 BOLT 构建的,以尽可能减少编译时间。

其编译链工具存储在:

  • GitHub:仅用于发布预构建的压缩文件(*.7z)
  • Gitea:仅用于存储预构建的二进制文件(Current AR Archive、ELF 64-bit LSB shared object 存储在 LFS)

编译脚本编写

内核编译流程其实只有两步:

  1. 生成对应设备的配置文件 make <theDefConfig>
  2. 开始编译内核 make

您可以直接执行这些指令进行编译(参数设置一定要正确),或参考我下面的编译流程:

1. 设置编译链环境

最简单的设置环境办法就是将编译链工具的路径添加到系统路径中,例如:

export PATH="<absolute/path/to/ur/toolchains>/bin:$PATH"
# 例如,您正在使用 neutron-clang
# export PATH="home/user/toolchains/neutron-clang/bin:$PATH"
# 其中的路径必须为绝对路径

如果您在使用 gcc,可能还需要将 gcc 工具链的路径加入到环境变量中。

2. 简易配置脚本

首先给出一个最基础的配置脚本:

#!/bin/bash
args="-j$(nproc --all) \
O=out \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
CC=clang \
CROSS_COMPILE_COMPAT=arm-linux-gnueabi- "
make ${args} <config name>
make ${args}

该脚本是在使用上一节的三个工具时才可以正常使用的,如果您使用其他工具可以需要进行其他配置。

下面是一些参数对应的说明:

参数 说明 一般参数
CC 指定使用的编译器,因为 make 默认使用 gcc,因此实际上只有你在使用 clang 进行编译的时候才会使用该参数 clang
CROSS_COMPILE 您的主要交叉编译链工具,如果你在使用谷歌的 gcc 4.9,请指定参数为 aarch64-linux-android-,32 位同理 aarch64-linux-gnu-
CLANG_TRIPLE 只在使用 clang 进行编译的时候才需要使用,用于指定当 clang 不生效时候使用的工具链,但在使用上一节我们提到的工具中基本不用设置该参数 aarch64-linux-gnu-
CROSS_COMPILE_ARM32 只在编译 32 位内核或者带 vdso 补丁的内核时需要指定该参数 arm-linux-gnueabi-
CROSS_COMPILE_COMPAT 类似于参数 CROSS_COMPILE_ARM32 ,但内核版本为 4.19 及更新版本应使用本参数而非 CROSS_COMPILE_ARM32 arm-linux-gnueabi-

更多参数介绍可以参考一下 Neutron-Clang 的编译说明,里面对于一些参数的说明比较详细。

正常情况下,clang 是无法独立完成内核编译的,需要 gcc 的辅助。但使用上一节介绍的几种工具并不需要并不需要单独指定 gcc 来辅助编译。

3. 部分参考脚本

制作刷机包镜像

内核编译完成后的打包请参考文章[内核向] 论如何优雅的刷入内核,目前最流行的方法是使用 osm0sis/AnyKernel3 来完成整个内核的打包刷入工作。

如果您更喜欢自己动手,那么请参考文章内的其他方法。

值得注意的是,不同版本的内核编译出来的内容并不相同,因此需要区分他们之间的打包,详情请参考文章:关于 Image.xx-dtb 和 Image.xx + dtb 的区别

来自文章的评论区:_对应芯片组的。比如 865 只需要 kona-v2.1.dtb。如果弄不清楚,可以使用 cat 命令将多个 dtb 连接在一起,bootloader 会自动识别。

编译常见问题

本教程将基于小米 10S 的内核源码进行实例,其他型号的手机请自行寻找内核源码。具体内容可以参考我的内核编译项目

1. -Werror=implicit-int

/arch/arm64/kernel/smp.c:834:8: error: type defaults to ‘int’ in declaration of ‘in_long_press’ [-Werror=implicit-int]

您可以修改 extern in_long_pressextern int in_long_press;或者去除MakeFile 中对应错误限制

参考

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[Android]从零开始的内核编译 的相关文章

随机推荐

  • 决策树应用实例③——银行借贷模型

    决策树系列目录 文末有惊喜彩蛋 决策树 信息熵 信息增益 基尼系数 决策树 决策树算法原理 ID3 C4 5 CART 决策树 决策树参数介绍 分类和回归 决策树 决策树Sklearn调参 GridSearchCV调参及过程做图 决策树 P
  • NoSQL数据库简介

    NoSQL代表 不仅是SQL 指的是一种数据库管理系统 旨在处理大量非结构化和半结构化数据 与使用具有预定义架构的表格格式的传统SQL数据库不同 NoSQL数据库是无模式的 并且允许灵活和动态的数据结构 NoSQL数据库是必需的 因为它们可
  • 解决:Not creating XLA devices, tf_xla_enable_xla_devices not set

    解决 Not creating XLA devices tf xla enable xla devices not set 实验环境 提示如下 分析原因 解决方法 实验环境 Windows 10 NVIDIA GeForce GTX 105
  • 易经中的一些见解

    曾仕强教授 易经不只是用来趋吉避凶 低端讲法 高端讲法 持正向善 云端讲法 心安理得 求得好死 好死指的是死得其时 死得其所 死得心安理得 趋吉避凶是手段 不是目的 顺自然 重人伦 自作自受 缺角 修治 完人 慎始 反省提升 善终 人生的乐
  • InvokeHelper调用引发异常

    代码原来的实现是 try InvokeHelper catch GetLastError 好吧 引发了异常 但是GetLastError 永远为零 状况了 网上又找不到相关资料 知道自己一步一步地从InvokeHelper跟踪进去 发现里面
  • Spring Cloud OpenFeign 超时设置与开启重试

    超时设置 数据中台HRestful API请求 feign okhttp enabled true client config default 日志打印级别 loggerLevel basic 跨服务接口请求超时 readTimeout 2
  • Windows操作系统截屏快捷键

    1 Print Screen截屏 不只是win10系统独有的 只要在键盘上按下 Print Screen 键 就会截取当前屏幕并储存在剪切板中 进入文档编辑器 文本文档除外 图片处理工具 QQ等聊天窗口进行粘贴 Ctrl V 操作 就可以获
  • os.path函数简要分析

    os模块简介 os模块实现了在路径上的一些有用的功能 os path abspath path 返回一个绝对路径名 import os path abspath os path abspath User home Work print ab
  • 静态代码扫描环境搭建(mac)

    一 安装要求 1 1 软件要求 在进行sonarqube环境安装和搭建前务必确定当前机器和平台配置满足如下要求 机器上需要安装java Oracle JRE 11 或 OpenJDK 11 SonarQube服务器需要的java版本为11
  • 数据分析-数据清洗与整理

    1 数据清洗 第一步 对异常值进行处理 首先 查看原数据库是否一样 然后 查询是否信息录入时出现错误 最后 看看是不是顾客随意填写的信息 第二步 对离群值进行处理 首先 查询是否与原数据库一致 然后 查询是否信息录入错误 最后 判断是否符合
  • Selenium成长之路-18多窗口切换

    在实际测试过程中 打开多窗口是进行测试是很正常的事情 那么在自动化测试中 也需要开启多窗口来进行测试 我们来分析一下 打开多窗口测试的思路 1 打开一个目标网页 2 再次打开新的网页 3 获得所有窗口的 4 循环判断窗口是否为当前窗口 5
  • 2024最强秋招八股文(精简、纯手打)

    7 28日已更新 错误已修改 有错误的地方 欢迎大家留言 目录 一 Java基础篇 1 接口和抽象类的区别 2 重载和重写的区别 3 和equals的区别 4 异常处理机制 5 HashMap原理 6 想要线程安全的HashMap怎么办 7
  • 让idea自动生成类关系图

    学习了解一些开源的工具源码 有时需要了解到程序入口及项目类之间的关系 Idea工具提供了这个功能 以Jmeter5 1 1源码为例 看下RemoteJMeterEngineImpl类的关系图 操作方法 1 定位到RemoteJMeterEn
  • 窗体的扩展样式GWL_EXSTYLE: 用于SetWindowLong

    SetWindowLong Handle GWL EXSTYLE GetWindowLong Handle GWL EXSTYLE or WS EX TRANSPARENT or WS EX LAYERED WS EX ACCEPTFILE
  • 若依框架主子表数据导出问题

    一 使用若依框架导出主子表数据因为返回的数据中含有子表的集合信息 导致excel表格中多出一行标题 二 在Controller层写入导出的方法 三 这边返回的数据是主表的数据 主表数据的实体类中含有子表的集合信息 四 如果不想要子表信息就把
  • 车载无线控制服务器,车载无线视频监控系统应用整体解决方案

    车载视频监控系统整体描述 前言 现如今社会存在一些不良分子扰乱社会治安 盗窃 抢劫 斗殴 民事纠纷 面对这些突发现象 在公安执法 治安巡逻的过程中 很多时候都要随时把过程记录下来 作为记录 取证 证明等各种用途 这时候车载无线视频监控系统起
  • Passing the Message HDU - 3410(单调栈模板题,简单应用)

    题意 现在有n个人站成一行 告诉你每个人的身高 现在每个人都要找到在他左边 比他矮的人中最高的人的位置 同时也要找到 在他右边比他矮的人中最高的人的位置 注意由于他们是站成一行的 所以他们不能越过比他们高的人去看后面的人 也就是说 他只能看
  • IDEA设置忽略idea文件和iml文件

    1 File gt Settings 2 Editor gt File Types 3 红框那里填上 iml idea
  • C语言中的宏定义

    1 简单宏定义 简单的宏定义有如下格式 define指令 简单的宏 define 标识符替换列表 替换列表是一系列的C语言记号 包括标识符 关键字 数 字符常量 字符串字面量 运算符和标点符号 当预处理器遇到一个宏定义时 会做一个 标识符
  • [Android]从零开始的内核编译

    从零开始的内核编译 本教程将基于小米 10S 的内核源码进行实例 其他型号的手机请自行寻找内核源码 具体内容可以参考我的内核编译项目 手机型号查询 1 获取设备 手机 代号 在安卓设备终端 adb shell 上执行 getprop gre