Décompilation logicielle MS41

Cet article traite du fonctionnement logiciel du MS41. Je ne vais que gratter la surface.
J’ai analysé une grosse partie du logiciel MS41 ID41. Tout n’est pas parfait et il y a encore des inconnues. mais j’explique ici de manière simplifié le fonctionnement de certaines partie de ce que j’ai pu comprendre du logiciel.

Des fautes peuvent êtres présentes ou même des approximations.

J’essayerai d’ajouter dans le futur les modifications des autres version logicielles.

Plages d’adresses et octets par fonction:

Le MS41 est composé de 256Ko de mémoire flash, cependant cette mémoire est sur le même bus que la ram. donc toute une partie n’est pas adressable.

CatégorieOctets identifiés
Moteur20 166
Sécurité11 622
K-line9054
Système8270
Cliquetis7324
Adaptations6470
Injection6404
Allumage5766
EEPROM5470
EWS2858

31,8 % du fichier full read est du code identifié pendant que 64,3 % est de la flash vierge

Catégorieaddresses full read (début →fin)
ADAPTATIONS0x2974E–0x2A754 ; 0x2B610–0x2B70C ; 0x2DB14–0x2E358
ALLUMAGE0x00E78–0x01E80 ; 0x2BB42–0x2BCC8 ; 0x35FAA–0x362F0 ; 0x36606–0x36816
CLIQUETIS0x236D4–0x24000 ; 0x28BE2–0x28F84 ; 0x2C000–0x2CD8E ; 0x2EF1C–0x2F15C
EEPROM0x05718–0x05BCC ; 0x20096–0x202D6 ; 0x202D6–0x21140
EWS0x0473C–0x0496C ; 0x04A24–0x04D28 ; 0x2268E–0x227B2 ; 0x2BFB8–0x2BFFE ; 0x2F840–0x2F9EC ; 0x362F0–0x365D2
INJECTION0x0006C–0x001BC ; 0x008EE–0x00E78 ; 0x21434–0x214F2 ; 0x22E16–0x236D4 ; 0x288F4–0x28BE2 ; 0x2A754–0x2A8A4 ; 0x2E358–0x2E780 ; 0x36614–0x3665C
KLINE0x0496C–0x0498A ; 0x04D28–0x05438 ; 0x0552E–0x05718 ; 0x20000–0x20096 ; 0x26428–0x27118 ; 0x27688–0x27C62 ; 0x27D70–0x28000 ; 0x2BD10–0x2BF7A ; 0x2F37C–0x2F568
MOTEUR0x06D90–0x071B8 ; 0x2234E–0x224C4 ; 0x24000–0x25404 ; 0x25FB6–0x26428 ; 0x286B4–0x288F4 ; 0x28F84–0x2974E ; 0x2B48C–0x2B610 ; 0x2B91E–0x2BB42 ; 0x2CD8E–0x2D700 ; 0x2E780–0x2EB06 ; 0x2F15C–0x2F37C ; 0x34BD8–0x35FAA ; 0x366BE–0x366D4
SECURITE0x05BCC–0x05C14 ; 0x21140–0x21434 ; 0x219E6–0x221A8 ; 0x224C4–0x2268E ; 0x227B2–0x22E16 ; 0x25404–0x25FB6 ; 0x27118–0x27688 ; 0x27C62–0x27D70 ; 0x2B70C–0x2B91E ; 0x2BCC8–0x2BD10 ; 0x2BF7A–0x2BFB8 ; 0x2F568–0x2F840 ; 0x2F9EC–0x2FC52 ; 0x365D2–0x36606
SYSTEME0x00000–0x000DE ; 0x04000–0x04730 ; 0x05438–0x0552E ; 0x06270–0x06400 ; 0x071B8–0x076AE ; 0x221A8–0x2234E ; 0x280F2–0x28438 ; 0x34000–0x34BD8

EWS:

1- A la mise sous tension du calculateur moteur, le CPU initialise son port série.(ASC1)
2- Le Calculateur moteur attend ensuite les trois lettres « BMW » envoyé sur le fil par l’EWS. Sans ca rien ne se passe.
3- Le DME présente un chalenge composé du code ISN ainsi que sa date de fabrication.
4- Le DME Calcule la réponse attendue de la par l’EWS. le résultat est une série de 4 octets
5- le DME compare le résultat avec celui de l’EWS.

Si ça correspond: Le calculateur autorise le fonctionnement normal du moteur

Si ça ne correspond pas: le calculateur retente 2 fois en incrémentant un compteur avant d’abandonner et de reste en immobilisation active.

Possiblement le même mécanisme que le Kline sécurisé.

Accès KLINE sécurisé:

Il existe dans le calculateur un second jeu, non documenté et non utilisé dans INPA ou autres logiciels dispo de BMW, un mode de diagnostique avancé caché derrière un mot de passe.

L’accès sécurisé permet, entre autres, de:

  • Réécrire des zones mémoires
  • Tester pour trouver les premières zones non vides de mémoire
  • Lecture de la mémoire
  • Selftest de l’EEPROM (pas la flash ni la ram)

Le moyen d’y accéder se fait par une commande suivit d’un mot de passe.
Cette commande défini un flag qui permet ensuite d’utiliser un set de commande caché

0x25, 0x21, 0x31 et d’autres. Je prendrait le soin de tout documenter dans la section ADS/ MS41du Wiki.

Le paquet magique de déverrouillage est le suivant:

12 08 90 42 4D 57 0E DC

Bien que connu, puisque utilisé par des logiciels qui permettent de flasher les MS41, celui ci été resté secret. (pas de secret avec moi)

Oui, c’est bien le mot « BMW » écrit en toutes lettres dans la trame….

Le calculateur répond avec un bloc de 46 octets (le « seed »). exemple de réponse:

12 2E A0 FF FF FF FF FF FF FF 31 31 30 31 FF FF FF FF 30 39 30 32 30 30 30 30 31 31 35 38 35 32 FF FF FF FF 30 32 30 32 31 31 36 30 33 56

On doit transformer le seed en clé grâce à une formule et l’envoyer au calculateur.
la formule est la suivante:

Octet 0 de la clé :
seed[11] + seed[38] + seed[15]
= FF (255) + 31 (49) + 30 (48)
= 255 + 49 + 48 = 352
352 – 256 = 96 = 0x60

Octet 1 de la clé :
seed[12] + seed[39] + seed[16]
= FF (255) + 36 (54) + 39 (57)
= 255 + 54 + 57 = 366
366 – 256 = 110 = 0x6E

Octet 2 de la clé :
seed[13] + seed[40] + seed[17]
= FF (255) + 30 (48) + 30 (48)
= 255 + 48 + 48 = 351
351 – 256 = 95 = 0x5F

Octet 3 de la clé :
seed[14] + seed[41] + seed[18]
= FF (255) + 33 (51) + 32 (50)
= 255 + 51 + 50 = 356
356 – 256 = 100 = 0x64

La clé calculée est 60 6E 5F 64

On reconstruit une trame avec le même format que la requête « BMW », mais avec la clé à la place de « BMW » .

12 08 90 60 6E 5F 64 BF

Le calculateur confirme avec A0. Si il répond avec A1 c’est qu’il est occupé et qu’il faut r’envoyer la clef. A2 il faut redémarrer l’ECU. on s’est fait jeté.

Bits de controle ID41:

Ces octets contiennent le codage du calculateur, Le même calculateur pouvant être monté avec le même logiciel dans différents châssis il faut pouvoir le configurer.

Ces octets sont présents dans le full read au adresses 0x10004 à 0x10008.

Octet 4:

BitRôleDescription
0-4 (au moins un actif)Temporisation du volet d’échappementActive une fonction qui gère le minuteur du volet d’échappement — sans lien direct avec le fait de l’ouvrir/fermer, plutôt sa cadence.
4 (seul)Probablement lié à la climDésactive un ajustement automatique du ralenti
5Interrupteur maître du VANOSLe plus important de cet octet. Si absent, le VANOS ne s’active jamais, peu importe le régime ou la charge — la fonction s’arrête à la première instruction.
6InconnuPositionné en mémoire mais jamais lu ailleurs — probablement sans effet sur ce logiciel précis.
7Sans effet isoléNe correspond à aucun cas testé individuellement dans le code.

Octet 5:

BitRôleDescription
0x2BActive un contrôle de panne calibréArme une vérification spécifique liée aux conditions moteur.
0x2CDéclenche un traitement de commande externeAppelle directement une fonction de validation — un pont entre une requête K-line et une action interne.
6Active un balayage de la liste des pannesVérifie si une panne stockée a un statut précis, et le signale ailleurs.
7Gate le calcul cible carburant + sauvegarde EEPROMImpact large : sans ce bit, deux fonctions majeures de calcul carburant et la sauvegarde des cellules d’apprentissage ne tournent pas.

Octet 6:

BitRôleDescription
0-1Probablement jamais lusAbsents du chemin de décodage
0x181 canal de sonde O2Un seul capteur lambda physique
0x1C2 canaux de sonde O2Deux capteurs, un par banc de cylindres
5-7InutileJamais lu nulle part dans le firmware.

Octet 7:

BitRôleDescription
0-2Masque de permissionAutorise ou verrouille certains comportements dynamiques ailleurs (word_FD18) — un mécanisme réel, sans nom de fonctionnalité précis.
3Redirige l’apprentissage de cliquetisCe bit fait pointer le système d’adaptation (AdaptiveCorrection) directement vers les données de détection cliquetis.
4-6Inutile Inutile

Octet 8:

BitRôleDescription
0-1InutileLu, puis le résultat est immédiatement écrasé sans jamais être utilisé
2Contrôle de panne piloté par l’EWSActive un des 21 états de notre plus grosse fonction de surveillance de pannes — probablement lié au contrôle du ralenti (IACV), mais pas certain à 100%.
3Active ExhaustFlap_ControlSans ce bit, la fonction entière de gestion du volet d’échappement ne fait rien.
4-6Mort, avec un lien croiséSans consommateur propre, mais teste des sous-bits seulement si le bit cliquetis de Byte_7 est actif.
7EWS DeleteContourne le calcul modifie un statut partagé par presque tout le firmware. Un seul bit peut désactiver le lien avec l’immobilisateur.

Adaptations:

Adaptations carburant:

On a 64 cellules stocké dans une zone en RAM de 368octets. Chaque cellule correspond a une combinaison Régime/Charge.

Chaque cellule contient 6 valeurs individuelles qui sont moyennées avant d’être utilisé.
Une cellule neutre contient 0x80.
Au fil des trajets, chaque cellule dérivé vers ce que le moteur à besoin.

Adaptation longue durée:

C’est un système séparé qui suit une tendance globale générale qui dérive vers une valeur stable.

Un bit de codage permet de faire pointer ce mécanisme ‘apprentissage directement vers les données de détection cliquetis.

Zero papillon:

Le calculateur apprend la position du papillon en se recalant a chaque fois qu’il détecte une lecture cohérente au ralenti.

Cliquetis:

Enregistre le seuil de bruit de fond normal de chaque capteur pour savoir a partir de quel seuil un signal doit être considéré comme un vrai cliquetis

Stockage:

Le tout est stocké a deux endroits.

Pendant que le moteur tourne, tout est en ram.
pour survivre a l’arrêt du calculateur, tout est copié de manière périodique dans la puce d’eeprom. (petite à 8 pins) avec laquelle le CPU communique en big-bang I2C.

Zone EEPROMTailleContenu
0xE68 oGrille des 64 cellules carburant
0x524 oCorrection adaptative longue durée
0x566 oEtat du système de fenêtre adaptative
0x5C4 oZéro papillon (TPS)
0x608 oGroupe de 5 valeurs d’adaptation annexes
0x6812 oBornes de fenêtre de détection cliquetis
0xEA12 oTrois « zones » d’adaptation supplémentaires

Sécurité:

On ne peu jamais faire confiance a des données brutes. au redémarrage, chaque bloc est relu depuis l’eeprom puis passe par un checksum (vérification de corruption) puis un teste de plausibilité, pour savoir si la valeur est dans une plage raisonnable.
Si l’un des test échoue la valeur n’est pas utilisé et le calculateur repart sur une valeur neutre.

Boot de l’ECU

Le CPU, avant même de démarrer le moteur passe par une série d’étape lui permettant d’être opérationnel.
Le code configure immédiatement le contrôleur CAN externe et démarre la liaison série avec le microcontroleur externe qui gère le clapet d’échappement et le relais de clim ainsi que d’autres sorties.

Ensuite le CPU configure le watchdog, le Stack et verrouille les réglages systèmes.

Le calculateur fait ensuite une vérification d’intégrité, il écris un motif de test dans sa mémoire et le relis pour voir si elle réagit correctement.

Ensuite il passe par une vérification de démarrage a froid ou un démarrage rapide. Pour se faire il compare 3 copies redondantes d’un meme octet en mémoire. Si les trois se recoupent, il considère que la RAM est encore valide et prend un chemin de démarrage rapide en sortant certaines réinitialisations.

Vient ensuite la mise en place de ces périphériques internes.Les broces entées sorties, les ports de communications EWS, et si ce n’est un démarrage rapide, la configuration de son port série pour le Kline.

Ensuite vient le Coding. c’est la que le calculateur va se configurer pour le châssis..

Il commence déjà par vérifier une signature (non identifiée et non rempli), si vide, c’est le cas sur les ID41, le calculateur cal prendre le chemin de la configuration complète.

Il décode les 5 octets de configuration, il apprend a ce moment la configuration véhicule.

Puis il restaure en RAM les adaptations depuis l’eeprom, après avoir fait les vérifications expliquée dans le paragraphe sur les adaptations.

Il réinitialise ensuite soutes les valeurs du cycle précédent au cas ou une valeur aurai résisté a un redémarrage pour ne pas polluer un nouveau démarrage.

A partir d’ici le calculateur rentre dans sa boucle principale permettant au moteur de démarrer et de tourner.

DTC:

Le calculateur vérifie les valeurs de capteurs en permanence. Il contient des fonctions défiées a tous les capteurs principaux. Papillon des gazq, débit d’air et d’autres.

Le principe est plutôt simple. chaque lecture de capteur est vérifié avec des bornes raisonnables, propres a chaque capteur.

En cas de dépassement d’un capteur en dessous et a! dessus des limites raisonnables, le capteur est ignoré et le calculateur passe sur des valeurs refuges.

Anti rebond:

Le coeur du système repose sur une fonction permettant d’éviter le rebond des capteurs si il yy a une valeur parasite ou ponctuelle. Cette valeur est ignorée pour pas qu’a elle seule elle déclenche un défaut.

Chaque contrôle de valeur a son compteur de confirmation. La condition doit se répéter un certain nombre de fois pour que le défaut soit considéré.

Enregistrement:

une fois un défaut confirmée il y a plusieurs choses qui en découle.

Un instantané figé est capturé, 4 capteurs sont prélevés au moment de la confirmation. Une sorte de boite noire.

L’index de default est ajouté a une liste (2 en parallèle)

Chaque capteur a sa fiche descriptive indiquant au calculateur quel capteur ajouter a la freezer frame et quels sont les seuils du capteur.

Auto effacement:

si le féfault est passager: un mécanisme d’expiration fait vieillir le default stocké. Si il ne se reproduitt pas dans une certaine fenêtre il est automatiquement effacé.

Si le défaut fait partie d’une liste déclarée permanent. celui ci échappe au vieillissement automatique et est recopié dans l’EEPROM Externe pour survivre a la coupure du contact. Un vrai défaut enregistré dans cette EEPROM survit a un retrait de batterie. Il ne doit pas disparaitre puisque réel.

Diagnostique:

Il y a deux commandes qui permette de récupérer la liste des défaut.

La première 0x04 peu envoyé un résumé du nombre de default présent. soit le détail complet avec la freezer frame.

La seconde 0x05 permet d’effacer les default ainsi que les freeze-frames.

Retour en haut