Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scripts: improved size validator for updater image #3834

Merged
merged 3 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/imglint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pathlib import Path

from flipper.app import App
from PIL import Image, ImageOps
from PIL import Image

_logger = logging.getLogger(__name__)

Expand Down
44 changes: 30 additions & 14 deletions scripts/update.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#!/usr/bin/env python3

import io
import math
import os
import shutil
import tarfile
import zlib
from os.path import exists, join

import heatshrink2
from flipper.app import App
from flipper.assets.coprobin import CoproBinary, get_stack_type
from flipper.assets.heatshrink_stream import HeatshrinkDataStreamHeader
Expand All @@ -35,7 +33,12 @@ class Main(App):
)

FLASH_BASE = 0x8000000
MIN_LFS_PAGES = 6
FLASH_PAGE_SIZE = 4 * 1024
MIN_GAP_PAGES = 2

# Update stage file larger than that is not loadable without fix
# https://github.com/flipperdevices/flipperzero-firmware/pull/3676
UPDATER_SIZE_THRESHOLD = 128 * 1024

HEATSHRINK_WINDOW_SIZE = 13
HEATSHRINK_LOOKAHEAD_SIZE = 6
Expand Down Expand Up @@ -117,7 +120,7 @@ def generate(self):
self.logger.error(
f"You are trying to bundle a non-standard stack type '{self.args.radiotype}'."
)
self.disclaimer()
self.show_disclaimer()
return 1

if radio_addr == 0:
Expand All @@ -130,7 +133,9 @@ def generate(self):
if not exists(self.args.directory):
os.makedirs(self.args.directory)

updater_stage_size = os.stat(self.args.stage).st_size
shutil.copyfile(self.args.stage, join(self.args.directory, stage_basename))

dfu_size = 0
if self.args.dfu:
dfu_size = os.stat(self.args.dfu).st_size
Expand All @@ -146,10 +151,10 @@ def generate(self):
):
return 3

if not self.layout_check(dfu_size, radio_addr):
if not self.layout_check(updater_stage_size, dfu_size, radio_addr):
self.logger.warn("Memory layout looks suspicious")
if not self.args.disclaimer == "yes":
self.disclaimer()
if self.args.disclaimer != "yes":
self.show_disclaimer()
return 2

if self.args.splash:
Expand Down Expand Up @@ -198,22 +203,33 @@ def generate(self):

return 0

def layout_check(self, fw_size, radio_addr):
def layout_check(self, stage_size, fw_size, radio_addr):
if stage_size > self.UPDATER_SIZE_THRESHOLD:
self.logger.warn(
f"Updater size {stage_size}b > {self.UPDATER_SIZE_THRESHOLD}b and is not loadable on older firmwares!"
)

if fw_size == 0 or radio_addr == 0:
self.logger.info("Cannot validate layout for partial package")
return True

lfs_span = radio_addr - self.FLASH_BASE - fw_size
self.logger.debug(f"Expected LFS size: {lfs_span}")
lfs_span_pages = lfs_span / (4 * 1024)
if lfs_span_pages < self.MIN_LFS_PAGES:
fw2stack_gap = radio_addr - self.FLASH_BASE - fw_size
self.logger.debug(f"Expected reserved space size: {fw2stack_gap}")
fw2stack_gap_pages = fw2stack_gap / self.FLASH_PAGE_SIZE
if fw2stack_gap_pages < 0:
self.logger.warn(
f"Firmware image overlaps C2 region and is not programmable!"
)
return False

elif fw2stack_gap_pages < self.MIN_GAP_PAGES:
self.logger.warn(
f"Expected LFS size is too small (~{int(lfs_span_pages)} pages)"
f"Expected reserved flash size is too small (~{int(fw2stack_gap_pages)} page(s), need >={self.MIN_GAP_PAGES} page(s))"
)
return False
return True

def disclaimer(self):
def show_disclaimer(self):
self.logger.error(
"You might brick your device into a state in which you'd need an SWD programmer to fix it."
)
Expand Down
Loading