出現「您的設備內部出現了問題。請聯繫您的設備製造商瞭解詳情」錯誤後,kernel的配置問題查找

您的設備內部出現了問題。請聯繫您的設備製造商瞭解詳情。
1. 文件:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java中判斷Build.isBuildConsistent的值進行檢查java

15411     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
		   ……
5601             if (!Build.isBuildConsistent()) {
15602                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15603                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15604             }
	       ……
  1. isBuildConsistent函數在frameworks/base/core/java/android/os/Build.java中其中IS_TREBLE_ENABLED是進行兼容性判斷的關鍵判斷,這個值來自於屬性ro.treble.enabled。繼續查看發現 int result = VintfObject.verifyWithoutAvb();爲判斷設備兼容性的關鍵函數。
962     /** 963 * True if Treble is enabled and required for this device. 964 * 965 * @hide 966 */
	 967     public static final boolean IS_TREBLE_ENABLED =
	 968         SystemProperties.getBoolean("ro.treble.enabled", false);
	 969 
	 970     /** 971 * Verifies the current flash of the device is consistent with what 972 * was expected at build time. 973 * 974 * Treble devices will verify the Vendor Interface (VINTF). A device 975 * launched without Treble: 976 * 977 * 1) Checks that device fingerprint is defined and that it matches across 978 * various partitions. 979 * 2) Verifies radio and bootloader partitions are those expected in the build. 980 * 981 * @hide 982 */  
	 983     public static boolean isBuildConsistent() {
	 984         // Don't care on eng builds. Incremental build may trigger false negative.
	 985         if (IS_ENG) return true;
	 986 
	 987         if (IS_TREBLE_ENABLED) {
	 988             // If we can run this code, the device should already pass AVB.
	 989             // So, we don't need to check AVB here.
	 990             int result = VintfObject.verifyWithoutAvb();
	 991 
	 992             if (result != 0) {
	 993                 Slog.e(TAG, "Vendor interface is incompatible, error="
	 994                         + String.valueOf(result));
	 995             }    
	 996 
	 997             return result == 0;
	 998         }
VintfObject.verifyWithoutAvb()---->
		frameworks/base/core/java/android/os/VintfObject.java--->
			public static native int verifyWithoutAvb();--->
				core/jni/android_os_VintfObject.cpp --->
					{"verifyWithoutAvb", "()I", (void*)android_os_VintfObject_verifyWithoutAvb}, ---->
					static jint android_os_VintfObject_verifyWithoutAvb(JNIEnv* env, jclass) { ---->
					static jint verify(JNIEnv* env, jobjectArray packageInfo, android::vintf::DisabledChecks checks) {--->
						int32_t status = VintfObject::CheckCompatibility(cPackageInfo, &error, checks);
VintfObject::CheckCompatibility函數成爲了關鍵函數,繼續排查發如今system/libvintf/VintfObject.cpp中,
	system/libvintf/VintfObject.cpp--->
		 return details::checkCompatibility(xmls, false /* mount */, *details::gPartitionMounter, error,disabledChecks); --->
			int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount,

此時checkCompatibility函數成爲了咱們的突破口,函數中的判斷髮現logcat中的關鍵打印:
"Runtime info and framework compatibility matrix are incompatible: "
在logcat中發現:android

W VintfObject: VintfObject.verify() returns 1: Runtime info and framework compatibility matrix are incompatible: For config CONFIG_NFS_FS, value = y but required n
	E Build   : Vendor interface is incompatible, error=1
	E ActivityManager: Build fingerprint is not consistent, warning user
此時找到了關鍵問題點,就是CONFIG_NFS_FS的不該該爲Y應該爲N,可是這個是怎麼查找到的呢?
	
	if (!updated.runtimeInfo->checkCompatibility(*updated.fwk.matrix, error, disabledChecks)) {---->
		RuntimeInfo.cpp ----->
			bool RuntimeInfo::checkCompatibility(const CompatibilityMatrix& mat, std::string* error,

	如今發現,忽然沒了頭緒,想到了以前error信息:
	「For config CONFIG_NFS_FS, value = y but required n」

	這個判斷確定是RuntimeInfo::checkCompatibility函數中返回,因此搜了下發現繼續進行下去:
		if (!matchKernelConfigs(matrixKernel.conditions(), error)) { --->
			bool RuntimeInfo::matchKernelConfigs(const std::vector<KernelConfig>& matrixConfigs,
	在RuntimeInfo::matchKernelConfigs函數中找到了關鍵的錯誤信息打印,並找到對應的判斷:
		if (!matrixConfig.second.matchValue(kernelValue)) {

到這發現是對kernel的信息進行比對,可是信息從哪裏來呢?比對的信息又從哪裏來呢?陷入了僵局
進行長時間博客谷歌查找再google的介紹裏面找到了關鍵的兼容性介紹,連接以下:
https://source.android.google.cn/devices/architecture/vintf/match-rules#avb-version
其中內核匹配不就是咱們想要的信息:web

選擇適當的 部分後,對於值不爲 n 的每一個 項,咱們預計對應條目會存在於
/proc/config.gz 中;對於值爲 n 的每一個 項,咱們預計對應條目不會存在於 /proc/config.gz
中。咱們預計 的內容與等號後面的文本(包括引號)徹底匹配,直到換行符或 #,開頭和結尾的空格被截斷。bash

這個config不就是咱們想要的信息;
在介紹的開始有一個信息的連接:
https://source.android.google.cn/devices/architecture/vintf/objects#runtime-collectible-information
這個連接裏面介紹了相關的清單,和信息來源,此時仍是懵逼,不過有個信息很重要:ide

<!-- Comments, Legal notices, etc. here -->
	<manifest version="1.0" type="device" target-level="1">
	    <!-- hals ommited -->
	    <kernel version="4.4.176">
	        <config>
	            <key>CONFIG_ANDROID</key>
	            <value>y</value>
	        </config>
	        <config>
	            <key>CONFIG_ARM64</key>
	            <value>y</value>
	        </config>
	    <!-- other configs ommited -->
	    </kernel>
	</manifest>

可是此時我並無發現他的重要性,不過讓我知道了有這個列表,但是這個列表在哪呢?查找了源碼仍是一無所得
在system/libvintf目錄中搜索了下「kernel version」發現不通常了:svg

test/vintf_object_tests.cpp文件中
	1222 //
	1223 // Set of framework matrices of different FCM version with <kernel>.
	1224 //
	1225 
	1226 #define FAKE_KERNEL(__version__, __key__)                   \
	1227     " <kernel version=\"" __version__ "\">\n"            \
	1228     " <config>\n"                                    \
	1229     " <key>CONFIG_" __key__ "</key>\n"           \
	1230     " <value type=\"tristate\">y</value>\n"      \
	1231     " </config>\n"                                   \
	1232     " </kernel>\n"
	當我看到FAKE_KERNEL定義的時候瞬間通透了,原來他是生成出來的,繼續往下看
	1234 const static std::vector<std::string> systemMatrixKernelXmls = {
	1235     // 1.xml
	1236     "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n"
	1237     FAKE_KERNEL("1.0.0", "A1")
	1238     FAKE_KERNEL("2.0.0", "B1")
	1239     "</compatibility-matrix>\n",
	1240     // 2.xml
	1241     "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"2\">\n"
	1242     FAKE_KERNEL("2.0.0", "B2")
	1243     FAKE_KERNEL("3.0.0", "C2")
	1244     FAKE_KERNEL("4.0.0", "D2")
	1245     "</compatibility-matrix>\n",
	1246     // 3.xml
	1247     "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"3\">\n"
	1248     FAKE_KERNEL("4.0.0", "D3")
	1249     FAKE_KERNEL("5.0.0", "E3")
	1250     "</compatibility-matrix>\n",
	1251 };

經過這個發現了xml的關鍵節點,妥了,去編譯出來的文件中去查以前的錯誤CONFIG_NFS_FS函數

system/etc/vintf/compatibility_matrix.3.xml:972:            <key>CONFIG_NFS_FS</key>
	system/etc/vintf/compatibility_matrix.3.xml:1758:            <key>CONFIG_NFS_FS</key>
	system/etc/vintf/compatibility_matrix.3.xml:2552:            <key>CONFIG_NFS_FS</key>
	system/etc/vintf/compatibility_matrix.2.xml:796:            <key>CONFIG_NFS_FS</key>
	system/etc/vintf/compatibility_matrix.2.xml:1434:            <key>CONFIG_NFS_FS</key>
	system/etc/vintf/compatibility_matrix.2.xml:2108:            <key>CONFIG_NFS_FS</key>
	system/compatibility_matrix.xml:976:            <key>CONFIG_NFS_FS</key>
	system/compatibility_matrix.xml:1762:            <key>CONFIG_NFS_FS</key>
	system/compatibility_matrix.xml:2556:            <key>CONFIG_NFS_FS</key>

這一瞬間,感受本身受到了極大的侮辱,原來如此;一切都通透了,一一匹配,對應而後查找
全部的配置中:ui

<config>
     <key>CONFIG_NFS_FS</key>
     <value type="tristate">n</value>
 </config>

報錯了,這下方便了,查找文件生成就行了:
繼續查找其中與kernel version匹配的配置,compatibility_matrix.2.xml最爲符合查找生成的位置:
hardware/interfaces/compatibility_matrices/Android.mk:this

49 include $(CLEAR_VARS)
	 50 include $(LOCAL_PATH)/clear_vars.mk
	 51 LOCAL_MODULE := framework_compatibility_matrix.2.xml
	 52 LOCAL_MODULE_STEM := compatibility_matrix.2.xml
	 53 LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
	 54 LOCAL_KERNEL_CONFIG_DATA_PATHS := \
	 55     3.18.0:$(my_kernel_config_data)/o-mr1/android-3.18 \
	 56     4.4.0:$(my_kernel_config_data)/o-mr1/android-4.4 \
	 57     4.9.0:$(my_kernel_config_data)/o-mr1/android-4.9 \
	 58 
	 59 include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)

匹配找到對應的目錄,而後進行修改就完事了google

感謝博客:http://www.javashuo.com/article/p-beqjcskr-nm.html 提供很重要的思路