GC150ATA
descrição geral
Display VGA SYS-GC150ATA
É um painel LCD comum. Meu interesse nele está em reprogramar o firmware pra fazer coisas inusitadas. Como ele tem um sistema de OSD (On-Screen Display), podemos fazer animações por cima do vídeo que estiver vindo pelo conector VGA. Dá também pra fazer isso de forma interativa, já que o display tem 4 botões (além do liga-desliga) na parte da frente.
Principais componentes
CPU
MYSON mtv312mv64 - variante de 8051
Datasheet em: http://www.telemaster.ru/minitv/pdf/MTV312MV64.pdf
chip de vídeo
Controlador GENESIS gmZAN1
Datasheet em: http://www.datasheetarchive.com/dlmain/Datasheets-312/182051.pdf
EPROM
Memória EPROM serial (I2C) ATMEL 24C21
Datasheet em: http://www.datasheetcatalog.com/datasheets_pdf/2/4/C/2/24C21.shtml
Estratégias de Engenharia Reversa
Dump de fw
Via I2C
A placa mãe tem um conector de 4 vias com alabel P303. Foi a primeira coisa que me saltou aos olhos quando abri o equipamento pois era o único conector da placa que não tinha cabo nenhum conectado. Portanto estava bem claro pra mim que deve se tratar de uma interface de programação do dispositivo que é usada na fábrica pra gravar o firmware inicial.
Os sinais desse conector são:
- VCC (5V)
- SCL
- SDA
- GND
As duas vias do barramento i²c estão ligadas aos pinos HSCL e HSDA do 8051.
O datasheet descreve o procedimento para apagar a memória flash por meio da interface I2C, mas imagino que dê também pra fazer o dump. Um dos comandos se chama "data read" e aparentemente é usado para verificação de uma gravação.
O datasheet diz também que o slave address da interface i2c é especificado pelo firmware por meio de uma escrita ao SFR (special funciona register) ISPSLV (In-System Programming Slave Address)
<quote> After Power On/Reset, The MTV312M runs the original Program Code. Once the S/W detects an ISP request (by key or IIC), S/W can accept the request following the steps below:
- Clear watchdog to prevent reset during ISP period.
- Disable all interrupt to prevent CPU wake-up.
- Write IIC address of ISP slave to ISPSLV for communication.
- Write 93h to ISP enable register (ISPEN) to enable ISP.
- Enter 8051 idle mode.
</quote>
Como não temos acesso ao firmware (ainda) não temos como saber qual é o endereço usado. Então resolvi tentar todos! De acordo com a descrição do protocolo de programação da Flash, são 6 bits de endereços possíveis (apesar de i2c permitir 7 bits, um deles - o menos significativo - é usado pra indicar se é acesso de comando ou acesso de dado).
Usando o BusPirate
http://dangerousprototypes.com/docs/Bus_Pirate
Preciso achar o meu que eu perdi ou comprar um novo.
O legal é que dá pra fazer uns scripts pra automatizar o sniffer...
Usando o USBTinyISP
https://learn.adafruit.com/usbtinyisp/
Pensei na possibilidade de modificar o dispositivo para se comunicar por i2c também. Ele é originalmente projetado pra falar SPI (Serial Peripheral Interface).
Cheguei a montar um e compilei o firmware a partir do source, mas quando gravei ele no attiny2313, não funcionou. Quando gravei de volta a imagem de fw precompilada disponivel pra download no site, voltou a funcionar. Talvez a versão do compilador avr-gcc que estou usando não esteja a ideal para geração de código que caiba na flash pequena desse dispositivo.
<quote> You must use avr-gcc v3.4.6 and avr-libc v1.4.4 as part of Winavr-20060421 to compile the firmware. Please do not post to the forums asking for help on how to compile or burn the firmware. </quote>
Achei meio esquisito... Meu avr-gcc 4.5.3 é mais recente que isso (e obviamente eu não uso Windows) mas é isso que eles indicam no site.
Usando a porta VGA
Isso é genial! http://www.instructables.com/file/FZTD0AYFFAOSLO5
Tentei fazer, mas ainda não rolou. :-P
O conector VGA contém uma interface i2c (chamada DDC - Display Data Channel) que é usada para que o monitor informe ao PC suas características como resolução, profundidade de cores, etc. E também permite setar a intensidade de brilho, ajuste de componentes de cor, etc...
Aí a gente pode simplesmente escrever código C que manipula de forma arbitrária essa "porta" i2c pra controlar o que a gente quiser. O adaptador é super simples. É só um conector VGA com os 4 fios que nos interessam (GND, VCC, SDA e SCL).
Inicialmente não consegui baixar o código do cara, por que o site dele estava extremamente lerdo. Então copiei uns trechos do source do ddccontrol-0.4.2 e adaptei para o meu propósito, implementando um algoritmo de dump com base na descrição do datasheet e usando a porta VGA do meu notebook como bridge i2c.
Depois de fazer modprobe i2c-dev e modprobe i915, o comando i2cdetect -l me listou várias interfaces /dev/i2c-0 até /dev/i2c-6.
Fiquei na dúvida de qual era a correta mas a minha intuição apontava para a /dev/i2c-1 (descrita como "i915 gmbus vga") e para a /dev/i2c-6 (descrita como "DPDDC-B") Então fiquei rodando meu código alternando entre essas duas opções pra ver no que dava.
No dia seguinte consegui baixar o código do site do cara, mas ainda não tive tempo de testá-lo.
Para tirar a dúvida sobre qual o /dev correto, dei uma olhada no código do driver da placa Intel i915 no kernel Linux e vi que o nome "gmbus vga" corresponde ao GPIOA que é usado para controlar o DDC, então o /dev correto é mesmo o /dev/i2c-1 no meu laptop.
Usando algum outro bridge USB->I2C
Preciso comprar um desses pra tentar.
Via Soquete PLCC
Desoldar o chip, conectá-lo a um conversor PLCC→DIP e utilizar o TL866CS para fazer o dump.
CONTRAS: Procedimento invasivo. Ter que soldar um soquete no lugar, e depois ter que remover/reinserir toda vez que for atualizar o firmware. Pode danificar o componente pelo esforço mecânico.
Teorias
Aqui eu listo algumas teorias que tenho para tentar explicar por que não está funcionando ainda a tentativa de se fazer dump do firmware via i2c.
detalhes do i2c
Talvez a frequencia do clock (SCL) gerado pela placa de vídeo Intel i915 esteja fora da faixa de frequencias de clock suportadas pela interface de atualização de firmware do 8051.
Talvez haja alguma leve divergência entre as implementações do protocolo da placa VGA e do 8051. Talvez tenha a ver com bits de acknownledge ou condições de Start/Restart ou alguma nuance na temporização dos sinais. Nesses momentos eu queria muito ter em mãos um analisador lógico pra de fato VER o que se passa no barramento i2c durante a execução desses testes.
interface desabilitada ?
Talvez o fabricante tenha usado a interface de update de firmware via i2c apenas durante a etapa de desenvolvimento do produto, mas tenha a desabilitado após colocar o produto no mercado. Se for isso mesmo, a única forma de modificar o firmware seria desolvando o chip e usando um gravador convencional, como o TL866.
detecção de ISP
O datasheet menciona que o fw detecta uma requisição de ISP (In-System Programming) e coloca o 8051 em modo idle (após preparar o terreno para uma atualização de firmware).
<quote> Once the S/W detects an ISP request (by key or IIC), S/W can accept the request </quote>
Como ocorre essa detecção? O datasheet fala de detecção por meio de "key or IIC".
Isso nos faz acreditar que pode haver algum combo mágico de teclas que o usuário pode fazer que indique para o 8051 que o dispositivo irá receber uma atualização. Tentei várias combinações, mas não obtive resultado satisfatório. Apenas encontrei uma tela secreta no OSD ao ligar o monitor com todos os 4 botões pressionados. Mas mesmo assim, continuei não conseguindo nenhum resultado pela interface i2c. Além disso, o manual de serviço deveria mencionar esses combos mágicos, mas nada consta...
Quando o datasheet do 8051 fala que o sw pode detectar uma requisição de ISP por meio de IIC (i²c), talvez isso signifique que algum comando mágico enviado pela i²c habilita a interface de update de fw. Mas isso também é algo que deveria constar ou no datasheet do microcontrolador, ou no service manual. Mas se for o caso, guardaram como segredo pra ser usado só na fábrica. Ter acesso a algum software de manutenção do monitor seria útil para desvendar essas coisas.
Talvez seja só um dos comandos do protocolo que habilite a interface. Mas fiquei com medo de testar com o comando "Program" por receio de que isso pudesse acadar apagando a flash toda durante o teste... Por outro lado, talvez Command=Program seguido por Data Read resulte em leituras corretas do fw interno, sem apagá-lo no processo (supondo que só apague quando se envia um Data Write)...