Interface JTAG

Un article de neufbox 4.

Sommaire

Description

Points de contact sur une Sercomm

  • TP6 = TDO (Test Data Output)
  • TP7 = TMS (Test Mode Select)
  • TP8 = TDI (Test Data Input)
  • TP9 = TCK (Test Data Clock)
  • TP10 = TRST (Test Reset)

Le TP6 n'est pas facilement (visible et) accessible, car il est sous le radiateur.

Points de contact sur une Foxconn

Le JTAG est situé sur un "rateau" de 8 pins en bas (marqué J9), en dessous du BCM6358 lorsqu'on regarde la carte comme sur la photo :

On voit le connecteur juste en dessous d'un quartz de 64MHz, à droite d'un composant de 14 broches noté HC164 (qui est un registre à décalage 8 bits série/parallèle).

Sur ce connecteur, les pins ne sont pas repérées. Arbitrairement, les pins seront notées de droite à gauche : pin 1 côté prises ethernet/alim/téléphone, pin 8 côté USB.

  • 1 = GND
  • 2 = GND
  • 3 = Vref (3.3V)
  • 4 = TCK (Test Clock)
  • 5 = TMS (Test Mode Select)
  • 6 = TDO (Test Data Out)
  • 7 = TDI (Test Data In)
  • 8 = TRST (Test TAP Reset) (non confirmé, pourrait être non connecté)

Utilisation

Le BCM6358 supporte le standard E-JTAG.

On peux utiliser le JTAG avec, par exemple, HairyDairyMaid WRT54G Debrick Utility mais celui-ci ne marche qu'avec un adaptateur pour port parallèle de type Wiggler.

Le programme UrJtag permet d'en savoir un peu plus: (Attention : La toute dernière version du repository SVN est nécéssaire, la version 0.9 n'est pas suffisante)

J'utilise une interface JTAG Amontec, j'ai ceci dans $HOME/.jtag/rc

cable JTAGkey
frequency 250000

La fréquence maximale de cet adaptateur est 6MHz, et un reflash à cette fréquence a été réussi. Néanmois pour les premiers essais, baisser la fréquence à 250 ou 500Khz reste une bonne idée.

Connected to libftd2xx driver.
Initialisation de la fréquence TCK à 250000 Hz

Ceci permet de détecter le processeur:

jtag> detect
longueur IR: 5
Longueur de la chaîne: 1
Device Id: 00000110001101011000000101111111 (0x000000000635817F)
  Manufacturier: Broadcom
  Part(0):         BCM6358
  Pas     :     V1
  nom de fichier:     /usr/local/share/urjtag/broadcom/bcm6358/bcm6358

Ceci permet de détecter le "bus" EJTAG (dans la terminologie de urjtag) (Attention, la commande endian big est importante, sans elle le programme ne marche pas)

jtag> endian big

jtag> initbus ejtag
ImpCode=00000000100000011000100100000100 00818904
EJTAG version: <= 2.0
EJTAG Implementation flags: R4k MIPS16 DMA MIPS32
Clear memory protection bit in DCR
Clear Watchdog
Potential flash base address: [0x0], [0x1e00000c]
Processor successfully switched in debug mode.

Voici le résultat de "print" :

jtag> print

No. Manufacturier             Pièce                Pas      Instruction         Registre
----------------------------------------------------------------------------------------------
  0 Broadcom                  BCM6358              V1       EJTAG_CONTROL        EJCONTROL

Bus actif:
*0: EJTAG compatible bus driver via DMA (JTAG part No. 0)
	début: 0x00000000, longueur: 0x1E000000, largeur des données: 32 bits, (USEG : User addresses)
	début: 0x1E000000, longueur: 0x02000000, largeur des données: 16 bits, (FLASH : Addresses in flash (boot=0x1FC000000))
	début: 0x20000000, longueur: 0x60000000, largeur des données: 32 bits, (USEG : User addresses)
	début: 0x80000000, longueur: 0x20000000, largeur des données: 32 bits, (KSEG0: Kernel Unmapped Cached)
	début: 0xA0000000, longueur: 0x20000000, largeur des données: 32 bits, (KSEG1: Kernel Unmapped Uncached)
	début: 0xC0000000, longueur: 0x20000000, largeur des données: 32 bits, (SSEG : Supervisor Mapped)
	début: 0xE0000000, longueur: 0x20000000, largeur des données: 32 bits, (KSEG3: Kernel Mapped)

Flash

Sur la neufbox, l'addresse de base de la flash est 0x1e000000 , comme suggérée par la commande "initbus". En réalité, Andrew Dyer (liste urjtag) m'a suggéré que les 2 lignes d'addresse hautes n'était pas connectées, la flash dispose donc de 4 addresses de base :

  • 0x1e000000
  • 0x1e800000
  • 0x1f000000
  • 0x1f800000

Nous n'utiliserons que la première.

Voici le résultat de "detectflash" :

jtag> detectflash 0x1e000000
Chaîne de requêtre d'identification:
	Jeu de commandes Primary Algorithm et Code ID de contrôle d'interface: 0x0002 (AMD/Fujitsu Jeu standard de commandes)
	Jeu alternatif de commandes Primary Algorithm et Code ID de contrôle d'interface: 0x0000 (nul)
Requête d'information d'interface système:
	Vcc logique Puissance minimum Écri/Efface ou Voltage d'écriture: 2700 mV
	Vcc logique Puissance maximum Écri/Efface ou Voltage d'écriture: 3600 mV
	Vpp [Programmation] puissance minimum Écriture/Efface voltage: 0 mV
	Vpp [Programmation] puissance maximum Écriture/Efface voltage: 0 mV
	Délai d'expiration typique par programme simple octet/mot: 16 us
	Délai d'expiration typique pour la taille maximale par programme multi-octets: 0 us
	Délai d'expiration typique par effacement individuel de blocs: 1024 ms
	Délai d'expiration typique pour un effacement complet du module: 0 ms
	Délai d'expiration maximal pour un programme octer/mot: 512 us
	Délai d'expiration maximum pour programme multi-octets: 0 us
	Délai d'expiration maximum par effacement individuel de blocs: 16384 ms
	Délai d'expiration maximum pour un effacement complet du module: 0 ms
Définition de la géométrie du périphérique:
	Taille du périphérique: 8388608 O (8192 KiB, 8 MiB)
	Description du code de l'interface du module: 0x0002 (x8/x16)
	Nombre maximum d'octets d'un programme multi-octest: 1
	Numbre de régions de blocs d'effacement à l'intérieur du périphérique: 2
	Information sur la région du bloc d'effacement:
		Région 0:
			Taille du bloc d'effacement: 8192 B (8 KiB)
			Nombre de blocs d'effacement: 8
		Région 1:
			Taille du bloc d'effacement: 65536 B (64 KiB)
			Nombre de blocs d'effacement: 127
Primary Vendor-Specific Extended Query:
	Major version number: 1
	Minor version number: 1
	Address Sensitive Unlock: Required
	Erase Suspend: Read/write
	Sector Protect: 4 sectors per group
	Sector Temporary Unprotect: Not supported
	Sector Protect/Unprotect Scheme: 29BDS640 mode (Software Command Locking)
	Simultaneous Operation: Not supported
	Burst Mode Type: Supported
	Page Mode Type: Not supported
	ACC (Acceleration) Supply Minimum: 11500 mV
	ACC (Acceleration) Supply Maximum: 12500 mV
	Top/Bottom Sector Flag: Bottom boot device

Enfin il est possible de dumper le contenu de la flash de 8Mo:

jtag>readmem 0x1E000000 0x800000 full_flash_8mb.bin
adresse: 0x1E000000
longueur:  0x00000010
lecture en cours:
adr: 0x1E000010
Complété.

Cette opération est TRES longue, chez moi presque 4h avec l'adaptateur à 6MHz.

Il est possible de dumper uniquement le CFE, soit les 8 premiers secteurs:

jtag>readmem 0x1E000000 0x10000 cfe.bin

Reflashage

Attention ! Tout ce qui a été fait jusqu'a maintenant était "relativement" sans danger, les commandes suivantes vont modifier le contenu de la flash.

Assurez-vous que l'installation fonctionne parfaitement, et que vous avez les fichers nécéssaire pour restaurer la flash.

Flash-Erase

Cette commande ramène tous les octets à 0xFF.

Attention ! Le second argument est un NOMBRE de SECTEUR, et non pas une taille en octet... La taille d'un secteur est donnée dans la sortie de la commande detectflash, ici 8Ko pour les 8 premiers blocs, et 64Ko pour les suivants.

Example:

jtag> eraseflash 0x1E000000 1
Module: AMD Flash
	Manufacturier: Macronix
	Module: MX29LV640B
	Protégé: 0000
Erasing 1 Flash block from address 0x1e000000
(100% Completed) FLASH Block 61440 : Unlocking ... flash_unlock_block 0x1E000000 IGNORE
Erasing ... flash_erase_block 0x1E000000
flash_erase_block 0x1E000000 DONE
(100% Completed) FLASH Block 61440 : Unlocking ... Erasing ... Ok.

Erasing Completed.

Dès lors, la box reste active, mais ne bootera plus : Tous les voyants resteront allumés, le port série ne montrera rien lors du branchement.

Il est possible d'effacer n'importe quel secteur en donnant son addresse, par exemple la NVRAM en 0x1E7F0000 (1 secteur de 64Ko).

La commande suivante lis 1 octet :

jtag> peek 0x1E000000
bus_read(0x1e000000) = 0xFFFF (65535)

Effacer la flash n'est pas vraiment obligatoire, car la commande suivante (flashmem) commence toute opération d'écriture par un effacement du secteur concerné.

Flash-Mem

L'opération reste assez longue, parceque la méthode de flashage est très précautionneuse : Elle écrit octet par octet, en quadruplant les temps d'attente recommandés par le constructeur, et en vérifiant chaque écriture. (Et ce n'est pas anodin : Des utilisateurs ont déclarés que, dans certaines conditions, le constructeur de la flash était assez optimiste sur les valeurs de temporisation annoncés)

jtag> flashmem 0x1E000000 /home/jaube/Desktop/Downloads/cfe.dump
Module: AMD Flash
	Manufacturier: Macronix
	Module: MX29LV640B
	Protégé: 0000
programme:
flash_unlock_block 0x1E000000 IGNORE

bloc 0 déverrouillé
flash_erase_block 0x1E000000
flash_erase_block 0x1E000000 DONE
effacement du bloc 0: 0
flash_unlock_block 0x1E002000 IGNORE

bloc 1 déverrouillé
flash_erase_block 0x1E002000
flash_erase_block 0x1E002000 DONE
effacement du bloc 1: 0
flash_unlock_block 0x1E004000 IGNORE

bloc 2 déverrouillé
flash_erase_block 0x1E004000
flash_erase_block 0x1E004000 DONE
effacement du bloc 2: 0
flash_unlock_block 0x1E006000 IGNORE

bloc 3 déverrouillé
flash_erase_block 0x1E006000
flash_erase_block 0x1E006000 DONE
effacement du bloc 3: 0
flash_unlock_block 0x1E008000 IGNORE

bloc 4 déverrouillé
flash_erase_block 0x1E008000
flash_erase_block 0x1E008000 DONE
effacement du bloc 4: 0
flash_unlock_block 0x1E00A000 IGNORE

bloc 5 déverrouillé
flash_erase_block 0x1E00A000
flash_erase_block 0x1E00A000 DONE
effacement du bloc 5: 0
flash_unlock_block 0x1E00C000 IGNORE

bloc 6 déverrouillé
flash_erase_block 0x1E00C000
flash_erase_block 0x1E00C000 DONE
effacement du bloc 6: 0
flash_unlock_block 0x1E00E000 IGNORE

bloc 7 déverrouillé
flash_erase_block 0x1E00E000
flash_erase_block 0x1E00E000 DONE
effacement du bloc 7: 0
addr: 0x1E00FFFE
vérifier:
addr: 0x1E00FFFE
Done.

Ici, le CFE a été reflashé, 8 blocs de 8ko (soit 64Ko).

jtag> peek 0x1e000000
bus_read(0x1e000000) = 0x1000 (4096)

Et voilà ! La box reboot sur CFE, qui embraye sur un firmware de secours, chez moi en tous cas.

Matériel

Sur port parallèle de type Wiggler

Sur port USB basé sur FTDI FT2232C

Liens

Liens