Hi,
die Application-Note AVR230 (DES Bootloader) macht genau das, was ich
suche. Nur leider für IAR. Hat schon jemand eine Portierung auf GCC
gemacht? Bei Avrfreaks habe ich den Code für AVR231 (AES Bootloader) für
GCC gefunden. Schlüssellängen ab 128 Bit sind aber für meine Anwendung
total überdimensioniert. Zumindestens sind diese Sourcen eine gute Hilfe
um zu sehen was für die Umstellung von IAR auf GCC nötig wird.
mfg
Nucor
Nucor schrieb:> Schlüssellängen ab 128 Bit sind aber für meine Anwendung> total überdimensioniert.
Ja, und?
"128 KiB Flash-ROM sind für meine Anwendung völlig überdimensioniert,
mir würden 80 KiB bereits völlig genügen." Trotzdem würde es teurer,
dir extra einen Controller mit 80 KiB zu bauen statt in dem mit 128
KiB einfach 48 KiB ungenutzt zu lassen. Solange nicht anderes dem
im Weg steht, würde ich einfach AES benutzen, egal, ob das jetzt
überdimensioniert erscheint oder nicht. Es ist ja ohnehin der
designierte Nachfolger von DES.
Nee, nee,
die jetzige Anwendung läuft auf einem Atmega64 und der ist bis fast zum
letzten Byte voll. Da noch weitere Wünsche anstehen ist es sinnvoll
sparsam mit dem Codeverbrauch (auch beim pinkompatiblen Atmega128)
umzugehen. Irgendwann ist auch der Atmega128 zu und dann ist ein neues
PCB - Layout fällig. Im Moment versuch' ich aber mit der aktuellen
Platine weiter zu kommen.
mfg
Nucor
Und du meinst, dass DES nur deshalb weniger Code benötigen würde als
AES, weil es eine geringere Verschlüsselungstiefe hat? Das halte
ich für einen Trugschluss. Allerdings kann man AES auf sehr
verschiedene Weise implementieren und damit den Tradeoff zwischen
Laufzeit und ROM-Verbrauch festlegen. Wenn es schnell gehen soll,
lagert man einen Teil des Codes in Tabellen aus, wenn man dagegen
Platz sparen will, rechnet man das zur Laufzeit aus.
OK Jörg, hast mich überredet.
Ich werde erst mal mit der AES - Variante weiter machen. Das ist der
schnellste Weg um die Sache anzuschieben. Ja, ich hatte die Hoffnung,
daß 56-Bit DES weniger Speicher als 128-Bit AES benötigt. Wobei mir klar
ist, daß das stark von der Art der Implementierung abhängt. Wenn später
der Speicher knapp wird kann ich immer noch daran drehen.
mfg
Nucor
Ich habe jetzt die Details auch nicht im Kopf, aber soweit ich mich
erinnere wurde DES damals für eine Implementierung in Hardware
entworfen. Da sind so Sachen wie Bits durcheinander werfen simpel, auf
einer CPU nicht (entweder viele Schritte oder große Lookup-Tables).
Weil sich seitdem viel Kryptographie auf CPUs abspielt, werden moderne
Algorithmen wie auch der, der zum AES gewählt wurde, mit mehr Rücksicht
darauf entworfen. AES kann also durchaus einfacher als DES sein.
Hi,
nach einigen Schwierigkeiten habe ich mittlerweile den AES - Bootloader
soweit, daß er mir den zu ladenden Code in den ATMEGA überträgt. Die
ursprüngliche Überlegung mit DES Code zu sparen war unnötig, da der
Bootloader - Bereich nur in Abschnitten (1K, 2K, 4K) zugewiesen werden
kann.
Ein Problem macht mir allerdings noch zu schaffen:
beim Start (nach dem Laden) prüft der Bootloader mittels CRC den
Applikationsbereich auf Fehler. Man kann es auch abschalten. Ich möcht'
es aber verwenden. Der geladene Code entspricht exakt dem Inhalt des
Hex-Files vor dem Verschlüsseln etc. Mit einem JTAG - Ice kann ich mir
den Flash - Bereich ansehen. Die Abfrage nach der CRC - Routine geht in
eine Endlos - Schleife wenn der Crc - Wert nicht 0 ist. Ermittelt wird
aber 0x8002. Der ATMEGA wird vor dem Laden vom Bootloader gelöscht. Alle
ungenutzten Speicherstellen sind mit FF gefüllt. Der Code ist relativ
kurz:
#if defined(CRC_CHECK)
// Check that the Application Section contents is undamaged
// by calculating the CRC of the whole memory.
{
uint16_t p = 0x000000;
uint16_t crc = 0;
do
{
crc = CRC(crc, pgm_read_byte(p));
}
while (++p < MEM_SIZE);
// Application Section damaged
// -> do not jump to Reset Vector of the Application Section
if (crc)
{
for(;;)
{
_delay_ms(1000);
}
}
}
#endif
die Assembler - Funktion:
// Polynome used in CRC calculations
#define CRC_POLYNOME 0x8005
// unsigned int CRC (unsigned int crc, unsigned char ch);
// r25:r24 r23:r22
.global CRC
// CRC calculation routine
CRC:
ldi r18, 0x08
ldi r19, lo8(CRC_POLYNOME)
ldi r20, hi8(CRC_POLYNOME)
CRC_Loop:
; Rotate left. If MSb is 1 -> divide with Generator-polynome.
lsl r22
rol r24
rol r25
brcc CRC_SkipEor
eor r24, r19
eor r25, r20
CRC_SkipEor:
dec r18
brne CRC_Loop
ret
Meine Kenntnis von CRC war bisher, daß für einen bestimmten Bereich oder
einen Datenstrom-Abschnitt eine charakteristische Zahl erzeugt wird.
Aber wieso steht hier 0 für einen korrekten Bereich ? Es wird beim Laden
kein weiterer Code, wie bei einem Blockcheck - Verfahren, hinzugefügt.
Im Moment stehe ich ratlos davor.
mfg
Nucor
Nucor schrieb:> Meine Kenntnis von CRC war bisher, daß für einen bestimmten Bereich oder> einen Datenstrom-Abschnitt eine charakteristische Zahl erzeugt wird.> Aber wieso steht hier 0 für einen korrekten Bereich ?
Indem man die CRC selbst ans Ende schreibt, ergibt sich bei einem
kompletten Test einschließlich der CRC anschließend eine 0, wenn
die Daten in sich stimmig waren.
CRC ist etwas tricky, da auch bei gleichem Generator-Polynom die
Bitreihenfolge und natürlich der Startwert eine Rolle spielen.
Hi Jörg,
der Code, der von Atmel stammt, checkt nur den Anwendungsbereich.
Gesteuert wird das Ganze von einer Konstanten im Konfigurationsfile:
MEM_SIZE - size of application section in target AVR (in decimal bytes).
Die CRC - Routine beginnt bei 0 und endet mit dem Byte vor MEM_SIZE. Die
CRC - Routine im Bootloader wird garnicht mit durchlaufen. Ich würde ja
verstehen, wenn während der Umwandlungen und des Transports weiterer
Code geladen wird um das Ergebnis auf 0 zu bringen. Allein, ich habe
keine zusätzlichen Einträge gefunden. Der Code stimmt mit dem Hex-File
überein, der Rest ist FF. In der application note AVR231 ist MEM_SIZE
z.B. mit 14336 (= 3800 hex) angegeben. Ein ATMEGA16 hat 16383 (= 3FFF),
die Differenz ist die bootloader section.
mfg
Nucor
Hast du denn nun die CRC selbst mit am Ende des überprüften Bereichs
abgelegt? Nur so kann das doch am Ende alles zu 0 werden.
Ein Beispiel aus der Kommunikationstechnik:
Wenn ich für einen Frame (hier einer nach IEEE 802.15.4) eine CRC
generieren will, dann nehme ich dessen Framedaten, sagen wir mal
"1 2 3":
$ ./gencrc 1 2 3
CRC = 0x5bf7
Wenn ich an den ursprünglichen Frame nun ebendiese CRC anhänge
und den Algorithmus nochmal (diesmal über alle 5 Bytes) laufen
lasse, dann ergibt sich 0:
$ ./gencrc 1 2 3 0xf7 0x5b
CRC = 0x0000
Das gencrc-Programm selbst ist im Wesentlichen der CCITT-Algorithmus
aus der avr-libc, halt in C aufgeschrieben:
Das ist genau das was ich von der AVR231 und der Portierung von
Raapeland auf GCC erwarte. Das nach dem Hexfile CRC - Bytes angehängt
werden. Ich hatte bis jetzt immer einen Bedienungsfehler durch mich
vermutet, da die Applikation schon lange existiert. Möglicherweise haben
andere, die diesen Bootloader verwenden, auf die CRC - Prüfung
verzichtet. Ich werde jetzt die Sourcen von Create.exe, ein C++ -
Program, näher untersuchen um Ursache für die fehlenden CRC - Bytes zu
finden.
mfg
Nucor
mittlerweile habe ich die Ursache für das CRC - Problem gefunden. Der
unbenutzte Applikationsspeicher war nicht vollständig gelöscht. Abhilfe
schafft das Setzen eines Switches (-d) beim Create - Tool.
Nachfolgend sind die notwendigen Einstellungen für einen ATMeg64
aufgeführt.
In der application note AVR231 wird für einen mit dem IAR - Compiler
erzeugten Bootloader ein Wert von < 2K Byte (will fit nicely into 2kb of
flash memory) angegeben. Mit dem GCC (-Os) komme ich auf 2242 Bytes.
Auch wenn ich die paar Anweisungen zum Schalten von einigen Leds
rausnehme sinkt die Größe nicht unter 2048 Bytes. Daher wird ein
Bootloaderbereich mit 4096 Byte verwendet.
Im AVR - Studio sind einige Einstellungen nötig:
-DBAUD=57600
-DF_CPU=8000000UL
Noch nicht getestet habe ich mit dem ATMEGA128 für den RAMPZ definiert
werden muss damit lange Pointer verwendet werden.
für den Linker:
--section-start=.text=0xF000
Die BOOTSZ - Fuses sind auf 0 - BOOTSZ1 und 1 - BOOTSZ0 zu setzen.
BOOTRST ist einzuschalten.
Der Bootloader belegt den Bereich 0xF000 - 0xFFFF in Bytes.
Im Memory - Window des JTAG - Ice werden Worte angezeigt. Dort beginnt
der Bootloader bei 0x7800. Die beiden CRC - Bytes liegen im Word 0x77FF.
Nicht, wie ich ursprünglich vermutete, direkt hinter dem
Anwendungscode.
GENTEMP.EXE wird einmal aufgerufen um ein Gerüst für den Config - File
zu erzeugen.
Im Config - File sind die folgenden Werte einzutragen:
PAGE_SIZE = 256
MEM_SIZE = 61440 <== entspricht 0xF000
CRC_ENABLE = YES
Danach werden mit dem Aufruf:
GCreate -c Config.txt -h BootLdr.h -k AESKeys.h
die Files BootLdr.h und AESKeys.h generiert. Diese sind in das
Verzeichnis der Bootloadersourcen zu kopieren. (GCREATE.EXE für den GCC
und CREATE.EXE für IAR verwenden)
Die zu ladende Hex-Applikationsdatei Test.hex wird mit dem Aufruf:
GCreate -c Config.txt -d -n -f Test.hex -o Update.hex
in Update.hex umgewandelt. Wichtig ist dabei der Schalter -d damit der
unbenutzte Flashbereich mit FFs beschrieben wird. Sonst schlägt die CRC
- Prüfung fehl. GCREATE erzeugt Schlüsselwörter für den GCC, keine IAR -
Schlüsselwörter wie APPFLASH.
Nach dem Laden des Bootloaders muss die Fuse LB auf Mode 3 gesetzt
werden damit kein Auslesen des Flashs über ISP oder JTAG mehr möglich
ist. BLB0 - Mode wird auf 01 gesetzt: keine Beschränkungen für SPM und
LPM. BLB1 - Mode wird auf 4 gesetzt: SPM und LPM sind nicht erlaubt.
Mit dem Aufruf:
Update Update.hex -COM3 -57600
wird das Anwendungsprogramm dann zum ATMEGA64 geschickt.
Im Anhang sind zusätzlich Screenshots der Einstellungen.
mfg
Nucor