Este artigo discutirá a proteção de software no processador S905X. O objetivo final é lançar software não autorizado.S905X
O processador S905X é um ARM Cortex-A53 com uma frequência de clock de até 1,5 GHz, repleto de todos os tipos de decodificadores para fluxos de vídeo e áudio, como H.265 4K, VP9, suportando 4KUHD, etc. Em geral, não é uma má escolha. Diferentemente de seu antecessor, o AMLogic integrou o chamado "sistema de segurança Advanced TrustZone" neste processador, que controla todas as operações críticas do sistema, como acessar áreas protegidas da memória ROM, verificar a assinatura e descriptografar o software, etc. Documentação detalhada sobre esse tópico pode ser encontrada no site do fabricante . O SecureOS atua como ATOS-V1.5-g3e467d9 (não afirmo, não verifiquei).Treinamento
Depois de desmontar o prefixo, encontrei facilmente os pinos RxD, TxD e GND para o UART. No verso, havia um conector para o botão de reinicialização (não verificado) e um local para o conector. A julgar pela localização, o conector parecia uma placa-a-placa para uma placa eMMS alternativa (a pinagem está naturalmente ausente).
A documentação de acesso livre para tópicos importantes do S905 como, por exemplo, a sequência de inicialização não afetou muito ou menos e foi praticamente inútil do ponto de vista do ER. Colocando a documentação de lado, conectei o UART e ... fiquei agradavelmente surpreendido com a velocidade de carregamento do processador. Mas isso é provavelmente tudo. O U-Boot não reagiu de maneira alguma ao teclado e, após algumas configurações de hardware, carregou e lançou o kernel Android de forma inteligente.U-Boot'a log de inicialização GXL:BL1:9ac50e:bb16dc;FEAT:BDFC31BC:0;POC:3;RCY:0;EMMC:0;READ:0;0.0;0.0;CHK:0;
TE: 351954
BL2 Built : 16:42:36, Nov 3 2016.
gxl g3eddb43 - xiaobo.gu@droid05
set vcck to 1120 mv
set vddee to 1000 mv
Board ID = 4
CPU clk: 1200MHz
DQS-corr enabled
DDR scramble enabled
DDR3 chl: Rank0+1 @ 768MHz - FAIL
DDR3 chl: Rank0 @ 768MHz - PASS
Rank0: 1024MB(auto)-2T-11
DataBus test pass!
AddrBus test pass!
-s
Load fip header from eMMC, src: 0x0000c200, des: 0x01400000, size: 0x00004000
aml log : R2048 check pass!
New fip structure!
Load bl30 from eMMC, src: 0x00010200, des: 0x01700000, size: 0x0000d600
aml log : R2048 check pass!
Load bl31 from eMMC, src: 0x00020200, des: 0x01700000, size: 0x00015400
aml log : R2048 check pass!
Load bl32 from eMMC, src: 0x00038200, des: 0x01700000, size: 0x00035a00
aml log : R2048 check pass!
Load bl33 from eMMC, src: 0x00070200, des: 0x01700000, size: 0x000aa200
aml log : R2048 check pass!
NOTICE: BL3-1: v1.0(debug):fb68908
NOTICE: BL3-1: Built : 18:30:11, Nov 1 2016
aml log : bl31 detect secure boot !
[Image: gxl_v1.1.3154-065f772 2016-09-29 14:08:54 yan.wang@droid05]
OPS=0x84
bc fc af 5f a2 b4 4d 4b 1c 91 59 9f [1.280536 Inits done]
secure task start!
high task start!
low task start!
INFO: BL3-1: Initializing runtime services
INFO: BL3-1: Initializing BL3-2
INFO: BL3-2: ATOS-V1.5-g3e467d9 #1 Mon Aug 22 17:11:43 CST 2016 arm
INFO: BL3-2: chip version = RevC (21:C - 0:0)
INFO: BL3-2: crypto engine DMA
INFO: BL3-2: secure time TEE
INFO: BL3-1: Preparing for EL3 exit to normal world
INFO: BL3-1: Next image address = 0x1000000
INFO: BL3-1: Next image spsr = 0x3c9
U-Boot 2015.01 (Nov 23 2018 - 15:50:35)
DRAM: 1 GiB
Relocation Offset is: 36ec8000
register usb cfg[0][1] = 0000000037f5e258
[CANVAS]canvas init
vpu: error: vpu: check dts: FDT_ERR_BADMAGIC, load default parameters
vpu: clk_level = 7
vpu: set clk: 666667000Hz, readback: 666660000Hz(0x300)
vpp: vpp_init
boot_device_flag : 1
Nand PHY Ver:1.01.001.0006 (c) 2013 Amlogic Inc.
init bus_cycle=6, bus_timing=7, system=5.0ns
reset failed
get_chip_type and ret:fffffffe
get_chip_type and ret:fffffffe
chip detect failed and ret:fffffffe
nandphy_init failed and ret=0xfffffff1
MMC: aml_priv->desc_buf = 0x0000000033ec86b0
aml_priv->desc_buf = 0x0000000033eca9d0
SDIO Port B: 0, SDIO Port C: 1
emmc/sd response timeout, cmd8, status=0x1ff2800
emmc/sd response timeout, cmd55, status=0x1ff2800
[mmc_startup] mmc refix success
[mmc_init] mmc init success
mmc read lba=0x14000, blocks=0x400
Amlogic multi-dtb tool
Multi dtb detected
Multi dtb tool version: v2 .
Support 2 dtbs.
aml_dt soc: gxl platform: sx6b6x variant: 1g
dtb 0 soc: gxl plat: sx6b6x vari: 1g
dtb 1 soc: gxl plat: sx6b6x vari: 2g
Find match dtb: 0
start dts,buffer=0000000033ecd270,dt_addr=0000000033ecda70
parts: 11
00: logo 0000000002000000 1
01: recovery 0000000002000000 1
02: rsv 0000000000800000 1
03: tee 0000000000800000 1
04: crypt 0000000002000000 1
05: misc 0000000002000000 1
06: instaboot 0000000020000000 1
07: boot 0000000002000000 1
08: system 0000000050000000 1
09: cache 0000000040000000 2
10: data ffffffffffffffff 4
get_dtb_struct: Get emmc dtb OK!
overide_emmc_partition_table: overide cache
[mmc_get_partition_table] skip partition cache.
Partition table get from SPL is :
name offset size flag
===================================================================================
0: bootloader 0 400000 0
1: reserved 2400000 4000000 0
2: cache 6c00000 40000000 2
3: env 47400000 800000 0
4: logo 48400000 2000000 1
5: recovery 4ac00000 2000000 1
6: rsv 4d400000 800000 1
7: tee 4e400000 800000 1
8: crypt 4f400000 2000000 1
9: misc 51c00000 2000000 1
10: instaboot 54400000 20000000 1
11: boot 74c00000 2000000 1
12: system 77400000 50000000 1
13: data c7c00000 10a400000 4
mmc read lba=0x12000, blocks=0x2
mmc read lba=0x12002, blocks=0x2
mmc_read_partition_tbl: mmc read partition OK!
eMMC/TSD partition table have been checked OK!
mmc env offset: 0x47400000
WARNING: 'recovery_from_sdcard' neither in running nor in imported env!
WARNING: 'recovery_from_udisk' neither in running nor in imported env!
In: serial
Out: serial
Err: serial
hpd_state=0
cvbs performance type = 6, table = 0
[store]To run cmd[emmc dtb_read 0x1000000 0x40000]
read emmc dtb
Amlogic multi-dtb tool
Multi dtb detected
Multi dtb tool version: v2 .
Support 2 dtbs.
aml_dt soc: gxl platform: sx6b6x variant: 1g
dtb 0 soc: gxl plat: sx6b6x vari: 1g
dtb 1 soc: gxl plat: sx6b6x vari: 2g
Find match dtb: 0
Net: dwmac.c9410000
wipe_data=successful
wipe_cache=successful
upgrade_step=2
[OSD]load fb addr from dts
[OSD]failed to get fb addr for logo
[OSD]use default fb_addr parameters
[OSD]fb_addr for logo: 0x3d800000
[OSD]load fb addr from dts
[OSD]failed to get fb addr for logo
[OSD]use default fb_addr parameters
[OSD]fb_addr for logo: 0x3d800000
[CANVAS]addr=0x3d800000 width=3840, height=2160
amlkey_init() enter!
[EFUSE_MSG]keynum is 4
[BL31]: tee size: 0
[KM]Error:f[key_manage_query_size]L507:key[deviceid] not programed yet
gpio: pin GPIOAO_2 (gpio 102) value is 1
get_cpu_id flag_12bit=1
SARADC channel(0) is 0x3e1.
SARADC closed.
Hit Enter or space or Ctrl+C key to stop autoboot -- : 0
[imgread]szTimeStamp[2019121002280214]
[imgread]secureKernelImgSz=0x977000
aml log : R2048 check pass!
aml log : R2048 check pass!
aml log : R2048 check pass!
ee_gate_off ...
## Booting Android Image at 0x01080000 ...
reloc_addr =33f4d440
copy done
Amlogic multi-dtb tool
Single dtb detected
load dtb from 0x1000000 ......
Uncompressing Kernel Image ... OK
kernel loaded at 0x01080000, end = 0x02258fd0
Loading Ramdisk to 33d12000, end 33eb6000 ... OK
Loading Device Tree to 000000001fff3000, end 000000001ffff8f4 ... OK
signature:
fdt_instaboot: no instaboot image
Starting kernel ...
Vale a pena notar que o próprio U-Boot (bl33) já estava em execução no ambiente do “mundo normal” (BL3-1 mudou o modo imediatamente antes de transferir o controle para ele). Essa. mesmo que de alguma forma assumamos o controle do U-Boot, teremos acesso limitado ao sistema. Em princípio, isso não é tão importante. Afinal, mesmo que você remova o dump da ROM, retire as chaves AES e abra o RSA do fusível, então não haverá grande sentido disso, porque ainda não há chave privada RSA.O próprio U-Boot não leu nenhuma chave. Ele carregou o kernel na memória e chamou o Security Monitor para descriptografar e verificar o código. O Security Monitor fez todo o necessário e disse ao U-Boot para carregar o kernel ou não. Em geral, uma abordagem séria à proteção de software com seu próprio TrustedOS e algum tipo de funcionalidade como o BIOS.Meu plano adicional era acessar a memória eMMC.eMMC
Para conectar-se ao eMMC, era necessário encontrar pelo menos os pinos DAT_0, CLK, CMD e GND. E também descubra em que voltagem o controlador eMMC funcionou (1V8 ou 3V3). Era impossível fazer isso visualmente e, para rastrear trilhas, eu mesmo peguei o eMMC. Como o chip estava em minhas mãos, após o rastreamento, eu o conectei ao adaptador e joguei um despejo completo. Infelizmente, eu não tinha equipamento profissional e usei materiais improvisados para isso. O resultado é um "Dead Bug".Bem, na verdade a pinagem do conector:Depois que a pinagem foi concluída, observei como o processador se comporta sem o eMMC. A julgar pelo log, a ROM após uma tentativa malsucedida de inicializar a partir do eMMC tentou carregar o código do cartão mSD. Isso foi encorajador. Carreguei rapidamente o despejo no cartão mSD e liguei o console. Uma pequena surpresa me esperava aqui. A ROM baixou o código BL2 do cartão e transferiu o controle para ele (isso significa que a seção "boot" no eMMC não estava envolvida e não havia necessidade de acesso root). Bem, quando chegou a vez do U-Boot, ele se queixou algumas vezes da falta de eMMC (dev 1) e, por um longo tempo, sem pensar, parou no terminal.cmd store failed
Err imgread(L132):Fail to read 0x100000B from part[recovery] at offset 0
gxl_sx6b6x_768_v2#version
U-Boot 2015.01 (Nov 23 2018 - 15:50:35)
aarch64-none-elf-gcc (crosstool-NG linaro-1.13.1-4.8-2013.11 - Linaro GCC 2013.10) 4.8.3 20131111 (prerelease)
GNU ld (crosstool-NG linaro-1.13.1-4.8-2013.11 - Linaro GCC 2013.10) 2.23.2.20130610 Linaro 2013.10-4
gxl_sx6b6x_768_v2#
Para começar, não foi nada mau. Após algumas experiências com o terminal, adicionei o parâmetro bootdelay = 5 à seção “env”, calculei a nova soma de verificação e soldou o eMMC de volta. Com a nova opção, eu esperava que o U-Boot pudesse ser interrompido. Mas, na prática, tudo foi diferente. Parece que o U-Boot não estava interessado nesse parâmetro e o processo de inicialização não foi diferente do normal. É triste porque era necessário um terminal com um eMMC conectado para outras ações. Com um pouco de reflexão, fechei o DAT_0 no chão e inseri meu cartão mSD. A ROM não pôde carregar o código do eMMC e passou para o mSD. Depois de carregar o U-Boot dessa maneira, abri os contatos e perguntei:gxl_sx6b6x_768_v2#mmc dev 1
emmc/sd response timeout, cmd8, status=0x1ff2800
emmc/sd response timeout, cmd55, status=0x1ff2800
[mmc_startup] mmc refix success
[mmc_init] mmc init success
mmc read lba=0x14000, blocks=0x400
Amlogic multi-dtb tool
Multi dtb detected
Multi dtb tool version: v2 .
Support 2 dtbs.
aml_dt soc: gxl platform: sx6b6x variant: 1g
dtb 0 soc: gxl plat: sx6b6x vari: 1g
dtb 1 soc: gxl plat: sx6b6x vari: 2g
Find match dtb: 0
start dts,buffer=0000000033ee4050,dt_addr=0000000033ee4850
parts: 11
00: logo 0000000002000000 1
01: recovery 0000000002000000 1
02: rsv 0000000000800000 1
03: tee 0000000000800000 1
04: crypt 0000000002000000 1
05: misc 0000000002000000 1
06: instaboot 0000000020000000 1
07: boot 0000000002000000 1
08: system 0000000050000000 1
09: cache 0000000040000000 2
10: data ffffffffffffffff 4
get_dtb_struct: Get emmc dtb OK!
overide_emmc_partition_table: overide cache
[mmc_get_partition_table] skip partition cache.
Partition table get from SPL is :
name offset size flag
===================================================================================
0: bootloader 0 400000 0
1: reserved 2400000 4000000 0
2: cache 6c00000 40000000 2
3: env 47400000 800000 0
4: logo 48400000 2000000 1
5: recovery 4ac00000 2000000 1
6: rsv 4d400000 800000 1
7: tee 4e400000 800000 1
8: crypt 4f400000 2000000 1
9: misc 51c00000 2000000 1
10: instaboot 54400000 20000000 1
11: boot 74c00000 2000000 1
12: system 77400000 50000000 1
13: data c7c00000 10a400000 4
mmc read lba=0x12000, blocks=0x2
mmc read lba=0x12002, blocks=0x2
mmc_read_partition_tbl: mmc read partition OK!
eMMC/TSD partition table have been checked OK!
switch to partitions #0, OK
mmc1(part 0) is current device
gxl_sx6b6x_768_v2#
O U-Boot não resistiu e passou para o eMMC. Eu olhei, é claro, o que estava no parâmetro bootdelay. E em vez dos meus cinco, vi 0. lá novamente.Parece que o U-Boot em algum momento anotou 0 lá, caso alguém de repente mude algo lá. Mas isso não me interessou mais e o tópico com o eMMC foi encerrado.Nota: com uma pinagem do conector, é possível conectar ao eMMC sem soldar o chip. Para fazer isso, você precisa de um adaptador especial com um conversor de tensão, porque O controlador eMMC é executado em 1V8 e se você conectar um adaptador SD comum a 3V3, existe o risco de queimar componentes no barramento 1V8.Também será necessário remover esse resistor, caso contrário, o processador irá interferir no adaptador.Componentes ausentes
Tendo acesso total ao terminal U-Boot, tive que fazer duas coisas: acessar o decodificador DeviceTree e convencer o U-Boot a recusar os serviços do Monitor de segurança relacionados à verificação do kernel. Para o primeiro lançamento, seria bom ter o kernel original, para não perder tempo depurando um novo.Foi extremamente fácil obter o DeviceTree. Eu perguntei:gxl_sx6b6x_768_v2#emmc dtb_read 0x1000000 0x40000
read emmc dtb
gxl_sx6b6x_768_v2#
e ele estava no meu bolso.O U-Boot exigiu uma análise detalhada. No log, seguiu-se que o próprio U-Boot foi carregado e descriptografado inicialmente em 0x1000000 e, posteriormente, se transferiu para 0x36ES8000 (deslocamento). Despejei o U-Boot e o analisei na IDA.Obviamente, eu estava interessado no local em que o Monitor de Segurança foi acessado a partir do comando bootm. Aqui é
ondeX0 - AML_D_P_IMG_DECRYPTX1 - nLoadAddrX2 - GXB_IMG_SIZEX3 - GXB_IMG_DEC_ALLPara remover o despejo original do kernel, você teve que carregá-lo na memória através da função imgread e modificar o bootm para que, imediatamente após chamar aml_sec_boot_check, a memória fosse emitida a partir do endereço 0x1080000 para o terminal (essa certamente não é a única maneira). Para fazer isso, escrevi um pedaço de código e o baixei no lugar certo. Aqui está o que aconteceu (é claro, não posso fornecer um log completo):gxl_sx6b6x_768_v2#imgread kernel boot
[imgread]szTimeStamp[2019121002280214]
[imgread]secureKernelImgSz=0x977000
gxl_sx6b6x_768_v2#bootm
aml log : R2048 check pass!
aml log : R2048 check pass!
aml log : R2048 check pass!
Ready for dumping kernel
41 4e 44 52 4f 49 44 21 20 d8 7b 20 20 20 08 01 | ANDROID!
Além do kernel, também obtive o ramdisk (pode ser útil caso haja drivers ou firmware importantes, por exemplo, para WiFi).Eu não sou mais Android
Para o primeiro lançamento do meu software, criei o uImage a partir do kernel original, construí meu rootfs com base no Busybox e usei meu próprio dtb. Carreguei todas as três partes diretamente da unidade USB e executei o comando “bootm”, desativando a descriptografia e a verificação de imagens antes.gxl_sx6b6x_768_v2#usb start
(Re)start USB...
USB0: USB3.0 XHCI init start
Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 2 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found
gxl_sx6b6x_768_v2#mw.l 0x37ed240c 0xd2800000
gxl_sx6b6x_768_v2#fatload usb 0:1 0x1000000 dtb.img
reading dtb.img
40960 bytes read in 43 ms (929.7 KiB/s)
gxl_sx6b6x_768_v2#fatload usb 0:1 0x2000000 uImage
reading uImage
8116288 bytes read in 4197 ms (1.8 MiB/s)
gxl_sx6b6x_768_v2#fatload usb 0:1 0x3000000 rootfs.img.uboot
reading rootfs.img.uboot
1041462 bytes read in 563 ms (1.8 MiB/s)
gxl_sx6b6x_768_v2#bootm 0x2000000 0x3000000 0x1000000
ee_gate_off ...
## Booting kernel from Legacy Image at 02000000 ...
Image Name: S905X Original
Image Type: AArch64 Linux Kernel Image (gzip compressed)
Data Size: 8116224 Bytes = 7.7 MiB
Load Address: 01080000
Entry Point: 01080000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 03000000 ...
Image Name: Root Filesystem
Image Type: AArch64 Linux RAMDisk Image (gzip compressed)
Data Size: 1041398 Bytes = 1017 KiB
Load Address: 033d1200
Entry Point: 033d1200
Verifying Checksum ... OK
Amlogic multi-dtb tool
Single dtb detected
load dtb from 0x1000000 ......
## Flattened Device Tree blob at 01000000
Booting using the fdt blob at 0x1000000
Uncompressing Kernel Image ... OK
kernel loaded at 0x01080000, end = 0x02258fd0
Loading Ramdisk to 33db8000, end 33eb63f6 ... OK
Loading Device Tree to 000000001fff3000, end 000000001ffff8f4 ... OK
fdt_instaboot: no instaboot image
Starting kernel ...
uboot time: 136710682 us
[ 0.000000@0] Initializing cgroup subsys cpu
[ 0.000000@0] Initializing cgroup subsys cpuacct
[ 0.000000@0] Linux version 3.14.29 (build@build2) (gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) ) #1 SMP PREEMPT Thu Sep 12 21:24:53 MSK 2019
[ 0.000000@0] CPU: AArch64 Processor [410fd034] revision 4
[ 6.302659@2] meson_uart c81004c0.serial: ttyS0 use xtal(8M) 24000000 change 115200 to 115200
# cat /proc/cpuinfo
Processor : AArch64 Processor rev 4 (aarch64)
processor : 0
processor : 1
processor : 2
processor : 3
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
Hardware : Amlogic
Serial : 210c84009f59911c4b4db4a25faffcbc
#
Fuga de presos
Devido ao fato de o U-Boot ter sido imunizado contra a alteração dos parâmetros env (isso envolvia não apenas o "bootdelay"), era impossível influenciar o processo de inicialização por meio do env e, para carregar seu software, o prefixo precisava ser conectado ao computador. Esta opção não combina comigo. Tendo analisado toda a cadeia de carregamento, este comando chamou minha atenção:init_display=osd open;osd clear;imgread pic logo bootup $loadaddr;bmp display $bootup_offset;bmp scale
em particular:imgread pic logo bootup $loadaddr
onde o U-Boot estava carregando um determinado recurso de "inicialização" no endereço loadaddr = 0x1080000. O recurso em si foi descrito por essa estrutura:struct resource_header{
unsigned int magic;
unsigned int hcrc;
unsigned int size;
unsigned int start;
unsigned int end;
unsigned int next;
unsigned int dcrc;
unsigned char index;
unsigned char nums;
unsigned char type;
unsigned char comp;
char name[32];
}
Obviamente, os parâmetros "size" e "start" eram interessantes. Continuando com eles e também com o parâmetro "loadaddr", o U-Boot resolveu três novos parâmetros para leitura direta no eMMC. Idealmente, é claro, ele baixou uma imagem da seção "logo" em 0x000B00C0 na memória em 0x1130000 ... Acho que o curso de meus pensamentos agora está claro. Resolvi novos parâmetros "size" e "start" e escrevi meu código, que foi salvo no eMMC. Após essas manipulações, o U-Boot não estava mais lendo uma imagem, mas uma exploração, que imediatamente ganhou controle. A exploração consistiu em várias linhas no assembler.LDR X21, printf
ADR X0, .message
BLR X21
LDR X21, run_command
ADR X0, .command
MOV X1,#0x0
BLR X21
.align 4
printf: .quad 0x37EE50A0
.align 4
run_command: .quad 0x37EE9BA0
.align 4
.message: .string "\nJailbreaking BL3-3...\n"
.align 4
.command: .string "fatload mmc 0:1 0x1000000 uboot.bin; go 0x1000000"
Ele leu o uboot.bin na primeira seção do cartão mSD e transferiu o controle para ele (o uboot.bin era um U-Boot não criptografado recentemente coletado. É claro que era possível usar um modificado nativo). Acontece que o processo de inicialização retornou ao local em que o BL3-1 descriptografou o U-Boot original e transferiu o controle para ele. Somente dessa vez, o código não assinado já estava em execução. E agora o download do eMMS ficou assim (o último fragmento):Hit Enter or space or Ctrl+C key to stop autoboot -- : 0
Jailbreaking BL3-3...
card in
[mmc_init] mmc init success
reading uboot.bin
408579 bytes read in 28 ms (13.9 MiB/s)
## Starting application at 0x01000000 ...
U-Boot 2017.11-02414-g9b5924abf2-dirty (Mar 01 2020 - 22:17:58 +0100) p212
DRAM: 1 GiB
MMC: mmc@72000: 0, mmc@74000: 1
reading uboot.env
In: serial@4c0
Out: serial@4c0
Err: serial@4c0
[BL31]: tee size: 0
[BL31]: tee size: 0
Net:
Warning: ethernet@c9410000 (eth0) using random MAC address - 22:10:89:5b:74:85
eth0: ethernet@c9410000
Hit any key to stop autoboot: 2 0
=> version
U-Boot 2017.11-02414-g9b5924abf2-dirty (Mar 01 2020 - 22:17:58 +0100) p212
aarch64-elf-gcc (Linaro GCC 7.2-2017.11) 7.2.1 20171011
GNU ld (Linaro_Binutils-2017.11) 2.28.2.20170706
=>
Conclusão
Para que o prefixo não fique ocioso na prateleira, decidi colocar o LibreElec nele. Imagem recém montada lançada quase imediatamente sem problemas. O kernel foi finalizado com um pequeno arquivo, os drivers para WiFi e o controle remoto foram instalados e a função de desligamento foi refeita. E tudo funcionou bem, mas lembrei que o console também suporta Bluetooth, que naturalmente não funcionava no LibreElec. Embora eu não precisasse, ainda decidi configurá-lo para complementar a imagem.A bordo estava o chip AP6255 da Ampak, responsável por WiFi e Bluetooth. O UART Bluetooth estava conectado ao ttyS1, mas o chip não respondeu a nenhum comando HCI e fingiu estar morto. Além disso, no núcleo nativo, o chip, como esperado, respondeu à equipe.A documentação para esse chip é muito ruim e tudo o que pode ser extraído de lá é uma pinagem. Antes de tudo, verifiquei a potência do chip e o pino BT_WAKE. Tudo estava normal. Tendo experimentado o próprio driver e a porta ttyS1, não obtive nenhum resultado - o chip ficou silencioso como partidário e eu liguei um osciloscópio a ele. Nele, verifiquei e comparei todos os sinais eletrônicos UART (RTS, TXD, RXD, CTS). Tudo estava normal. Em seguida, verifiquei a sequência de redefinição, que é controlada via rfkill (esses eram os pinos BT_WAKE e BT_REGON). Mas aqui estava tudo bem. Depois verifiquei o pino do LPO, onde, de acordo com a documentação, um sinal com frequência de 32.768KHz deveria entrar, mas mesmo aqui vi um sinal no osciloscópio. Em geral, tudo estava em ordem, mas o chip não funcionou com o meu núcleo. Depois de passar mais alguns dias desmontando o driver UART original, voltei ao sinal LPO e medi sua frequência.O resultado mostrou 26KHz. Ah, como.O driver wifi_dt foi responsável por esse sinal, que no meu núcleo não gerou corretamente a frequência. Desmontei o driver original e assumi a inicialização do sinal pwm de lá e ... o chip ganhou vida (mais tarde, encontrei uma versão desse driver com o sinal correto). E assim, o chip estava pronto para mais ajustes, mas eu não tinha ideia de como colocá-lo em alerta, porque Não encontrei nenhum driver / firmware / documentação para ele. No Android original, não havia nada no log do kernel, exceto rfkill ao trabalhar com Bluetooth. Isso é compreensível, porque não havia driver do kernel e o lançamento ocorreu no nível do usuário. Era necessário, de alguma forma, acessar o log do Android e, para isso, era necessário o acesso root ao dispositivo. Para fazer isso, na minha ingenuidade, adicionei as configurações necessárias à seção do sistema e ativei o adb.Mas com esse cenário, o Android percebeu que algo estava errado e se recusou a começar, referindo-se a algumas manipulações por aí ... Bem, não, não. Eu restaurei a partição do sistema e refiz o rootfs simplesmente incluindo sh lá. Após o lançamento subsequente, eu tive acesso root no terminal.Foi assim que o chip foi inicializado.5759 5781 I bt_hci_h4: hal_open
5759 5781 I bt_userial_vendor: userial vendor open: opening /dev/ttyS1
5759 5781 E bt_userial_vendor: userial vendor open success!!
5759 5781 I bt_userial_vendor: device fd = 52 open
5759 5781 I bt_hwcfg: bt vendor lib: set UART baud 2000000
5759 5781 I bt_hwcfg: FW prepatch file: /etc/bluetooth/4335/bcm4335_prepatch.hcd
5759 5781 I bt_hwcfg: bt vendor lib: loading prepatch /etc/bluetooth/4335/bcm4335_prepatch.hcd
5759 5781 D bt_hwcfg: Chipset BCM4335A0
5759 5781 D bt_hwcfg: Target name = [BCM4335A0]
5759 5781 I bt_hwcfg: FW patchfile: /etc/bluetooth/4335/bcm4335.hcd
5759 5781 I bt_hwcfg: bt vendor lib: set UART baud 115200
5759 5781 D bt_hwcfg: Settlement delay -- 200 ms
5759 5781 I bt_hwcfg: Setting fw settlement delay to 200
5759 5781 I bt_hwcfg: bt vendor lib: set UART baud 2000000
5759 5781 I bt_hwcfg: Setting local bd addr to 22:22:99:F7:B6:BD
5759 5781 I bt_hwcfg: vendor lib fwcfg completed
Esta informação foi suficiente para escrever um programa que fez o mesmo. O último passo foi iniciar o hciattach e o LibreElec reconheceu o Bluetooth corretamente. Agora o dispositivo foi totalmente configurado. Se alguém estiver interessado, aqui está a imagem final.