1. 编译可用内核
1.1 准备
内核链接:https://github.com/MiCode/Xiaomi_Kernel_OpenSource/tree/cappu-n-oss
对应安卓N,就是版本7
基本工具:奇兔两件套:奇兔刷机和线刷大师,后者救砖用
编译环境:Ubuntu 20.04
主要编译工具:在下面第一个教程链接里
开始之前一定要备份好数据,解除屏幕锁和小米账户锁
推荐提前在http://www.miui.com/download-329.html准备好卡刷包和线刷包(这个在“下载完整包”旁边的“教程”里)
如果刷机过程中遇到问题,是可以救命的(保底方法进fastboot刷线刷包)
奇兔recovery在奇兔刷机的工具箱里有,在fastboot下刷入,注意刷入后不要点下面的重启,要自己手动重启。如果一遍不行需要第二遍。
音量键上+开机键=recovery,音量键下+开机键=fastboot
1.2 步骤
参考大佬的教程,首先看这个
https://blog.csdn.net/u014418171/article/details/82659887
里面提到的工具android image kitchen下载链接
https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/
补充阅读
https://github.com/MiCode/Xiaomi_Kernel_OpenSource/wiki/How-to-compile-kernel-standalone
https://github.com/MiCode/Xiaomi_Kernel_OpenSource/issues/957
https://www.cnblogs.com/codex/p/13414213.html
一个简单的编译脚本,要自己根据实际情况改
mkdir out
export ARCH=arm64
export SUBARCH=arm64
export CROSS_COMPILE=~/androidkernel/toolchain_aarch64/google_gcc/aarch64-linux-android-4.9/bin/aarch64-linux-android-
sudo chmod -R 777 ./
make O=out xiaomi8176_tb_c9_n_defconfig
make -j$(nproc) O=out 2>&1 | tee kernel.log
就我个人经历,只要linux环境变量正确,defconfig配置文件找对了(xiaomi8176_tb_c9_n_defconfig),make是一步到位的。然后编译出来的文件按第一个教程,解包目前运行的系统的线刷包(如果不确定最好先刷一遍)的boot.img,替换掉boot.img-kernel,再打包,刷入即可。adb工具奇兔里有。没有出现驱动缺失问题。这样看来,比隔壁高通平台编译还简单亿点,可惜二次开发比不上。
可以在安兔兔里查看内核版本。编译日期会是最新的。也可以在系统设置里连续点击“内核版本”,进入CIT后查看详细版本信息。
2. 内核对比(未完结)
2.1 概述
2.1.1 准备
在该环节,我们的目的是研究MIUI提供的内核和原版本的内核(开源在https://android.googlesource.com/)之间的差异,从而了解MTK平台在内核上有哪些不同,为之后的移植做铺垫(如果还有机会的话)
由于能力有限,分析会不够严谨,请读者多海涵,并且能理性探讨。
MTK目录下的内核链接(版本号3.18):https://android.googlesource.com/kernel/mediatek/+/refs/heads/android-3.18
我们可以看到版本迭代记录:https://android.googlesource.com/kernel/mediatek/+log/a178462e7c4eef47f777571316a5194f4d879a50/Makefile
在写作前,我已经尝试过根据3.18.35和3.18.36版本差异(diff),手动将小米内核更新至3.18.36,并且成功在真机上运行。所以我这次用的是3.18.36版本来分析。读者也可以用3.18.35版本。
分析工具:Github Desktop
本文的读者应该都会用github,但是不知道Github Desktop用的人多不多。用这个工具,是因为它能够用图形界面显示版本之间的差异,比较方便。
网上有推荐Beyond Compare,不过我认为在代码对比分析这块还不如Github Desktop,时代变了,或许有更好的工具,大佬们可以推荐给我。
补充一下,ubuntu不要用root用户登录,否则打不开,和vscode一样。
建立一个repository,将原版本的内核代码复制进对应的目录,修改权限(这个很重要,不然权限不同软件里面也会显示修改,导致所有文件都会显示出来)
sudo chmod -R 777 ./
改完就可以commit,简便起见就一个main分支。然后把里面的文件除了.git文件夹都删了,把小米内核代码复制进去,执行上述命令。如果Github Desktop里显示出修改了,那就成功了。
这样被修改的文件也很多,可以一个个文件夹替换掉再分析。每次替换都要执行上述命令。
2.1.2 目录概览
android:安卓内核配置
arch:不同平台体系相关代码
block:块设备驱动
certs:与认证和签名相关代码
crypto:内核常用加密、压缩算法等代码
documentation:描述模块功能和协议规范
drivers:驱动程序(USB总线、PCI总线、显卡驱动等)
firmware:二进制固件
fs:虚拟文件系统代码
include:内核代码依赖的绝大部分头文件
init:内核初始化代码,联系到内存各组件入口
ipc:进程间通信实现,比如共享内存、信号量、匿名管道等
kernel:内核核心代码,包括进程管理、IRQ、时间等
lib:C标准库的子集
mm:内存管理相关实现
net:网络协议代码,比如TCP、IPv6、WiFi、以太网实现等
samples:内核示例代码
scripts:编译和配置内核所需脚本;perl/bash
security:内核安全模型相关代码,如selinux
sound:声卡驱动代码
tools:与内核交互/开发工具
usr:用户打包和压缩内核的实现代码
virt:/kvm虚拟化目录相关支持实现
2.2 android目录
2个不同文件,都是配置
android/configs/android-base.cfg
android/configs/android-recommended.cfg
2.3 Arch目录
我们是arm64(看上面脚本环境变量的设置),所以直接忽略掉其他平台目录的修改
提一下,在目前的粗略研究之后有以下发现,
- MTK本身提供了一套快速配置芯片的工具,和内核放一起了(tools/dct),它能够生成arch/arm或arm64代码(根据该目录下代码注释中有Generated by MTK SP Drv_CodeGen)
- 小米对thread_info.h作了修改,以下是变动(除arm64之外架构),以arch/alpha/include/asm/thread_info.h为例
@@ -46,6 +46,7 @@
struct thread_info {
struct exec_domain *exec_domain;/* execution domain */
__u32 cpu; /* current CPU */
unsigned long thr_ptr; /* TLS ptr */
+ struct restart_block restart_block;
};
@ -61,6 +62,9 @@
struct thread_info {
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
}
#define init_thread_info (init_thread_union.thread_info)
@ @@
在搜索restart_block结构体后,发现结果都很古老,是linux2.x时代的产物。
以下是arch/arm64/include/asm/thread_info.h
@ -48,11 +48,11 @@ struct thread_info {
mm_segment_t addr_limit; /* address limit */
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
- #ifdef CONFIG_ARM64_SW_TTBR0_PAN
- u64 ttbr0; /* saved TTBR0_EL1 */
- #endif
+ struct restart_block restart_block;
int preempt_count; /* 0 => preemptable, <0 => bug */
int cpu; /* cpu */
+ void *regs_on_excp; /* aee */
+ int cpu_excp; /* aee */
};
#define INIT_THREAD_INFO(tsk) \
@ -62,6 +62,10 @@ struct thread_info {
.flags = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+ .cpu_excp = 0, /* aee */ \
}
#define init_thread_info (init_thread_union.thread_info)
@ -77,16 +81,10 @@ register unsigned long current_stack_pointer asm ("sp");
*/
static inline struct thread_info *current_thread_info(void) __attribute_const__;
- /*
- * struct thread_info can be accessed directly via sp_el0.
- */
static inline struct thread_info *current_thread_info(void)
{
- unsigned long sp_el0;
-
- asm ("mrs %0, sp_el0" : "=r" (sp_el0));
-
- return (struct thread_info *)sp_el0;
+ return (struct thread_info *)
+ (current_stack_pointer & ~(THREAD_SIZE - 1));
}
#define thread_saved_pc(tsk) \
@ -123,6 +121,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK 20
#define TIF_SINGLESTEP 21
#define TIF_32BIT 22 /* 32bit process */
+ #define TIF_SWITCH_MM 23 /* deferred switch_mm */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
@ @@
注释中出现了aee,经查询,推测是MTK平台用于侦测Android手机系统异常重启的一套系统机制
参考链接:https://www.cnblogs.com/programandriod/p/13868599.html
- 可以全局搜索Copyright (C) 2018 XiaoMi, Inc.,虽然不是所有被小米修改过的文件,但一定很关键,MTK同理