小米平板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-2026 CODEPRJ.COM