REGO600, 8051 och reverse engineering – ett simulatorprojekt

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
manicken
Inlägg: 98
Blev medlem: 10 februari 2006, 14:20:59
Ort: DEGEBERGA

REGO600, 8051 och reverse engineering – ett simulatorprojekt

Inlägg av manicken »

Jag tänkte skriva ihop lite om ett projekt jag hållit på med ett tag,
eftersom det kanske kan vara intressant för andra här som gillar gamla styrsystem,
8051:or och reverse engineering.

Jag ska först vara ärlig med att jag inte har skrivit all kod själv.
Jag använder Claude ganska mycket som programmeringshjälp,
och grunduppsättningen till simulatorn, disassemblern och hexeditorn är skriven med hjälp av AI.

Jag försöker däremot göra så mycket som möjligt själv och använder främst AI när tiden eller orken inte riktigt räcker till.
Det är fortfarande jag som står för reverse engineering och bestämmer vad som faktiskt behöver göras.

Egentligen skulle man kunna se det lite som att jag använder färdiga libraries.
Skillnaden är att istället för att använda ett färdigt library för en viss funktion tycker jag det är ganska kul att göra mina egna wrappers och helpers.
Då har jag full koll på vad som faktiskt händer och kan dessutom anpassa och förbättra dem efter behov.

Jag kör till exempel helt med vanilla JS och har gjort egna wrappers för att slippa skriva en massa kod bara för att skapa några HTML-element.
Visst finns det exempelvis jQuery (o massa nytt grejs), som är väldigt smidigt,
men jag tycker att man får betydligt bättre kontroll över layout och beteende när man gör det själv.

Ok tillbaka till hur detta projektet föddes och det som jag gjort.

Allt började egentligen med att VP VV beredaren gick sönder.
Det gjorde att det blev en del service av övriga delar samtidigt,
och då jag hade läst att kondensatorerna säkert började gamla så bytte jag ut dem i samma process.

Då upptäckte jag att både firmware- och datachipet var löstagbara, så jag passade på att läsa av dem också.
Jag hade läst om att man kunde uppgradera från 3.06 till 3.12 på Värmepumpsforum, så egentligen var det bara en backup.

Sen gick tiden och jag fortsatte på mitt omfattande DALHAL projekt, och nu när det hade nått en major milestone (inte helt färdigt ännu)
så började jag att kolla runt om hur jag skulle eventuellt disassemble/decompile original firmware
mest lite för skojs skull för att se hur man gjorde och om det gick att förstå något.

Sedan tidigare ville jag förstå hur service porten verkligen fungerade och se om det fanns något som inte redan var dokumenterat.
så efter lite sökande så upptäckte jag Ghridra som är ett fritt och open source program som utvecklats av NSA
Där kunde jag till slut verifiera att upptäckterna kring serviceportens protokoll var helt korrekta,
samt att det inte finns fler kommandon än de som redan hade dokumenterats.


Efter det köpte jag även en billig REGO634. Den är så vitt jag kan se samma hårdvara som REGO637,
tanken med den rego var framför allt att ha något jag kunde fortsätta göra
reverse engineering på utan att behöva riskera den värmepump som faktiskt används.

Sen är det ju inte helt fel att ha ett extra kort liggande heller.
Skulle den gamla styrenheten någon gång ge upp helt,
så finns det åtminstone en reserv att ersätta direkt med,
medans man eventuellt kanske kan laga den trasiga.

Min process var att ta foto på båda sidor av PCB,
sen använda massor av lager i Krita för att dela upp alla signaler så de blev enkla att följa utan att behöva använda alla färger,
istället kunde jag ge dem färg efter funktion, och sen gjorde jag grupper av lager för att enklare slå på av allt
på så sätt kan man enkelt se om man missat en ledare.
Efter detta var det "bara" att överföra det till KiCad
Tycker inte riktigt om KiCad då det är ett extremt besvärligt program att göra scheman i, speciellt om man vill göra det snyggt.
Men då det ska vara framtidssäkert så fick det bli KiCad ändå.

Ok vidare.

Grundläggande info för REGO600:
80C552 8051-baserad MCU utan inbyggd ROM
27SF512 code
AM29F040 data (user settings, loggar och menytexter)
62256 SRAM

SRAM och 29F040 delar på samma addressområde så endast det ena av dem kan vara aktivt åt gången

Lite övrig Hårdvara:

* 2x CD4094 för utgångar
* CD4021 för 3-fas avläsning + tre skyddsavläsning (2x motorskydd/elpatron)
* 2x CD4051 för multiplexade signaler
* DS1302 RTC
* TC1232 watchdog/reset
* I²C-baserad LCD
* diverse GPIO-baserade funktioner

Det jag inte har identifierat är de exakta värdena på de ytmonterade kondensatorerna.
Sedan har jag inget schema över själva POWER I/O-kortet, men än så länge har jag inte behövt det.
Det kommer jag göra när jag känner för det.


Det var här nånstans som jag funderade på: **går det att få originalfirmwaren från en IVT Greenline/REGO600 att köra i en emulator på riktigt?**

Inte emulera funktionen genom att skriva om programmet,
utan faktiskt köra originalkoden och försöka återskapa den hårdvara som den förväntar sig.

Tänkte först bara prova i Proteus, men gav upp när jag inte hittade någon bra crackbar version.
Jag ville egentligen bara testa om det gick.

Simulatorn
Simulator.png
Jag kollade med AI vad som fanns för 8051-simulatorer och fastnade för aimini-js51, som är en browserbaserad 8051-simulator.

Jag tyckte dock att dokumentationen var lite besvärlig, så jag tänkte att jag provar med Claude istället.

Jag gav den följande input:
"could you write a simulator using https://github.com/Aimini/js51
where it should simulate a 80c552 it should be able
to simulate manual extmemory swap using gpio so that it can swap between simulating
a 29f040 and a 62256(which is much easier to simulate) then it also need adc support"

Det gav mig en väldigt basic view där jag kunde ladda in firmware och köra den. Den visade i princip bara CPU-register, första delen av XRAM och någon slags automatisk view över dataflash.

Den körde dessutom väldigt långsamt eftersom den bara körde 2000 instruktioner var 30 ms. Det fanns också en XRAM-clean vid boot, och efter ett tag hängde simulatorn sig.

Jag tänkte först att den säkert hängde på grund av att I2C saknades, eftersom frontpanelen använder det. Så efter en ny fråga om I2C-implementering fick jag även möjlighet att logga vad som skickades.

Men det fungerade fortfarande inte.

Efter lite mer research visade det sig att det var interrupten som inte fungerade. I2C använder ISR för att skicka ett 5-byte-paket i "bakgrunden".

När jag väl fått ISR för I2C att fungera korrekt började det äntligen komma data i loggen. Det gjorde att jag kunde tolka frontpanelens protokoll.

Det är egentligen ganska enkelt, 5 bytes:
<row 1-4> <col 1-20> <charcode> <altchars/led status/bg_on> <led_blink_on>
Den gör också REGO-läsningar periodiskt för att läsa av knappstatus.

Det var i princip där simulatorn faktiskt började bli kul.

Någonstans däremellan ändrade jag så att den körde 3000 instruktioner varje 1 ms,
vilket gjorde exekveringen snabbare. Sen ändrades det till 50000 instruktioner vid något tillfälle, och då blev allt mycket snabbare.

Hela tidslinjen är lite spretig och jag kan inte exakt säga i vilken ordning allt kodades,
men simulatorn växte ganska snabbt.
Det tillkom bland annat en IRAM-view och flera XRAM-views där
jag kunde välja vilken 256-byte chunk jag ville visa med hjälp av en num input.

Flash-data-viewen försvann till slut eftersom utrymmet i simulatorn behövdes till annat,
bland annat disassembly-viewen. Även de två extra XRAM-vyerna är numera borta.

Jag tänker att om man behöver dem så har jag ett välfungerande modal/form-system som
jag enkelt kan använda för att lägga till dem igen.

Att få simulatorn att bete sig som den riktiga hårdvaran

Det som var mest kritiskt att simulera var själva 3-fasavkänningen.
Jag gjorde flera försök, men inget blev riktigt lyckat.

Efter att ha hittat rätt ställe i koden blev det däremot mycket enklare att förstå vad firmwaren faktiskt förväntade sig,
och därifrån kunde jag simulera det korrekt.


Jag fick då också göra en förändring i själva CPU-emuleringen.
Varje gång en instruktion utförs returnerar den nu hur många cycles den
riktiga CPU hade tagit för att utföra instruktionen.
Det gjorde att jag kunde simulera den förväntade tiden mycket mer korrekt.

Till exempel kunde Timer0, som tidigare bara räknade en gång per utförd instruktion,
nu faktiskt räkna utifrån den tid varje instruktion tog på den riktiga CPU.

Detta gjorde senare att jag kunde införa en throttling-funktion som gör att CPU
faktiskt körs i riktig hastighet.

Det visade sig vara nödvändigt eftersom jag upptäckte att bland annat sekundnedräkningen
var baserad på dessa timers, till exempel för cooldown-tiderna i de säkerhetsfunktioner
som värmepumpen normalt har. Även avläsningen av RTC var tidsbaserad på samma sätt.

Jag använder som sagt js51 som grund för 8051-emuleringen, men har byggt en hel del runt
den för att få den att fungera som originalfirmwaren förväntar sig.

Jag har försökt hålla själva CPU-emuleringen separerad från REGO600-hårdvaran,
så simulatorn består i princip av en VM plus en uppsättning virtuella perifera enheter.

Till exempel finns virtuella implementationer av I²C-buss, frontpanel (LCD), RTC, watchdog och shift registers.

Det gör också att jag kan observera vad originalfirmwaren faktiskt gör istället för att behöva gissa utifrån assemblerkoden.


Efter jag undersökt kod och börjat skriva om kod som hanterar UART/service, liksom manuellt, så kom behovet av en inbyggd assembler.


Vad simulatorn faktiskt kan idag

Så vad har jag egentligen fått ihop av allt detta?

Simulatorn är idag betydligt mer än bara en 8051-emulator.
Den kan köra originalfirmwaren och har bland annat:

* 80C552/8051 CPU-emulering med korrekt instruction timing
* emulering av 29F040 och 62256 med samma adressområde och GPIO-styrt memory swap
* ADC
* Timer och interrupt
* I²C-buss
* LCD/frontpanel
* DS1302 RTC
* TC1232 watchdog/reset
* CD4094 shift registers
* CD4021 input shift register
* CD4051 multiplexers
* 3-fasavkänning och skyddssignaler
* UART/serviceport
* real-time throttling så att simulatorn kan köras i ungefär samma hastighet som den riktiga CPU

Ovanpå själva emuleringen finns sedan debuggerfunktioner med CPU- och SFR-register,
IRAM/XRAM-viewers, breakpoints, logging och disassembly.

Disassemblern kan dessutom följa kodflöden och hantera labels, kommentarer och referenser.

Profiling så att jag kan mäta hur mycket tid olika delar av originalfirmwaren faktiskt spenderar.

Sedan finns en assembly-editor med tab-baserad filhantering och separata editor sessions.
Assembly-editorn är byggd för att kunna kompilera assemblerkod direkt,
utan att behöva översätta asm-kod till machinecode manuellt.

Tanken är alltså att man i princip ska kunna gå från originalfirmware till reverse engineering,
göra en ändring och sedan testa den direkt i simulatorn.

Det är fortfarande långt ifrån färdigt och det finns massor kvar att förstå och emulera.

Men någonstans här tycker jag ändå att projektet har blivit det jag ursprungligen ville se om det var möjligt:

original REGO600 firmware → 8051 VM → emulerad hårdvara → debugger → disassembler → profiling → assembler/editor

Och allt började egentligen bara med att jag ville se om man kunde få den gamla firmwaren att starta i en emulator. 😄

jo och allt finns på
https://github.com/manicken/rego600_reverseEngineer

sen här värmempumpsforumtråden för ytterligare info:
https://www.varmepumpsforum.com/vpforum ... #msg877098
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
nifelheim
Den första
Inlägg: 2616
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: REGO600, 8051 och reverse engineering – ett simulatorprojekt

Inlägg av nifelheim »

:bravo: :bravo: :bravo:
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 5773
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: REGO600, 8051 och reverse engineering – ett simulatorprojekt

Inlägg av Mickecarlsson »

KUDOS :tumupp:
Användarvisningsbild
rvl
Inlägg: 7509
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: REGO600, 8051 och reverse engineering – ett simulatorprojekt

Inlägg av rvl »

Cool!
Skriv svar