|
|
  |
AES bootloader от Atmel (AVR231), Кто разбирался с данным примером? |
|
|
|
Oct 14 2007, 17:45
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Караул!!! Спасайте кто знает и разбирался с данным примером. Короче сама передача работает(сделал по прерываниям - уже жалею). Декодирование тоже проходит. Сигнатуры совпадают. Почему то сама запись не происходит. Флэш после операции девственно чист. И сама операция идёт - уснуть можно. Да и выспаться тоже. То ли JTAGом нельзя при данной операции, то ли ещё что-то. Не понимаю также записи вида Код spm #endif dw 0xFFFF nop В даташите тоже такого не нашёл. PS: ATMEGA640
|
|
|
|
|
Oct 15 2007, 15:15
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
До сих пор мучаешся  Выкладывай ,что и в каком порядке и в какие регистры заносиш при записи страницы. spm #endif dw 0xFFFF nop Это типа трех нопов - не актуально ,для этого кирпича
|
|
|
|
|
Jul 22 2013, 10:27
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726

|
Цитата(SasaVitebsk @ Oct 14 2007, 21:45)  Почему то сама запись не происходит. Флэш после операции девственно чист. ... PS: ATMEGA640 Доброго времени суток, коллеги! Столкнулся с подобной проблемой, не пишется FLASH из бутлоадера. Бутлоадер немного переделанный под себя из AES-аппнота, подобных бутлоадеров понаделано прилично под меги 16/32/64, все работают. А вот под 640 - не шьет  Исходные данные: камень Atmega640-16AU, питание схемы 5В, кварц 14.7456МГц. Фузы: E:0xF4 H:0xDA L:0xD7 L:0x3F (вообще последний должен быть 0x0C, но ставлю 0x3F для тестов, чтобы уж точно была разрешена запись spm и чтобы потом FLASH можно было прочитать для сравнения) Вот кусочки исходников, откуда пишется во FLASH CODE else if (type == TYPE_PROGRAM) { // Program page buffer into flash page unsigned int *q = (unsigned int *) pageBuffer; unsigned char APPFLASH *r = address; do { spmWriteWord(r, *q++); r += 2; } while (--size); spmErasePage(address); spmProgramPage(address); } Вот исходник spm640.asm (сделал специальный под 640, обрезав "лишнее") CODE NAME spm(16) PUBLIC spmWriteWord PUBLIC spmErasePage PUBLIC spmProgramPage PUBLIC spmEEWriteByte
#define __ENABLE_BIT_DEFINITIONS__ #include INCLUDE_FILE
#if !defined( EEMWE ) #define EEMWE EEMPE #endif #if !defined( EEWE ) #define EEWE EEPE #endif
//============================================================================= // I/O registers used
RSEG CODE
//============================================================================= // Writes one word to a temporary page buffer
spmWriteWord: movw r1:r0, r19:r18 ldi r22, (1 << SPMEN) rjmp spmSPM
//============================================================================= // Erases one flash page
spmErasePage: ldi r22, (1 << PGERS) | (1 << SPMEN) rjmp spmSPM
//============================================================================= // Programs the temporary buffer to flash memory
spmProgramPage: ldi r22, (1 << PGWRT) | (1 << SPMEN)
//============================================================================= // Executes self-programming command
spmSPM: ; movw r31:r30, r17:r16
; в целях тестирования по адресу 0 всегда пишем константу 0x1357 ldi r31, 0 ldi r30, 0 ldi r19, 0x13 ldi r18, 0x57 movw r1:r0, r19:r18
rcall spmWait
in r20, SREG cli
sts SPMCSR, r22 spm dw 0xFFFF nop out SREG, r20 ret
spmWait: wdr __spmWait: lds r23, SPMCSR andi r23, (1 << SPMEN) brne __spmWait
ret
//============================================================================= // Writes one byte to EEPROM memory
spmEEWriteByte: rcall spmWait rcall spmEEWriteByteComplete
out EEARL, r16 out EEARH, r17 out EEDR, r18
sbi EECR, EEMWE sbi EECR, EEWE spmEEWriteByteComplete: sbic EECR, EEWE rjmp spmEEWriteByteComplete ret
END Вот настройки линкера CODE -ca90 -w29
//============================================================================= // Interrupt vectors
-Z(CODE)INTVEC=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1) -H1895 -h(CODE)(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1)
//============================================================================= // Code memory
-Z(CODE)NEAR_F,HUGE_F,SWITCH,INITTAB,DIFUNCT,CODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1) -Z(FARCODE)FAR_F,FARCODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1)
//============================================================================= // RAM -Z(DATA)NEAR_I,NEAR_Z=RAM_BASE-(RAM_BASE+RAM_SIZE-1) -Z(DATA)RSTACK+100=RAM_BASE-(RAM_BASE+RAM_SIZE-1) -Z(DATA)CSTACK+(RAM_SIZE-300-APP_SRAM_USAGE)=RAM_BASE-(RAM_BASE+RAM_SIZE-1) Вот вывод map-а CODE **************************************** * * * MODULE MAP * * * ****************************************
DEFINED ABSOLUTE ENTRIES PROGRAM MODULE, NAME : ?ABS_ENTRY_MOD
Absolute parts ENTRY ADDRESS REF BY ===== ======= ====== APP_SRAM_USAGE 0000042E RAM_BASE 00000200 RAM_SIZE 00002000 IVT_SIZE 000000E4 FLASH_SIZE 00010000 BOOT_SIZE 00001000 *************************************************************************
..............
SEGMENTS IN THE MODULE ====================== INTVEC Common segment, address: CODE 0000F000 - 0000F063 (0x64 bytes), align: 0 Segment part 0.
**************************************** * * * SEGMENTS IN ADDRESS ORDER * * * ****************************************
SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN ======= ===== ============= =========== ==== ==== ===== INTVEC CODE 0000F000 - 0000F063 64 com 1 NEAR_F CODE 0000F064 - 0000F097 34 rel 0 SWITCH CODE 0000F098 dse 0 HUGE_F CODE 0000F098 dse 0 INITTAB CODE 0000F098 - 0000F09D 6 rel 0 DIFUNCT CODE 0000F09E dse 0 CODE CODE 0000F09E - 0000F9C9 92C rel 1 ABSOLUTE DATA 0000001F rel 0 DATA 00000020 DATA 00000021 DATA 00000027 - 00000028 2 DATA 0000002A - 0000002B 2 DATA 0000002D - 0000002E 2 DATA 00000030 - 00000031 2 DATA 00000033 - 00000034 2 DATA 00000036 - 00000036 1 DATA 0000004C - 0000004E 3 DATA 00000055 - 00000055 1 DATA 00000060 - 00000060 1 DATA 0000006F - 0000006F 1 DATA 0000007C - 0000007C 1 DATA 00000080 - 00000082 3 DATA 00000084 - 00000085 2 DATA 000000C0 - 000000C1 2 DATA 000000C4 - 000000C6 3 DATA 00000101 - 00000102 2 DATA 00000104 - 00000105 2 DATA 00000107 - 00000108 2 DATA 0000010A - 0000010B 2 NEAR_I DATA 00000200 dse 0 NEAR_Z DATA 00000200 - 0000061F 420 rel 0 RSTACK DATA 00000620 - 0000071F 100 dse 0 CSTACK DATA 00000720 - 00001FF1 18D2 dse 0
**************************************** * * * END OF CROSS REFERENCE * * * ****************************************
2 506 bytes of CODE memory 7 666 bytes of DATA memory (+ 41 absolute )
Errors: none Warnings: none Пишу бутлоадер, обновляю через него прошивку, читаю FLASH - чистая с 0-го адреса (0xFFFF), с 0xF000 - бутлоадер. Пишу бутлоадер и рабочую прошивку, обновляю через бутлоадер прошивку, читаю FLASH - прошивка по адресу 0 на константу 0x1357 не затирается, с 0xF000 - бутлоадер. Прошу помощи, уже весь мозг сломал, в чем может быть причина, куда копать.
|
|
|
|
|
Jul 23 2013, 06:42
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726

|
Цитата(_Артём_ @ Jul 22 2013, 15:15)  Вы после записи страницы разрешаете RWW section? По исходникам непонятно. Вообще нет, и до этого случая все прекрасно работало. Не хочется думать, что мне просто несказанно везло, но за несколько лет сбоев не наблюдалось. Возможно используется какой-то хитрый трюк, давно это было. По теме - я об этом думал и даже делал тест, в котором реализовывал такой алгоритм - стирание страницы, разрешение RWW, запись в буфер, запись страницы, разрешение RWW. Результат был тем же - не работало. Но если Вы считаете, что это критически важно, я повторю тест и выложу результат с исходником. Цитата(Hmm @ Jul 22 2013, 22:24)  Что-бы не плодить темы, спрошу здесь: Поскольку существует возможность "вывалиться" в загрузчик (jump, call, ..) , то и вероятность "слёта" прошивки не равна нулю? Т.е. использовать этот способ обновления ПО в случаях ответственного применения нельзя. Командировки по разным странам обременительны. Извиняюсь, если это обсуждалось, но сходу не нашел. Смотря что Вы имеете в виду под "слетом" прошивки. Если несанкционированный вылет рабочей прошивки в код загрузчика - то да, такое теоретически возможно, и да, теоретически возможно, что МК попадет в такое место загрузчика, в котором зациклится. Но на этот случай есть WDT, который сбросит МК и все восстановится, если конечно а) в этом "цикле" не встретится команда wdr б) сам WDT не окажется временно отключенным. Повторюсь из предыдущего поста - я с таким не сталкивался. А если Вы боитесь, что во время обновления произойдет сбой, прошивка "недообновится" и привет - то нет. Принцип такой - сначала ВСЕГДА стартует бутлоадер, смотрится некий признак, переходить ли в режим обновления. Если признака нет (тут каждый на что горазд придумывает по каким критериям переходить, смотря какой интерфейс используется, таймауты и пр.), считается CRC всей памяти МК (application, т.е. от 0 до бутлоадера), если CRC сошлась, управление передается на 0-ой адрес рабочей прошивке. Рабочая прошивка тоже должна уметь "ловить" какие-то признаки, по которым она передает управление бутлоадеру в целях обновления. Как она это делает? Тупо и цинично  - встает колом и по WDT ресетится, попадая в бутлоадер. Ну а если бутлоадер "понял", что кто-то извне хочет обновлять - он и обновляет, ну там целый набор команд в аппноте, опять же Вы можете оставить себе только необходимые. Например я оставил только запись FLASH/EEPROM, старт/стоп, все чтения удалил, и все остальное. А фузы блокировки выставил таким образом, что из рабочей прошивки нельзя ни читать ни писать область бутлоадера, и нельзя ни читать ни писать application область, и поскольку прошивки формирую только я, и прошивки эти шифрованные (ключ внутри бутлоадера, на каждый тип устройства свой), получилось очень удобно - вероятность взлома прошивки или ее воровства практически нулевая. Да, забыл добавить, если происходит сбой при обновлении, надо просто запустить процесс повторно - в 99.99% случаев помогает.
|
|
|
|
|
Jul 23 2013, 10:40
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726

|
Вот исходник с разрешением RWW CODE else if (type == TYPE_PROGRAM) { // Program page buffer into flash page unsigned int *q = (unsigned int *) pageBuffer; unsigned char APPFLASH *r = address; spmErasePage(address); spmEnableRWW(address); do { spmWriteWord(r, *q++); r += 2; } while (--size); spmProgramPage(address); spmEnableRWW(address); } Вот исходник spm640.asm CODE NAME spm(16) PUBLIC spmWriteWord PUBLIC spmErasePage PUBLIC spmEnableRWW PUBLIC spmProgramPage PUBLIC spmEEWriteByte
#define __ENABLE_BIT_DEFINITIONS__ #include INCLUDE_FILE
#if !defined( EEMWE ) #define EEMWE EEMPE #endif #if !defined( EEWE ) #define EEWE EEPE #endif
//============================================================================= // I/O registers used
RSEG CODE
//============================================================================= // Writes one word to a temporary page buffer
spmWriteWord: movw r1:r0, r19:r18 ldi r22, (1 << SPMEN) rjmp spmSPM
//============================================================================= // Erases one flash page
spmErasePage: ldi r22, (1 << PGERS) | (1 << SPMEN) rjmp spmSPM
//============================================================================= // Re-enables RWW section
spmEnableRWW: ldi r22, (1 << RWWSRE) | (1 << SPMEN) rjmp spmSPM
//============================================================================= // Programs the temporary buffer to flash memory
spmProgramPage: ldi r22, (1 << PGWRT) | (1 << SPMEN)
//============================================================================= // Executes self-programming command
spmSPM: ; movw r31:r30, r17:r16
ldi r31, 0 ldi r30, 0 ldi r19, 0x13 ldi r18, 0x57 movw r1:r0, r19:r18
rcall spmWait
in r20, SREG cli
sts SPMCSR, r22 spm dw 0xFFFF nop out SREG, r20 ret
spmWait: wdr __spmWait: lds r23, SPMCSR andi r23, (1 << SPMEN) brne __spmWait
ret
//============================================================================= // Writes one byte to EEPROM memory
spmEEWriteByte: rcall spmWait rcall spmEEWriteByteComplete
out EEARL, r16 out EEARH, r17 out EEDR, r18
sbi EECR, EEMWE sbi EECR, EEWE spmEEWriteByteComplete: sbic EECR, EEWE rjmp spmEEWriteByteComplete ret
END Увы, результат печальный - FLASH не пишется
|
|
|
|
|
Jul 24 2013, 18:15
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726

|
Цитата(Hmm @ Jul 24 2013, 21:37)  Процесс обновления думаю некритичен, а вот наличие в адресном пространстве кода способного стереть/записать страницу "мусора" может окончится неприятностями. Почему не реализована, например, возможность программно устанавливать флаг RWWSB? Непонятно. Так этот код же находится в пространстве бутлоадера, стереть/записать самого себя он не может, а если по ошибке программиста/мантейнера прошивки зальется "левая" прошивка, которая не позволит штатным образом переходить в бутлоадер, то это проблема программиста/мантейнера. Если же произойдет сбой и запишется "мусор", то не сойдется CRC прошивки, и бутлоадер просто не передаст на нее управление, ожидая загрузки по новой. По моей проблеме - ни у кого не возникло идей? Куда рыть?
|
|
|
|
|
Jul 24 2013, 18:43
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Hmm @ Jul 24 2013, 20:37)  Почему не реализована, например, возможность программно устанавливать флаг RWWSB? Зачем его устанавливать? Скорее нужен бит, установка которого запрещает использование функции самопрограммирования. И чтобы его сбросить можно было только сбросом МК. Цитата(Costa @ Jul 24 2013, 21:15)  Так этот код же находится в пространстве бутлоадера, стереть/записать самого себя он не может, Себя - может, но это редко кому надо. Цитата(Costa @ Jul 24 2013, 21:15)  По моей проблеме - ни у кого не возникло идей? Куда рыть? Код бута расположен там где ему положено в соответсвии с фузами? P.S. Проще может оказаться не искать ошибку, а взять готовый код у атмела и вставить в свою программу.
|
|
|
|
|
Jul 24 2013, 19:12
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726

|
Цитата(_Артём_ @ Jul 24 2013, 22:43)  Себя - может, но это редко кому надо. Ну можно же и проверку адреса в бутлоадере вставить, чтобы запретить самоперезапись. Цитата(_Артём_ @ Jul 24 2013, 22:43)  Код бута расположен там где ему положено в соответсвии с фузами?
P.S. Проще может оказаться не искать ошибку, а взять готовый код у атмела и вставить в свою программу. Да, бутлоадер на своем месте, проверено считыванием из МК всей памяти. В моем случае - F000. У меня все нормально работает на мегах 16/32/64, и только на 640 затык
|
|
|
|
|
Jul 25 2013, 17:30
|

Местный
  
Группа: Свой
Сообщений: 329
Регистрация: 22-06-04
Пользователь №: 124

|
Я наверное не внятно описал гипотетическую ситуацию. Целость бутлоадера по уязвимости проблема N2. Речь про штатный режим, а не момент обновления. По проблеме N1: Цитата "левая" прошивка, которая не позволит штатным образом переходить в бутлоадер Это каким способом можно "не позволить", если в результате сбоя в СК окажется код из пространства бутлоадера. Цитата RWWSB? Зачем его устанавливать? Не этот бит так другой, позволяющий запретить самопрограммирование или делающее область загрузчика недоступной, при удачном старте основного кода. Похоже выхода нет - придется ставить внешний чип.
--------------------
Талант не пропить ...
|
|
|
|
|
Jul 25 2013, 20:05
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726

|
Цитата(Hmm @ Jul 25 2013, 21:30)  Я наверное не внятно описал гипотетическую ситуацию. Целость бутлоадера по уязвимости проблема N2. Речь про штатный режим, а не момент обновления. По проблеме N1:
Это каким способом можно "не позволить", если в результате сбоя в СК окажется код из пространства бутлоадера. Хм, это интересный поворот. Надо будет на досуге сымитировать подобное. Но полагаю, что вероятность порчи основной прошивки в этом случае исчезающе мала, т.к. нужно точно "попасть" в код записи/стирания, иначе весь ущерб - нештатный переход в бутлоадер и как следствие - перезагрузка в рабочую прошивку или штатно, или по WDT. Внешний чип не обеспечит защиты от копирования.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|