第一次拿到NanoPi K2开发板是几个月之前了,当时就出现了使用store固件正常,下载的内核源码不做任何修改,编译后下载进去Android系统无法启动。当时还记录了文档NanoPi K2 (Amlogic S905) 自行编译内核启动不起来,并邮件咨询厂家,他们一直觉得是我个人的问题,出于不想当新产品的小白鼠的想法,当时这个问题就搁置在这了。最近不得硬着头皮再拾起来研究。
由于我没有做任何改动,只是编译一下就启动不起来,这着实让人费解,怀疑过交叉工具链的问题,系统环境的问题等等,甚至想过是不是必须和Android系统一样新编译才可以。这些一个一个都排除了,还是没有找到问题。当时记录的文档NanoPi K2 (Amlogic S905) 自行编译内核启动不起来里有整个内核启动Log,这次也使用logcat查看了Android的Log,截取到了关键Log信息:
I/DEBUG ( 1797): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 1797): Build fingerprint: 'Android/nanopi_k2/nanopi-k2:5.1.1/LMY48G/tony12261955:userdebug/dev-keys'
I/DEBUG ( 1797): Revision: '0'
I/DEBUG ( 1797): ABI: 'arm'
I/DEBUG ( 1797): pid: 2878, tid: 2878, name: surfaceflinger >>> /system/bin/surfaceflinger <<<
I/DEBUG ( 1797): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
I/DEBUG ( 1797): Abort message: 'no suitable EGLConfig found, giving up'
I/DEBUG ( 1797): r0 00000000 r1 00000b3e r2 00000006 r3 00000000
I/DEBUG ( 1797): r4 f74b7e38 r5 00000006 r6 00000002 r7 0000010c
I/DEBUG ( 1797): r8 ab6de550 r9 00000000 sl 00000000 fp 00000001
I/DEBUG ( 1797): ip 00000b3e sp ffcbda30 lr f742514d pc f744a938 cpsr 600f0010
I/DEBUG ( 1797):
I/DEBUG ( 1797): backtrace:
I/DEBUG ( 1797): #00 pc 0003c938 /system/lib/libc.so (tgkill+12)
I/DEBUG ( 1797): #01 pc 00017149 /system/lib/libc.so (pthread_kill+52)
I/DEBUG ( 1797): #02 pc 00017d67 /system/lib/libc.so (raise+10)
I/DEBUG ( 1797): #03 pc 000144f5 /system/lib/libc.so (__libc_android_abort+36)
I/DEBUG ( 1797): #04 pc 000129f0 /system/lib/libc.so (abort+4)
I/DEBUG ( 1797): #05 pc 00007c55 /system/lib/libcutils.so (__android_log_assert+88)
I/DEBUG ( 1797): #06 pc 00028ad9 /system/lib/libsurfaceflinger.so
I/DEBUG ( 1797): #07 pc 000286d5 /system/lib/libsurfaceflinger.so
I/DEBUG ( 1797): #08 pc 00018a39 /system/lib/libsurfaceflinger.so (android::SurfaceFlinger::init()+148)
I/DEBUG ( 1797): #09 pc 00000af1 /system/bin/surfaceflinger
I/DEBUG ( 1797): #10 pc 000123a1 /system/lib/libc.so (__libc_init+44)
I/DEBUG ( 1797): #11 pc 00000c08 /system/bin/surfaceflinger
I/DEBUG ( 1797):
I/DEBUG ( 1797): Tombstone written to: /data/tombstones/tombstone_02
由Log可以看到是surfaceflinger没有启动起来,这个是显示相关的。再结合之前了解到的自行编译的内核,系统中预置的内核模块加载不进去。其中和显示相关的是mali.ko这个是GPU的内核模块,位置是/boot/mali.ko。手动加载一下:
shell@nanopi-k2:/system # insmod /boot/mali.ko
[ 813.219045@0] module mali: unsupported RELA relocation: 275
insmod: init_module '/boot/mali.ko' failed (Exec format error)
shell@nanopi-k2:/system #
这个错误信息unsupported RELA relocation: 275
成为了破案的关键。开始以为这是mali.ko模块里打印出来的呢,最后在内核里搜索了一下才知道其是内核中打印的。具体的位置在:arch/arm64/kernel/module.c
的382行
int apply_relocate_add(Elf64_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
/* Perform the static relocation. */
switch (ELF64_R_TYPE(rel[i].r_info)) {
/* Null relocations. */
case R_ARM_NONE:
case R_AARCH64_NONE:
ovf = 0;
break;
/* Data relocations. */
...
case R_AARCH64_CALL26:
break;
default:
pr_err("module %s: unsupported RELA relocation: %llu\n",
me->name, ELF64_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
...
return -ENOEXEC;
}
这是一个switch语句,能进入default里,说明275
应该是一个常量,搜索到在arch/arm64/include/asm/elf.h
里
...
#define R_AARCH64_ADR_PREL_PG_HI21 275
...
其在这个switch语句被CONFIG_ARM64_ERRATUM_843419
宏给条件编译了,如下:
#ifndef CONFIG_ARM64_ERRATUM_843419
...
case R_AARCH64_ADR_PREL_PG_HI21:
ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
AARCH64_INSN_IMM_ADR);
break;
#endif
case R_AARCH64_ADD_ABS_LO12_NC:
而这个CONFIG_ARM64_ERRATUM_843419
正是y
。经查这个配置的位置在:
Kernel Features --->
ARM errata workarounds via the alternatives framework --->
[ ] Cortex-A53: 843419: A load or store might access an incorrect address
将其去掉选中,重新编译内核后,按照wiki上的方法更新内核:
adb shell mount -t ext4 /dev/block/mmcblk0p1 /storage/sdcard1/
adb push arch/arm64/boot/Image /storage/sdcard1/
adb push arch/arm64/boot/dts/amlogic/nanopi-k2.dtb /storage/sdcard1/
adb reboot
就这一行代码困扰好长时间,以后会遇到网上查不到的问题,不能心急,硬着头皮解决了也不错。厂家release源码的时候应该好好的验证,这样自家的板子才能有更多的人使用。