Recentemente, eu e um amigo começamos a fuçar em como fazer o Nexus 5 rodar o kernel Linux principal (diretamente do Linus Torvalds). O objetivo disso é, além de ser uma ótima oportunidade de aprendizado, permitir que o Nexus 5 rode uma distribuição Linux, como o PostmarketOS, ao invés de Android, e ainda receber atualizações por toda a vida do celular.
Mas antes de sair programando, primeiro era necessário ter acesso ao UART (serial) do celular no computador, para que eu pudesse ler as mensagens do kernel desde o começo da inicialização e descobrir a fonte de qualquer erro que surgisse. No caso do Nexus 5, o UART fica na saída P2 de áudio, então seria necessária alguma forma de conectar essa saída no USB do meu computador.
Eu achei instruções sobre a construção desse cabo na wiki do postmarketOS e no site do nexus-5-upstream, um projeto do Brian Masney, que já contribuiu muito código para fazer o Nexus rodar o kernel principal.
Mas como as informações nessas duas páginas eram contraditórias, decidi que seria melhor prototipar o circuito antes e confirmar como funciona, antes de soldar.
Para o protótipo, eu precisava usar só os componentes que eu já tinha, já que eu já ia precisar comprar componentes para a placa final e não queria fazer duas compras.
Decidi seguir o esquemático da wiki do postmarketOS, já que ele tinha sido baseado em um esquemático do Google.
Para o conector P2, eu usei um fone de ouvido velho que estava sobrando, e cortei o fio, ficando com os fios expostos em uma ponta e o conector na outra. Para o divisor de tensão no pino TX, eu usei os mesmos valores de resistência do esquemático, mas usando um resistor de 1kΩ e dois de 100Ω em série para obter o de 1.2kΩ.
A conversão entre UART e USB foi feita usando uma placa Adafruit FT232H breakout que eu tinha. Já que ela não possui uma saída 3.3V (na minha versão), eu tentei combinar resistores para dividir os 5V. Consegui chegar em 3.26V, mas não funcionou.
Já estava quase desistindo, quando lembrei que o Brian Masney escreveu na página dele que precisa mesmo ser 3.3V, e também que eu tinha uma placa conversora de SPI para USB com uma saída de 3.3V. Era hora de testar.
Depois de um pequeno problema, que foi resolvido simplesmente mudando a taxa de transmissão do serial para 115200, funcionou! 🥳
O protótipo ficou assim:
Eu sei, horrível, mas funciona!
Com o protótipo funcionando, eu comprei mais alguns componentes para deixar o circuito mais atraente.
Os componentes que eu usei para fazer a placa foram:
Apenas para referência, os pinos devem ser conectados assim (mas é melhor de visualizar no esquemático do postmarketOS):
Pino de UART | Entre | Pino do P2 |
---|---|---|
RX | — | Ponta (TX) |
TX (com 3.3V) | Divisor de tensão (1kΩ e 1.2kΩ) | Anel 1 (RX com 1.8V) |
GND | — | Anel 2 |
3.3V | — | Base |
Eu gastei um pouco de tempo pensando qual seria a melhor posição das conexões e resistores na placa, e decidi soldar assim:
As ligações no verso da placa e pinos correspondentes podem ser vistos a seguir:
Como a PCB era maior que a placa do conversor, eu serrei ela até ficar com mais ou menos o mesmo tamanho (17x7), mas as conexões ocupam só 9x7.
Também mudei a posição do jumper da placa conversora para que o VCC ficasse com 3.3V.
E por fim soldei a barra de pinos na placa conversora e sobre a minha PCB, resultando em uma placa de 2 andares bem estilosa 😎.
A placa final ficou assim:
Depois de conectar o USB da placa no meu computador e o P2 no Nexus 5, eu abri o
console serial usando o picocom
com uma taxa de transmissão de 115200:
picocom /dev/ttyUSB0 -b 115200
E liguei o Nexus 5 no modo fastboot segurando os botões de energia e de abaixar volume, sendo recebido por essa mensagem calorosa:
welcome to hammerhead bootloader [10] Power on reason 80 [10] DDR: hynix [110] Loaded IMGDATA at 0x11000000 [110] Display Init: Start [190] MDP GDSC already enabled [190] bpp 24 [230] Config MIPI_CMD_PANEL. [230] display panel: ORISE [230] display panel: Default setting [360] Turn on MIPI_CMD_PANEL. [410] Display Init: Done [410] cable type from shared memory: 8 [410] vibe [610] USB init ept @ 0xf96b000 [630] secured device: 1 [630] fastboot_init() [680] splash: fastboot_op FASTBOOT MODE PRODUCT_NAME - hammerhead VARIANT - hammerhead D821(H) 16GB HW VERSION - rev_11 BOOTLOADER VERSION - HHZ20h BASEBAND VERSION - M8974A-2.0.50.2.30 CARRIER INFO - None SERIAL NUMBER - *** SIGNING - production SECURE BOOT - enabled LOCK STATE - unlocked [790] splash: start [1820] Fastboot mode started [1820] udc_start()
Já que eu verifiquei que os pinos do nexus-5-upstream estavam errados, mandei uma mudança de código consertando, então agora não deve haver mais confusão 😉.
Beleza! Agora que eu eu consigo ler todas as mensagens de inicialização, estou pronto para mergulhar no código do kernel. Apesar que certamente essa foi a parte mais fácil do projeto 😅...