diff options
| author | Ned Konz <ned@metamagix.tech> | 2025-10-01 10:56:41 -0700 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-10-22 10:22:48 +1100 |
| commit | 7090fc5dd63bc1dcbe5470e2000ed333cb867d64 (patch) | |
| tree | b18cc4a35da5d9f51db0358d83025e98639f1543 /ports/zephyr/modules/_boot.py | |
| parent | b1802eb0e1363fb7d0d2c618a3522b84978c77d2 (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.py | 73 |
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 |
