Skip to content

Commit 293c122

Browse files
authored
Merge pull request #53 from osresearch/tinyprog-security
tinyprog security page writing and other features
2 parents 6e31253 + dceca91 commit 293c122

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ Optionally, an additional `desc.tgz` file may be included in the SPI flash itsel
5050
"bver": "2.0.0",
5151
"update": "https://tinyfpga.com/update/tinyfpga-bx",
5252
"addrmap": {
53-
"bootloader": "0x00000+131542",
54-
"userimage": "0x30000+131542",
55-
"userdata": "0x50000+710000",
56-
"desc.tgz": "0xFC000+16000"
53+
"bootloader": "0x00000-0x2FFFF",
54+
"userimage": "0x30000-0x4FFFF",
55+
"userdata": "0x50000-0xFBFFF",
56+
"desc.tgz": "0xFC000-0xFFFFF"
5757
}
5858
}
5959
```

programmer/tinyprog/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import platform
33
import re
44
import struct
5+
import time
56

67
from functools import reduce
78
from pkg_resources import get_distribution, DistributionNotFound
@@ -493,12 +494,32 @@ def program_sectors(self, addr, data):
493494
for offset in range(0, len(data), sector_size):
494495
current_addr = addr + offset
495496
current_write_data = data[offset:offset + sector_size]
497+
498+
# Determine if we need to write this sector at all
499+
current_flash_data = self.read(
500+
current_addr,
501+
sector_size,
502+
disable_progress=True,
503+
max_length=sector_size)
504+
505+
if current_flash_data == current_write_data:
506+
# skip this sector since it matches
507+
pbar.update(sector_size)
508+
continue
509+
496510
self.erase(current_addr, sector_size, disable_progress=True)
497511

498512
minor_sector_size = 256
499513
for minor_offset in range(0, 4 * 1024, minor_sector_size):
500514
minor_write_data = current_write_data[
501515
minor_offset:minor_offset + minor_sector_size]
516+
517+
# if the minor data is all 0xFF then it will match
518+
# the erased bits and doesn't need to be re-sent
519+
if minor_write_data == chr(0xFF) * len(minor_write_data):
520+
pbar.update(len(minor_write_data))
521+
continue;
522+
502523
self.write(
503524
current_addr + minor_offset,
504525
minor_write_data,
@@ -566,3 +587,12 @@ def program_bitstream_fast(self, addr, bitstream):
566587
self.wake()
567588
self.progress(str(len(bitstream)) + " bytes to program")
568589
return self.program_fast(addr, bitstream)
590+
591+
def program_security_page(self, page, data):
592+
self.progress("Waking up SPI flash")
593+
self.wake()
594+
self.progress("Erasing security page " + str(page))
595+
self.erase_security_register_page(page)
596+
self.progress(str(len(data)) + " bytes to program")
597+
return self.program_security_register_page(page, data)
598+

programmer/tinyprog/__main__.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ def parse_int(str_value):
266266
"--meta",
267267
action="store_true",
268268
help="dump out the metadata for all connected boards in JSON")
269+
parser.add_argument(
270+
"--security",
271+
type=str,
272+
help="update the security page in the flash at address addr")
269273
parser.add_argument(
270274
"--update-bootloader",
271275
action="store_true",
@@ -372,6 +376,7 @@ def parse_int(str_value):
372376
# program the flash memory
373377
if (args.program is not None) or (
374378
args.program_userdata is not None) or (
379+
args.security is not None) or (
375380
args.program_image is not None):
376381
boot_fpga = False
377382

@@ -381,6 +386,7 @@ def progress(info):
381386

382387
with active_port:
383388
fpga = TinyProg(active_port, progress)
389+
force = False
384390

385391
if args.program is not None:
386392
print(" Programming %s with %s" % (
@@ -390,6 +396,7 @@ def progress(info):
390396

391397
if args.addr is not None:
392398
addr = parse_int(args.addr)
399+
force = True
393400
else:
394401
addr = fpga.meta.userimage_addr_range()[0]
395402

@@ -400,7 +407,7 @@ def progress(info):
400407
print(" Bootloader not active")
401408
sys.exit(1)
402409

403-
if check_if_overwrite_bootloader(
410+
if force or check_if_overwrite_bootloader(
404411
addr, len(bitstream),
405412
fpga.meta.userimage_addr_range()):
406413
boot_fpga = True
@@ -417,6 +424,7 @@ def progress(info):
417424

418425
if args.addr is not None:
419426
addr = parse_int(args.addr)
427+
force = True
420428
else:
421429
addr = fpga.meta.userdata_addr_range()[0]
422430

@@ -427,7 +435,7 @@ def progress(info):
427435
print(" Bootloader not active")
428436
sys.exit(1)
429437

430-
if check_if_overwrite_bootloader(
438+
if force or check_if_overwrite_bootloader(
431439
addr, len(bitstream),
432440
fpga.meta.userdata_addr_range()):
433441
boot_fpga = True
@@ -444,6 +452,7 @@ def progress(info):
444452

445453
if args.addr is not None:
446454
addr = parse_int(args.addr)
455+
force = True
447456
else:
448457
addr = fpga.meta.userimage_addr_range()[0]
449458

@@ -454,7 +463,7 @@ def progress(info):
454463
print(" Bootloader not active")
455464
sys.exit(1)
456465

457-
if check_if_overwrite_bootloader(
466+
if force or check_if_overwrite_bootloader(
458467
addr, len(bitstream),
459468
(fpga.meta.userimage_addr_range()[0],
460469
fpga.meta.userdata_addr_range()[1])):
@@ -463,6 +472,27 @@ def progress(info):
463472
if not fpga.program_bitstream(addr, bitstream):
464473
sys.exit(1)
465474

475+
if args.security is not None:
476+
print(" Programming %s security page with %s" % (
477+
active_port, args.security))
478+
479+
data = open(args.security, 'r').read()
480+
481+
if args.addr is not None:
482+
addr = parse_int(args.addr)
483+
else:
484+
addr = 1
485+
486+
if addr < 0:
487+
print(" Negative write addr: {}".format(addr))
488+
sys.exit(1)
489+
if not fpga.is_bootloader_active():
490+
print(" Bootloader not active")
491+
sys.exit(1)
492+
493+
if not fpga.program_security_page(addr, data):
494+
sys.exit(1)
495+
466496
if boot_fpga:
467497
fpga.boot()
468498
print("")

0 commit comments

Comments
 (0)