Ich habe hier ein Problem mit einem Radio auf dem ein OMAP-Prozessor (OMAP5912 derivat) verbaut ist. Der hat eine ARM9 CPU drauf, externen SDRAM und Flash. Ich kann per JTAG auf die CPU zugreifen und auch das Flash lesen/programmieren. Trotzdem bootet das Ding nicht weil irgendwas nicht stimmt. Ich habe bereits die Firmware neu geflasht (von einem laufenden Gerät), aber das hat nichts geändert. Es gibt wohl eine externe Abhängigkeit/defekt die ich noch nicht gefunden habe.
Beim Connect mit J-Link sehe ich das die CPU nach einem Reset immer hier hängen bleibt:
1
J-Link: ARM9 CP15 Settings changed: 5327F from 78, MMU On, ICache On, DCache On
0xFFFF000C ist der Reset-Vector vom ABORT Interrupt (soweit ich das weis). Und der "ABORT mode" zeigt es ja auch an.
War es nicht so das in einem solchen Fall R13 auf den Stacktrace zeigt und R14 auf die Adresse in der der Abbruch stattfand?
1
ABT: R13=BBE9D6AB, R14=00000002, SPSR=000000F7
Von der Adresse her wäre aber doch in R14 ein illegaler Wert mit 0x0000_0002?
Die von R13 angezeigte Stack-Trace Adresse liegt im Bereich des externen SDRAMs (EMIFF), welcher von 0x8000_0000 bis 0xEFFF_FFFF geht. Wenn ich versuche über JTAG den Bereich zu lesen erhalte ich einen Fehler:
1
J-Link>mem 0xbbe9d6ab, 64
2
Could not read memory.
Aus dem internen SRAM kann ich aber lesen. Möglicherweise ist aber zum Zeitpunkt des ABORTs das externe SDRAM noch garnicht verfügbar, wodurch der Adressbereich noch nicht belegt ist?
Hat hier jemand genug Erfahrung mir da ein wenig unter die ARMe zu greifen? ;-) Ich würde gern herausfinden warum und wo der ABORT stattfindet. Evtl. gibt mir das Aufschluß darüber was mit der Hardware nicht stimmt?
Ein Abort kann ja auch durch Timeouts beim Zugriff auf externe Peripherie ausgelöst werden. Hier liegt meine Vermutung. Aber ohne einen Anhaltspunkt wo ist das stochern im Nebel. Natürlich habe ich schon die bekannten bzw. möglichen Fehlerquellen geprüft wie das RAM, das Flash, die Stromversorgungen, Power-Control und Boot-Control, aber alles ohne erkennbares Problem.
Normalerweise läuft das Programm ja im SVC mode (Supervisor). Irgendwann kommt dann das Problem und er wechselt in den ABORT mode. Ist dann nicht vom obigen regs der letzte ausgeführte Befehl hier zu suchen?
1
SVC: R13=2000FE18, R14=00001FA0, SPSR=00000010
Also an R14?
Hier mal der Disassembly aus diesem Bereich:
1
ROM:00001F7C PUSH {R4,LR}
2
ROM:00001F80 MOV R4, R0
3
ROM:00001F84 MOV R0, R1
4
ROM:00001F88 MOV R1, R2
5
ROM:00001F8C MOV R2, R3
6
ROM:00001F90 LDR R3, [SP,#8+arg_0]
7
ROM:00001F94 ADD R4, R4, #0x14
8
ROM:00001F98 MOV LR, PC
9
ROM:00001F9C BX R4
10
ROM:00001FA0 POP {R4,PC}
Das habe ich mal mit einem Breakpoint ein paar Befehle davor geprüft:
An 0x1F9C springt er ja mit einem call an die Adresse von R4, wo zu diesem Zeitpunkt 0x9000_0014 drin steht. Eine Zielmarke im SDRAM. Dort springt er wohl weiter nach 0x9000_0034. Die Adresse muss er ja aus dem Speicherort 0x9000_0014 - 0x18 = 0x8FFF_FFFC gelesen haben. Von der Zielmarke her (aligned) eher ein ARM als ein Thumb-Befehl?. Aber das scheint er dann nicht mehr hin zu bekommen (Fehlermeldung). Danach ist der PC auf 0xE51FF018 gestellt, warum auch immer?!
Den Speicher ab 0x9000_0000 kann ich übrigens problemlos auslesen:
Einzig das bei mehreren gleichen Lesezyklen ab und zu mal ein anderer Inhalt erscheint, wenn auch immer derselbe:
1
J-Link>mem 0x90000000, 64
2
90000000 = 60 54 05 FA 01 1F 0F E2 60 54 05 FA 01 1F 0F E2 `T......`T......
3
90000010 = 60 54 05 FA 01 1F 0F E2 60 54 05 FA 01 1F 0F E2 `T......`T......
4
90000020 = 60 54 05 FA 01 1F 0F E2 60 54 05 FA 01 1F 0F E2 `T......`T......
5
90000030 = 60 54 05 FA 01 1F 0F E2 60 54 05 FA 01 1F 0F E2 `T......`T......
6
90000040 = 60 54 05 FA 01 1F 0F E2 60 54 05 FA 01 1F 0F E2 `T......`T......
7
90000050 = 60 54 05 FA 01 1F 0F E2 60 54 05 FA 01 1F 0F E2 `T......`T......
8
90000060 = 60 54 05 FA `T..
Da das im SDRAM ist, dürfte das doch bei einer angehaltenen CPU nicht sein, oder? Das müsste doch immer gleich sein...
Vom Rest des Codes her ist das in einem Bereich wo Images aus dem Flash ins RAM geladen werden. Was darin genau abgeht weiss ich noch nicht aber es wird ein Image nach dem anderen übertragen und dann ausgeführt (initialisiert). Und in einem davon scheint es dann zu knallen.
Ich schaue mal ob ich durch einen Breakpoint in der Verzeigungsroutine (case) herausbekomme bei welchem das der Fall ist.
Hier auch mal zur Vollständigkeit das Decompile dieses Bereichs:
Ich glaube ich liege total falsch, diese Kaskade da oben scheint eher ein Teil des Bootloaders zu sein. Hier wird im Kern ein String-Vergleich durchgeführt. Und zwar gibt es im SRAM eine Adresse (z.B. 0x2C5EB7A5) welche durch die ganze Kette durchgeschleust und nach einem String-Match gesucht wird. An besagtem SRAM steht da:
Ich würde mal versuchen die Register ESR_EL3 (Exception Syndrome Register) und FAR_EL3 (Fault Address Register) auszulesen, wenn mit J-Link möglich. Solltest du das noch nicht gemacht haben. Bei FAR_ELx "sollte" die tatsächliche Adresse hinterlegt sein, wo der Fehler aufgetreten ist. ESR_ELx "sollte" angeben, was der Fehler genau war.