@@ -43,17 +43,19 @@ const (
43
43
)
44
44
45
45
type image struct {
46
- addr uint32
47
- data []byte
48
- part * fwbundle.FirmwarePart
46
+ Name string
47
+ Type string
48
+ Addr uint32
49
+ Data []byte
50
+ ESP32Encrypt bool
49
51
}
50
52
51
53
type imagesByAddr []* image
52
54
53
55
func (pp imagesByAddr ) Len () int { return len (pp ) }
54
56
func (pp imagesByAddr ) Swap (i , j int ) { pp [i ], pp [j ] = pp [j ], pp [i ] }
55
57
func (pp imagesByAddr ) Less (i , j int ) bool {
56
- return pp [i ].addr < pp [j ].addr
58
+ return pp [i ].Addr < pp [j ].Addr
57
59
}
58
60
59
61
func enDis (enabled bool ) string {
@@ -75,32 +77,9 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
75
77
}
76
78
defer cfr .rc .Disconnect ()
77
79
78
- common .Reportf ("Flash size: %d, params: %s" , cfr .flashParams .Size (), cfr .flashParams )
79
-
80
- encryptionEnabled := false
81
- secureBootEnabled := false
82
- var esp32EncryptionKey []byte
83
- var fusesByName map [string ]* esp32.Fuse
84
- kcs := esp32 .KeyEncodingSchemeNone
85
80
if ct == esp .ChipESP8266 {
86
81
// Based on our knowledge of flash size, adjust type=sys_params image.
87
82
adjustSysParamsLocation (fw , cfr .flashParams .Size ())
88
- } else {
89
- _ , _ , fusesByName , err = esp32 .ReadFuses (cfr .fc )
90
- if err != nil {
91
- return errors .Annotatef (err , "failed to read eFuses" )
92
- }
93
-
94
- if fcnt , err := fusesByName [esp32 .FlashCryptCntFuseName ].Value (true /* withDiffs */ ); err == nil {
95
- encryptionEnabled = (bits .OnesCount64 (fcnt .Uint64 ())% 2 != 0 )
96
- kcs = esp32 .GetKeyEncodingScheme (fusesByName )
97
- common .Reportf ("Flash encryption: %s, scheme: %s" , enDis (encryptionEnabled ), kcs )
98
- }
99
-
100
- if abs0 , err := fusesByName [esp32 .AbstractDone0FuseName ].Value (true /* withDiffs */ ); err == nil {
101
- secureBootEnabled = (abs0 .Int64 () != 0 )
102
- common .Reportf ("Secure boot: %s" , enDis (secureBootEnabled ))
103
- }
104
83
}
105
84
106
85
// Sort images by address
@@ -122,11 +101,52 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
122
101
glog .V (1 ).Infof ("%s -> %s -> 0x%x" , p .Name , p .ESP32PartitionName , pti .Pos .Offset )
123
102
p .Addr = pti .Pos .Offset
124
103
}
125
- im := & image {addr : p .Addr , data : data , part : p }
126
- if im .addr == 0 || im .addr == 0x1000 && len (data ) >= 4 && data [0 ] == 0xe9 {
127
- im .data [2 ], im .data [3 ] = cfr .flashParams .Bytes ()
104
+ im := & image {
105
+ Name : p .Name ,
106
+ Type : p .Type ,
107
+ Addr : p .Addr ,
108
+ Data : data ,
109
+ ESP32Encrypt : p .ESP32Encrypt ,
128
110
}
129
- if ct == esp .ChipESP32 && p .ESP32Encrypt && encryptionEnabled {
111
+ images = append (images , im )
112
+ }
113
+
114
+ return errors .Trace (writeImages (ct , cfr , images , opts , true ))
115
+ }
116
+
117
+ func writeImages (ct esp.ChipType , cfr * cfResult , images []* image , opts * esp.FlashOpts , sanityCheck bool ) error {
118
+ var err error
119
+
120
+ common .Reportf ("Flash size: %d, params: %s" , cfr .flashParams .Size (), cfr .flashParams )
121
+
122
+ encryptionEnabled := false
123
+ secureBootEnabled := false
124
+ var esp32EncryptionKey []byte
125
+ var fusesByName map [string ]* esp32.Fuse
126
+ kcs := esp32 .KeyEncodingSchemeNone
127
+ if ct == esp .ChipESP32 {
128
+ _ , _ , fusesByName , err = esp32 .ReadFuses (cfr .fc )
129
+ if err != nil {
130
+ return errors .Annotatef (err , "failed to read eFuses" )
131
+ }
132
+
133
+ if fcnt , err := fusesByName [esp32 .FlashCryptCntFuseName ].Value (true /* withDiffs */ ); err == nil {
134
+ encryptionEnabled = (bits .OnesCount64 (fcnt .Uint64 ())% 2 != 0 )
135
+ kcs = esp32 .GetKeyEncodingScheme (fusesByName )
136
+ common .Reportf ("Flash encryption: %s, scheme: %s" , enDis (encryptionEnabled ), kcs )
137
+ }
138
+
139
+ if abs0 , err := fusesByName [esp32 .AbstractDone0FuseName ].Value (true /* withDiffs */ ); err == nil {
140
+ secureBootEnabled = (abs0 .Int64 () != 0 )
141
+ common .Reportf ("Secure boot: %s" , enDis (secureBootEnabled ))
142
+ }
143
+ }
144
+
145
+ for _ , im := range images {
146
+ if im .Addr == 0 || im .Addr == 0x1000 && len (im .Data ) >= 4 && im .Data [0 ] == 0xe9 {
147
+ im .Data [2 ], im .Data [3 ] = cfr .flashParams .Bytes ()
148
+ }
149
+ if ct == esp .ChipESP32 && im .ESP32Encrypt && encryptionEnabled {
130
150
if esp32EncryptionKey == nil {
131
151
if opts .ESP32EncryptionKeyFile != "" {
132
152
mac := strings .ToUpper (strings .Replace (fusesByName [esp32 .MACAddressFuseName ].MACAddressString (), ":" , "" , - 1 ))
@@ -154,19 +174,20 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
154
174
encrKey = append (encrKey , encrKey [8 :16 ]... )
155
175
}
156
176
encData , err := esp32 .ESP32EncryptImageData (
157
- im .data , encrKey , im .addr , opts .ESP32FlashCryptConf )
177
+ im .Data , encrKey , im .Addr , opts .ESP32FlashCryptConf )
158
178
if err != nil {
159
- return errors .Annotatef (err , "%s: failed to encrypt" , p .Name )
179
+ return errors .Annotatef (err , "%s: failed to encrypt" , im .Name )
160
180
}
161
- im .data = encData
181
+ im .Data = encData
162
182
}
163
- images = append (images , im )
164
183
}
165
184
sort .Sort (imagesByAddr (images ))
166
185
167
- err = sanityCheckImages (ct , images , cfr .flashParams .Size (), flashSectorSize )
168
- if err != nil {
169
- return errors .Trace (err )
186
+ if sanityCheck {
187
+ err = sanityCheckImages (ct , images , cfr .flashParams .Size (), flashSectorSize )
188
+ if err != nil {
189
+ return errors .Trace (err )
190
+ }
170
191
}
171
192
172
193
imagesToWrite := images
@@ -188,10 +209,10 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
188
209
start := time .Now ()
189
210
totalBytesWritten := 0
190
211
for _ , im := range imagesToWrite {
191
- data := im .data
212
+ data := im .Data
192
213
numAttempts := 3
193
214
imageBytesWritten := 0
194
- addr := im .addr
215
+ addr := im .Addr
195
216
if len (data )% flashSectorSize != 0 {
196
217
newData := make ([]byte , len (data ))
197
218
copy (newData , data )
@@ -201,7 +222,7 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
201
222
}
202
223
data = newData
203
224
}
204
- for i := 1 ; imageBytesWritten < len (im .data ); i ++ {
225
+ for i := 1 ; imageBytesWritten < len (im .Data ); i ++ {
205
226
common .Reportf (" %7d @ 0x%x" , len (data ), addr )
206
227
bytesWritten , err := cfr .fc .Write (addr , data , true /* erase */ , opts .EnableCompression )
207
228
if err != nil {
@@ -211,7 +232,7 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
211
232
}
212
233
err = errors .Annotatef (err , "write error (attempt %d/%d)" , i , numAttempts )
213
234
if i >= numAttempts {
214
- return errors .Annotatef (err , "%s: failed to write" , im .part . Name )
235
+ return errors .Annotatef (err , "%s: failed to write" , im .Name )
215
236
}
216
237
glog .Warningf ("%s" , err )
217
238
if err := cfr .fc .Sync (); err != nil {
@@ -224,7 +245,7 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
224
245
imageBytesWritten += bytesWritten
225
246
addr += uint32 (bytesWritten )
226
247
}
227
- totalBytesWritten += len (im .data )
248
+ totalBytesWritten += len (im .Data )
228
249
}
229
250
seconds := time .Since (start ).Seconds ()
230
251
bytesPerSecond := float64 (totalBytesWritten ) / seconds
@@ -233,19 +254,19 @@ func Flash(ct esp.ChipType, fw *fwbundle.FirmwareBundle, opts *esp.FlashOpts) er
233
254
234
255
common .Reportf ("Verifying..." )
235
256
for _ , im := range images {
236
- common .Reportf (" %7d @ 0x%x" , len (im .data ), im .addr )
237
- digest , err := cfr .fc .Digest (im .addr , uint32 (len (im .data )), 0 /* blockSize */ )
257
+ common .Reportf (" %7d @ 0x%x" , len (im .Data ), im .Addr )
258
+ digest , err := cfr .fc .Digest (im .Addr , uint32 (len (im .Data )), 0 /* blockSize */ )
238
259
if err != nil {
239
- return errors .Annotatef (err , "%s: failed to compute digest %d @ 0x%x" , im .part . Name , len (im .data ), im .addr )
260
+ return errors .Annotatef (err , "%s: failed to compute digest %d @ 0x%x" , im .Name , len (im .Data ), im .Addr )
240
261
}
241
262
if len (digest ) != 1 || len (digest [0 ]) != 16 {
242
263
return errors .Errorf ("unexpected digest packetresult %+v" , digest )
243
264
}
244
265
digestHex := strings .ToLower (hex .EncodeToString (digest [0 ]))
245
- expectedDigest := md5 .Sum (im .data )
266
+ expectedDigest := md5 .Sum (im .Data )
246
267
expectedDigestHex := strings .ToLower (hex .EncodeToString (expectedDigest [:]))
247
268
if digestHex != expectedDigestHex {
248
- return errors .Errorf ("%d @ 0x%x: digest mismatch: expected %s, got %s" , len (im .data ), im .addr , expectedDigestHex , digestHex )
269
+ return errors .Errorf ("%d @ 0x%x: digest mismatch: expected %s, got %s" , len (im .Data ), im .Addr , expectedDigestHex , digestHex )
249
270
}
250
271
}
251
272
if opts .BootFirmware {
@@ -274,34 +295,34 @@ func sanityCheckImages(ct esp.ChipType, images []*image, flashSize, flashSectorS
274
295
// Note: we require that images are sorted by address.
275
296
sort .Sort (imagesByAddr (images ))
276
297
for i , im := range images {
277
- imageBegin := int (im .addr )
278
- imageEnd := imageBegin + len (im .data )
298
+ imageBegin := int (im .Addr )
299
+ imageEnd := imageBegin + len (im .Data )
279
300
if imageBegin >= flashSize || imageEnd > flashSize {
280
301
return errors .Errorf (
281
- "Image %d @ 0x%x will not fit in flash (size %d)" , len (im .data ), imageBegin , flashSize )
302
+ "Image %d @ 0x%x will not fit in flash (size %d)" , len (im .Data ), imageBegin , flashSize )
282
303
}
283
304
if imageBegin % flashSectorSize != 0 {
284
305
return errors .Errorf ("Image starting address (0x%x) is not on flash sector boundary (sector size %d)" ,
285
306
imageBegin ,
286
307
flashSectorSize )
287
308
}
288
- if imageBegin == 0 && len (im .data ) > 0 {
289
- if im .data [0 ] != espImageMagicByte {
309
+ if imageBegin == 0 && len (im .Data ) > 0 {
310
+ if im .Data [0 ] != espImageMagicByte {
290
311
return errors .Errorf ("Invalid magic byte in the first image" )
291
312
}
292
313
}
293
314
if ct == esp .ChipESP8266 {
294
315
sysParamsBegin := flashSize - sysParamsAreaSize
295
- if imageBegin == sysParamsBegin && im .part . Type == sysParamsPartType {
316
+ if imageBegin == sysParamsBegin && im .Type == sysParamsPartType {
296
317
// Ok, a sys_params image.
297
318
} else if imageEnd > sysParamsBegin {
298
319
return errors .Errorf ("Image 0x%x overlaps with system params area (%d @ 0x%x)" ,
299
320
imageBegin , sysParamsAreaSize , sysParamsBegin )
300
321
}
301
322
}
302
323
if i > 0 {
303
- prevImageBegin := int (images [i - 1 ].addr )
304
- prevImageEnd := prevImageBegin + len (images [i - 1 ].data )
324
+ prevImageBegin := int (images [i - 1 ].Addr )
325
+ prevImageEnd := prevImageBegin + len (images [i - 1 ].Data )
305
326
// We traverse the list in order, so a simple check will suffice.
306
327
if prevImageEnd > imageBegin {
307
328
return errors .Errorf ("Images 0x%x and 0x%x overlap" , prevImageBegin , imageBegin )
@@ -314,29 +335,35 @@ func sanityCheckImages(ct esp.ChipType, images []*image, flashSize, flashSectorS
314
335
func dedupImages (fc * FlasherClient , images []* image ) ([]* image , error ) {
315
336
var dedupedImages []* image
316
337
for _ , im := range images {
317
- glog .V (2 ).Infof ("%d @ 0x%x" , len (im .data ), im .addr )
318
- imAddr := int (im .addr )
319
- digests , err := fc .Digest (im .addr , uint32 (len (im .data )), flashSectorSize )
338
+ glog .V (2 ).Infof ("%d @ 0x%x" , len (im .Data ), im .Addr )
339
+ imAddr := int (im .Addr )
340
+ digests , err := fc .Digest (im .Addr , uint32 (len (im .Data )), flashSectorSize )
320
341
if err != nil {
321
- return nil , errors .Annotatef (err , "%s: failed to compute digest %d @ 0x%x" , im .part . Name , len (im .data ), im .addr )
342
+ return nil , errors .Annotatef (err , "%s: failed to compute digest %d @ 0x%x" , im .Name , len (im .Data ), im .Addr )
322
343
}
323
344
i , offset := 0 , 0
324
345
var newImages []* image
325
346
newAddr , newLen , newTotalLen := imAddr , 0 , 0
326
- for offset < len (im .data ) {
347
+ for offset < len (im .Data ) {
327
348
blockLen := flashSectorSize
328
- if offset + blockLen > len (im .data ) {
329
- blockLen = len (im .data ) - offset
349
+ if offset + blockLen > len (im .Data ) {
350
+ blockLen = len (im .Data ) - offset
330
351
}
331
352
digestHex := strings .ToLower (hex .EncodeToString (digests [i ]))
332
- expectedDigest := md5 .Sum (im .data [offset : offset + blockLen ])
353
+ expectedDigest := md5 .Sum (im .Data [offset : offset + blockLen ])
333
354
expectedDigestHex := strings .ToLower (hex .EncodeToString (expectedDigest [:]))
334
355
glog .V (2 ).Infof ("0x%06x %4d %s %s %t" , imAddr + offset , blockLen , expectedDigestHex , digestHex , expectedDigestHex == digestHex )
335
356
if expectedDigestHex == digestHex {
336
357
// Found a matching sector. If we've been building an image, commit it.
337
358
if newLen > 0 {
338
- nim := & image {addr : uint32 (newAddr ), data : im .data [newAddr - imAddr : newAddr - imAddr + newLen ], part : im .part }
339
- glog .V (2 ).Infof ("%d @ 0x%x" , len (nim .data ), nim .addr )
359
+ nim := & image {
360
+ Name : im .Name ,
361
+ Type : im .Type ,
362
+ Addr : uint32 (newAddr ),
363
+ Data : im .Data [newAddr - imAddr : newAddr - imAddr + newLen ],
364
+ ESP32Encrypt : im .ESP32Encrypt ,
365
+ }
366
+ glog .V (2 ).Infof ("%d @ 0x%x" , len (nim .Data ), nim .Addr )
340
367
newImages = append (newImages , nim )
341
368
newTotalLen += newLen
342
369
newAddr , newLen = 0 , 0
@@ -352,19 +379,25 @@ func dedupImages(fc *FlasherClient, images []*image) ([]*image, error) {
352
379
i ++
353
380
}
354
381
if newLen > 0 {
355
- nim := & image {addr : uint32 (newAddr ), data : im .data [newAddr - imAddr : newAddr - imAddr + newLen ], part : im .part }
382
+ nim := & image {
383
+ Name : im .Name ,
384
+ Type : im .Type ,
385
+ Addr : uint32 (newAddr ),
386
+ Data : im .Data [newAddr - imAddr : newAddr - imAddr + newLen ],
387
+ ESP32Encrypt : im .ESP32Encrypt ,
388
+ }
356
389
newImages = append (newImages , nim )
357
- glog .V (2 ).Infof ("%d @ %x" , len (nim .data ), nim .addr )
390
+ glog .V (2 ).Infof ("%d @ %x" , len (nim .Data ), nim .Addr )
358
391
newTotalLen += newLen
359
392
newAddr , newLen = 0 , 0
360
393
}
361
- glog .V (2 ).Infof ("%d @ 0x%x -> %d" , len (im .data ), im .addr , newTotalLen )
394
+ glog .V (2 ).Infof ("%d @ 0x%x -> %d" , len (im .Data ), im .Addr , newTotalLen )
362
395
// There's a price for fragmenting a large image: erasing many individual
363
396
// sectors is slower than erasing a whole block. So unless the difference
364
397
// is substantial, don't bother.
365
- if newTotalLen < len (im .data ) && (newTotalLen < flashBlockSize || len (im .data )- newTotalLen >= flashBlockSize ) {
398
+ if newTotalLen < len (im .Data ) && (newTotalLen < flashBlockSize || len (im .Data )- newTotalLen >= flashBlockSize ) {
366
399
dedupedImages = append (dedupedImages , newImages ... )
367
- common .Reportf (" %7d @ 0x%x -> %d" , len (im .data ), im .addr , newTotalLen )
400
+ common .Reportf (" %7d @ 0x%x -> %d" , len (im .Data ), im .Addr , newTotalLen )
368
401
} else {
369
402
dedupedImages = append (dedupedImages , im )
370
403
}
0 commit comments