Skip to content

Commit 2a83ee5

Browse files
committed
Add a version number to the optiboot source and binary.
http://code.google.com/p/arduino/issues/detail?id=554 end of flash memory where they can be read (at least in theory) by device programmers, hex-file examination, or application programs. This is done by putting the version number in a separate section (".version"), and using linker/objcopy magic to locate that section as appropriate for the target chip. (See http://lists.gnu.org/archive/html/avr-gcc-list/2011-02/msg00016.html for some discussion on the details.) Start the version at 4.1 (the last "packaged" version of optiboot was called version 3, so the "top of source" would be 4.0, and adding the version number makes 4.1) Refactor LDSECTION in the Makefile to LDSECTIONS so that multiple section start addresses can be defined. Change the _isp makefile definitions to make the bootloader section readable (but not writable) by the application section. (This would need to be done elsewhere as well to handle all bootloader programming techniques. Notably Arduino's boards.txt Note that this change does not change the "code" portion of optiboot at all. The only diffs in the .hex files are the added version word at the end of flash memory.
1 parent 64be388 commit 2a83ee5

20 files changed

+784
-729
lines changed

bootloaders/optiboot/Makefile

+13-13
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ ISPPORT = usb
3636
ISPSPEED = -b 115200
3737

3838
MCU_TARGET = atmega168
39-
LDSECTION = --section-start=.text=0x3e00
39+
LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
4040

4141
# Build environments
4242
# Start of some ugly makefile-isms to allow optiboot to be built
@@ -88,7 +88,7 @@ endif
8888
# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
8989
#
9090
# similarly, the lock bits should be 0xff instead of 0x3f (to
91-
# unlock the bootloader section) and 0xcf instead of 0x0f (to
91+
# unlock the bootloader section) and 0xcf instead of 0x2f (to
9292
# lock it), but since the high two bits of the lock byte are
9393
# unused, avrdude would get confused.
9494

@@ -98,7 +98,7 @@ ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
9898
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
9999
ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
100100
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
101-
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m
101+
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
102102

103103
STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
104104
STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
@@ -116,7 +116,7 @@ CC = $(GCCROOT)avr-gcc
116116
# Override is only needed by avr-lib build system.
117117

118118
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
119-
override LDFLAGS = -Wl,$(LDSECTION) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
119+
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
120120

121121
OBJCOPY = $(GCCROOT)avr-objcopy
122122
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
@@ -129,7 +129,7 @@ virboot328: TARGET = atmega328
129129
virboot328: MCU_TARGET = atmega328p
130130
virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT'
131131
virboot328: AVR_FREQ = 16000000L
132-
virboot328: LDSECTION = --section-start=.text=0x7e00
132+
virboot328: LDSECTIONS = --section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
133133
virboot328: $(PROGRAM)_atmega328.hex
134134
virboot328: $(PROGRAM)_atmega328.lst
135135

@@ -200,7 +200,7 @@ atmega328: TARGET = atmega328
200200
atmega328: MCU_TARGET = atmega328p
201201
atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
202202
atmega328: AVR_FREQ = 16000000L
203-
atmega328: LDSECTION = --section-start=.text=0x7e00
203+
atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
204204
atmega328: $(PROGRAM)_atmega328.hex
205205
atmega328: $(PROGRAM)_atmega328.lst
206206

@@ -262,7 +262,7 @@ atmega8: TARGET = atmega8
262262
atmega8: MCU_TARGET = atmega8
263263
atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
264264
atmega8: AVR_FREQ = 16000000L
265-
atmega8: LDSECTION = --section-start=.text=0x1e00
265+
atmega8: LDSECTIONS = --section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
266266
atmega8: $(PROGRAM)_atmega8.hex
267267
atmega8: $(PROGRAM)_atmega8.lst
268268

@@ -281,7 +281,7 @@ atmega88: TARGET = atmega88
281281
atmega88: MCU_TARGET = atmega88
282282
atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
283283
atmega88: AVR_FREQ = 16000000L
284-
atmega88: LDSECTION = --section-start=.text=0x1e00
284+
atmega88: LDSECTIONS = --section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
285285
atmega88: $(PROGRAM)_atmega88.hex
286286
atmega88: $(PROGRAM)_atmega88.lst
287287

@@ -357,7 +357,7 @@ atmega328_pro8: TARGET = atmega328_pro_8MHz
357357
atmega328_pro8: MCU_TARGET = atmega328p
358358
atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
359359
atmega328_pro8: AVR_FREQ = 8000000L
360-
atmega328_pro8: LDSECTION = --section-start=.text=0x7e00
360+
atmega328_pro8: LDSECTIONS = --section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
361361
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
362362
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
363363

@@ -382,7 +382,7 @@ luminet: MCU_TARGET = attiny84
382382
luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
383383
luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
384384
luminet: AVR_FREQ = 1000000L
385-
luminet: LDSECTION = --section-start=.text=0x1d00
385+
luminet: LDSECTIONS = --section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
386386
luminet: $(PROGRAM)_luminet.hex
387387
luminet: $(PROGRAM)_luminet.lst
388388

@@ -421,10 +421,10 @@ clean:
421421
$(OBJDUMP) -h -S $< > $@
422422

423423
%.hex: %.elf
424-
$(OBJCOPY) -j .text -j .data -O ihex $< $@
424+
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
425425

426426
%.srec: %.elf
427-
$(OBJCOPY) -j .text -j .data -O srec $< $@
427+
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
428428

429429
%.bin: %.elf
430-
$(OBJCOPY) -j .text -j .data -O binary $< $@
430+
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@

bootloaders/optiboot/optiboot.c

+34-4
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,37 @@
114114
/* 500,1000,2000,4000,8000 supported. */
115115
/* */
116116
/**********************************************************/
117+
118+
/**********************************************************/
119+
/* Version Numbers! */
120+
/* */
121+
/* Arduino Optiboot now includes this Version number in */
122+
/* the source and object code. */
123+
/* */
124+
/* Version 3 was released as zip from the optiboot */
125+
/* repository and was distributed with Arduino 0022. */
126+
/* Version 4 starts with the arduino repository commit */
127+
/* that brought the arduino repository up-to-date with */
128+
/* the optiboot source tree changes since v3. */
129+
/* */
130+
/**********************************************************/
131+
132+
/**********************************************************/
133+
/* Edit History: */
134+
/* */
135+
/* 4.1 WestfW: put version number in binary. */
136+
/**********************************************************/
137+
138+
#define OPTIBOOT_MAJVER 4
139+
#define OPTIBOOT_MINVER 1
117140

141+
#define MAKESTR(a) #a
142+
#define MAKEVER(a, b) MAKESTR(a*256+b)
143+
144+
asm(" .section .version\n"
145+
"optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
146+
" .section .text\n");
147+
118148
#include <inttypes.h>
119149
#include <avr/io.h>
120150
#include <avr/pgmspace.h>
@@ -324,7 +354,7 @@ int main(void) {
324354

325355
// If we are in RWW section, immediately start page erase
326356
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
327-
357+
328358
// While that is going on, read in page contents
329359
bufPtr = buff;
330360
do *bufPtr++ = getch();
@@ -336,7 +366,7 @@ int main(void) {
336366

337367
// Read command terminator, start reply
338368
verifySpace();
339-
369+
340370
// If only a partial page is to be programmed, the erase might not be complete.
341371
// So check that here
342372
boot_spm_busy_wait();
@@ -371,7 +401,7 @@ int main(void) {
371401
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
372402
addrPtr += 2;
373403
} while (--ch);
374-
404+
375405
// Write from programming buffer
376406
__boot_page_write_short((uint16_t)(void*)address);
377407
boot_spm_busy_wait();
@@ -489,7 +519,7 @@ uint8_t getch(void) {
489519
" rcall uartDelay\n" // Wait 1 bit period
490520
" clc\n"
491521
" sbic %[uartPin],%[uartBit]\n"
492-
" sec\n"
522+
" sec\n"
493523
" dec %[bitCnt]\n"
494524
" breq 3f\n"
495525
" ror %[ch]\n"

bootloaders/optiboot/optiboot_atmega328.hex

+1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
:107FD00090838083089580E0F8DFEE27FF270994DF
3131
:107FE000E7DF803209F0F7DF84E1DACF1F93182F43
3232
:0C7FF000DFDF1150E9F7F4DF1F91089566
33+
:027FFE0001047C
3334
:0400000300007E007B
3435
:00000001FF

bootloaders/optiboot/optiboot_atmega328.lst

+15-13
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@ Sections:
55
Idx Name Size VMA LMA File off Algn
66
0 .text 000001fc 00007e00 00007e00 00000054 2**1
77
CONTENTS, ALLOC, LOAD, READONLY, CODE
8-
1 .debug_aranges 00000028 00000000 00000000 00000250 2**0
8+
1 .version 00000002 00007ffe 00007ffe 00000250 2**0
9+
CONTENTS, READONLY
10+
2 .debug_aranges 00000028 00000000 00000000 00000252 2**0
911
CONTENTS, READONLY, DEBUGGING
10-
2 .debug_pubnames 0000006a 00000000 00000000 00000278 2**0
12+
3 .debug_pubnames 0000006a 00000000 00000000 0000027a 2**0
1113
CONTENTS, READONLY, DEBUGGING
12-
3 .debug_info 00000284 00000000 00000000 000002e2 2**0
14+
4 .debug_info 00000285 00000000 00000000 000002e4 2**0
1315
CONTENTS, READONLY, DEBUGGING
14-
4 .debug_abbrev 000001ae 00000000 00000000 00000566 2**0
16+
5 .debug_abbrev 0000019f 00000000 00000000 00000569 2**0
1517
CONTENTS, READONLY, DEBUGGING
16-
5 .debug_line 00000450 00000000 00000000 00000714 2**0
18+
6 .debug_line 00000453 00000000 00000000 00000708 2**0
1719
CONTENTS, READONLY, DEBUGGING
18-
6 .debug_frame 00000090 00000000 00000000 00000b64 2**2
20+
7 .debug_frame 00000090 00000000 00000000 00000b5c 2**2
1921
CONTENTS, READONLY, DEBUGGING
20-
7 .debug_str 00000141 00000000 00000000 00000bf4 2**0
22+
8 .debug_str 00000141 00000000 00000000 00000bec 2**0
2123
CONTENTS, READONLY, DEBUGGING
22-
8 .debug_loc 000001e1 00000000 00000000 00000d35 2**0
24+
9 .debug_loc 000001e1 00000000 00000000 00000d2d 2**0
2325
CONTENTS, READONLY, DEBUGGING
24-
9 .debug_ranges 00000068 00000000 00000000 00000f16 2**0
26+
10 .debug_ranges 00000068 00000000 00000000 00000f0e 2**0
2527
CONTENTS, READONLY, DEBUGGING
2628

2729
Disassembly of section .text:
@@ -135,7 +137,7 @@ void watchdogReset() {
135137
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
136138
addrPtr += 2;
137139
} while (--ch);
138-
140+
139141
// Write from programming buffer
140142
__boot_page_write_short((uint16_t)(void*)address);
141143
7e50: a5 e0 ldi r26, 0x05 ; 5
@@ -249,7 +251,7 @@ void watchdogReset() {
249251
7ec6: e8 95 spm
250252
7ec8: c0 e0 ldi r28, 0x00 ; 0
251253
7eca: d1 e0 ldi r29, 0x01 ; 1
252-
254+
253255
// While that is going on, read in page contents
254256
bufPtr = buff;
255257
do *bufPtr++ = getch();
@@ -278,7 +280,7 @@ void watchdogReset() {
278280
// Read command terminator, start reply
279281
verifySpace();
280282
7ef4: 75 d0 rcall .+234 ; 0x7fe0 <verifySpace>
281-
283+
282284
// If only a partial page is to be programmed, the erase might not be complete.
283285
// So check that here
284286
boot_spm_busy_wait();
@@ -336,7 +338,7 @@ int main(void) {
336338
7f2e: a0 38 cpi r26, 0x80 ; 128
337339
7f30: bf 07 cpc r27, r31
338340
7f32: 51 f7 brne .-44 ; 0x7f08 <main+0x108>
339-
341+
340342
// Write from programming buffer
341343
__boot_page_write_short((uint16_t)(void*)address);
342344
7f34: e0 91 00 02 lds r30, 0x0200
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
:107E0000112484B714BE81FFE6D085E08093810001
2-
:107E100082E08093C00088E18093C10086E0809377
3-
:107E2000C20088E08093C4008EE0CFD0259A86E01F
4-
:107E300028E13EEF91E0309385002093840096BBCB
5-
:107E4000B09BFECF1D9AA8958150A9F7DD24D3944D
6-
:107E5000A5E0EA2EF1E1FF2EABD0813421F481E0E0
7-
:107E6000C5D083E020C0823411F484E103C085349E
8-
:107E700019F485E0BBD091C0853581F499D0082FE5
9-
:107E800010E096D090E0982F8827802B912B880FB8
10-
:107E9000991F90930102809300027EC0863529F4D9
11-
:107EA00084E0A4D080E07CD078C0843609F04EC055
12-
:107EB00087D0E0910002F091010280E7E030F807FE
13-
:107EC00018F483E087BFE895C0E0D1E071D08993D2
14-
:107ED000809102028150809302028823B9F7E091D9
15-
:107EE0000002F091010280E7E030F80718F083E02B
16-
:107EF00087BFE89575D007B600FCFDCF4091000222
17-
:107F000050910102A0E0B1E02C9130E011968C91EB
18-
:107F1000119790E0982F8827822B932B1296FA01C5
19-
:107F20000C01D7BEE89511244E5F5F4FF1E0A038F9
20-
:107F3000BF0751F7E0910002F0910102E7BEE8951A
21-
:107F400007B600FCFDCFF7BEE89527C08437B9F42B
22-
:107F500037D046D0E0910002F09101023196F093C3
23-
:107F60000102E09300023197E4918E2F19D08091A5
24-
:107F70000202815080930202882361F70EC0853788
25-
:107F800039F42ED08EE10CD085E90AD08FE08BCF6A
26-
:107F9000813511F488E019D023D080E101D05CCF85
27-
:107FA000982F8091C00085FFFCCF9093C600089564
28-
:107FB000A8958091C00087FFFCCF8091C6000895EE
29-
:107FC000F7DFF6DF80930202F3CFE0E6F0E098E11E
30-
:107FD00090838083089580E0F8DFEE27FF270994DF
31-
:107FE000E7DF803209F0F7DF84E1DACF1F93182F43
32-
:0C7FF000DFDF1150E9F7F4DF1F91089566
33-
:0400000300007E007B
1+
:10000000112484B714BE81FFE6D085E0809381007F
2+
:1000100082E08093C00088E18093C10086E08093F5
3+
:10002000C20088E08093C4008EE0CFD0259A86E09D
4+
:1000300028E13EEF91E0309385002093840096BB49
5+
:10004000B09BFECF1D9AA8958150A9F7DD24D394CB
6+
:10005000A5E0EA2EF1E1FF2EABD0813421F481E05E
7+
:10006000C5D083E020C0823411F484E103C085341C
8+
:1000700019F485E0BBD091C0853581F499D0082F63
9+
:1000800010E096D090E0982F8827802B912B880F36
10+
:10009000991F90930102809300027EC0863529F457
11+
:1000A00084E0A4D080E07CD078C0843609F04EC0D3
12+
:1000B00087D0E0910002F091010280E7E030F8077C
13+
:1000C00018F483E087BFE895C0E0D1E071D0899350
14+
:1000D000809102028150809302028823B9F7E09157
15+
:1000E0000002F091010280E7E030F80718F083E0A9
16+
:1000F00087BFE89575D007B600FCFDCF40910002A0
17+
:1001000050910102A0E0B1E02C9130E011968C9169
18+
:10011000119790E0982F8827822B932B1296FA0143
19+
:100120000C01D7BEE89511244E5F5F4FF1E0A03877
20+
:10013000BF0751F7E0910002F0910102E7BEE89598
21+
:1001400007B600FCFDCFF7BEE89527C08437B9F4A9
22+
:1001500037D046D0E0910002F09101023196F09341
23+
:100160000102E09300023197E4918E2F19D0809123
24+
:100170000202815080930202882361F70EC0853706
25+
:1001800039F42ED08EE10CD085E90AD08FE08BCFE8
26+
:10019000813511F488E019D023D080E101D05CCF03
27+
:1001A000982F8091C00085FFFCCF9093C6000895E2
28+
:1001B000A8958091C00087FFFCCF8091C60008956C
29+
:1001C000F7DFF6DF80930202F3CFE0E6F0E098E19C
30+
:1001D00090838083089580E0F8DFEE27FF2709945D
31+
:1001E000E7DF803209F0F7DF84E1DACF1F93182FC1
32+
:0C01F000DFDF1150E9F7F4DF1F910895E4
33+
:027FFE0001047C
3434
:00000001FF

0 commit comments

Comments
 (0)