小米平板3安卓内核编译研究笔记


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(看上面脚本环境变量的设置),所以直接忽略掉其他平台目录的修改
提一下,在目前的粗略研究之后有以下发现,

  1. MTK本身提供了一套快速配置芯片的工具,和内核放一起了(tools/dct),它能够生成arch/arm或arm64代码(根据该目录下代码注释中有Generated by MTK SP Drv_CodeGen)
  2. 小米对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

  1. 可以全局搜索Copyright (C) 2018 XiaoMi, Inc.,虽然不是所有被小米修改过的文件,但一定很关键,MTK同理


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM