summaryrefslogtreecommitdiff
path: root/ports/zephyr/modules/_boot.py
diff options
context:
space:
mode:
authorNed Konz <ned@metamagix.tech>2025-10-01 10:56:41 -0700
committerDamien George <damien@micropython.org>2025-10-22 10:22:48 +1100
commit7090fc5dd63bc1dcbe5470e2000ed333cb867d64 (patch)
treeb18cc4a35da5d9f51db0358d83025e98639f1543 /ports/zephyr/modules/_boot.py
parentb1802eb0e1363fb7d0d2c618a3522b84978c77d2 (diff)
zephyr: Mount all disks and flash partition, formatting if necessary.
Existing C code in `main.c` only mounts a flash filesystem if one exists, and doesn't do anything if the 'storage' partition is not formatted. This commit moves the mounting logic from `main.c` to frozen code using `modules/_boot.py` and adds the formatting of a previously unformatted partition if the mount fails. Every available disk (in the newly added `DiskAccess.disks` tuple) will be mounted on separate mount points (if they're formatted), and the 'storage' flash partition (if any) will be mounted on /flash (and will be formatted as LFS2 if necessary). Also, `sys.path` will be updated with appropriate 'lib' subdirectories for each mounted filesystem. The current working directory will be changed to the last `DiskAccess.disk` mounted, or to /flash if no disks were mounted. Then `boot.py` and `main.py` will be executed from the current working directory if they exist. Thanks to @VynDragon for the logic in `zephyr/zephyr_storage.c`. Signed-off-by: Ned Konz <ned@metamagix.tech>
Diffstat (limited to 'ports/zephyr/modules/_boot.py')
-rw-r--r--ports/zephyr/modules/_boot.py73
1 files changed, 73 insertions, 0 deletions
diff --git a/ports/zephyr/modules/_boot.py b/ports/zephyr/modules/_boot.py
new file mode 100644
index 000000000..5af302fad
--- /dev/null
+++ b/ports/zephyr/modules/_boot.py
@@ -0,0 +1,73 @@
+# ruff: noqa: F821
+import sys
+import os
+from micropython import const
+import vfs # vfs is always available
+import zephyr
+
+# FlashArea depends on CONFIG_FLASH_MAP
+FlashArea = getattr(zephyr, "FlashArea", None)
+
+# DiskAccess depends on CONFIG_DISK_ACCESS
+DiskAccess = getattr(zephyr, "DiskAccess", None)
+
+_FLASH = const("/flash")
+_FLASH_LIB = const("/flash/lib")
+_STORAGE_KEY = const("storage")
+_FLASH_EXISTS = False
+
+
+def create_flash_partition():
+ """Create an LFS2 filesystem on the partition labeled storage
+ and mount it on /flash.
+ Return True if successful, False otherwise.
+ """
+ if _STORAGE_KEY in FlashArea.areas:
+ # TODO: get the erase block size from DTS instead of 4K.
+ bdev = FlashArea(FlashArea.areas[_STORAGE_KEY], 4096)
+ retval = True
+ try:
+ vfs.mount(bdev, _FLASH)
+ except OSError:
+ try:
+ vfs.VfsLfs2.mkfs(bdev)
+ vfs.mount(bdev, _FLASH)
+ except OSError:
+ print("Error formatting flash partition")
+ retval = False
+ return retval
+ return False
+
+
+def mount_all_disks():
+ """Now mount all the DiskAreas (if any)."""
+ retval = False
+ for da_name in DiskAccess.disks:
+ mount_name = f"/{da_name.lower()}"
+ da = DiskAccess(da_name)
+ try:
+ vfs.mount(da, mount_name)
+ sys.path.append(f"{mount_name}/lib")
+ os.chdir(mount_name)
+ retval = True
+ except OSError as e:
+ print(f"Error mounting {da_name}: {e}")
+ return retval
+
+
+if FlashArea and create_flash_partition():
+ _FLASH_EXISTS = True
+
+# Prefer disks to /flash
+if not (DiskAccess and mount_all_disks()):
+ if _FLASH_EXISTS:
+ os.chdir(_FLASH)
+
+# Place /flash/lib last on sys.path
+if _FLASH_EXISTS:
+ sys.path.append(_FLASH_LIB)
+
+# Cleanup globals for boot.py/main.py
+del FlashArea, DiskAccess, zephyr
+del sys, vfs, os, const
+del create_flash_partition, mount_all_disks, _FLASH_EXISTS