Metadata-Version: 2.4
Name: realfs-python
Version: 0.1.0
Summary: Python bindings and image tools for the REALFS embedded filesystem
Home-page: https://github.com/Ameba-AIoT/ameba-rtos
License: Apache-2.0
Project-URL: Source, https://github.com/Ameba-AIoT/ameba-rtos
Project-URL: Issues, https://github.com/Ameba-AIoT/ameba-rtos/issues
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Filesystems
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-python
Dynamic: summary

# realfs — Python bindings to the real REALFS core

制作/检查可直接烧录到 **VFS 分区**的 REALFS 镜像(上电即挂载读取预置文件)。

与 `littlefs-python` 的思路一致:**不重写磁盘格式**,而是把真实的文件系统源码
`realfs.c` 编译成一个共享库来调用,所以产出的镜像与固件写出的**逐字节一致**,
不会随内核演进而漂移。

加载方式(方案C,**用户端不需要编译器**):
- 加载 `realfs/prebuilt/` 里**本平台的预编译库**(如 `_librealfs.linux-x86_64.so`),直接用。
- 若本平台**没有**预编译库,或库与当前 `realfs.c` **不一致**(与 `prebuilt/SOURCES.sha256`
  比对),**直接报错并提示去更新库**——不会本地自动编译。
- **维护约定**:每次改动 realfs 核心代码,维护者用 `build_lib.py`(或 CI)**同步重编所有平台的库并提交**,保证库始终与 realfs.c 对齐。

## 安装 / 使用

无需安装,直接用仓库内的 `mkrealfs.py`;或可编辑安装成库:

```bash
pip install -e tools/realfs_py      # 之后任何地方都能 import realfs
```

### 命令行

```bash
# 2 MB NOR-direct,收录 ./assets 下所有文件(挂载路径为相对路径)
./mkrealfs.py nor-direct --size 2M --dir assets -o realfs_nor.bin

# 512 KB NOR@512B,逐个指定文件(host路径:REALFS路径)
./mkrealfs.py nor-512 --size 512K --file cfg.json:cfg/boot.json -o out.bin

# 32 MB NAND(2048B 页、每擦除块 64 页)
./mkrealfs.py nand --size 32M --page-size 2048 --block-pages 64 --dir assets -o n.bin

# 等价形式
python -m realfs nor-direct --size 2M --dir assets -o realfs_nor.bin
```

### 库 API

```python
import realfs
files = {"ui/logo.png": open("logo.png","rb").read(), "cfg/boot.json": b"{}"}

img = realfs.nor_direct_image(2*1024*1024, files)          # -> bytes
open("realfs_nor.bin","wb").write(img)

realfs.nor_direct_list(img)                                 # [(path, size), ...]
realfs.nor_direct_read(img, "ui/logo.png")                  # -> bytes

realfs.nor512_image(512*1024, files)                        # NOR@512B
realfs.nand_image(32*1024*1024, files, page_size=2048, block_pages=64)  # 含 LBM 封装
# 对应的 *_list / *_read 亦可用于回读校验
```

## 预编译库(方案C:免编译分发)

让使用者**不装编译器**就能用:预先为各平台编好库、随仓库提交到 `realfs/prebuilt/`。

- **每个平台各编一次**:在该平台上跑 `python build_lib.py`,产物落到
  `realfs/prebuilt/_librealfs.<平台-架构><后缀>`,并刷新 `prebuilt/SOURCES.sha256`;
  `git add` 后提交。
- **凑不齐机器?用 CI**:`.github/workflows/realfs-prebuilt.yml` 用 GitHub 免费托管
  runner 一次编出四平台(Linux x86-64 / Windows x64 / macOS arm64 / macOS x86-64),
  下载 artifact 后提交进 `prebuilt/`。本仓库是内部 Gerrit,需把本工具子目录镜像到
  (私有)GitHub 跑该 workflow;任何带 C 编译器的 CI(GitLab/Jenkins)也能调 `build_lib.py`。
- **realfs.c 改动后**:预编译库会与源码指纹比对并告警;需重新 `build_lib.py` 并重提交
  各平台库。

支持平台的命名标签见 `realfs.platform_tag()`:`linux-x86_64` / `win-amd64` /
`macos-arm64` / `macos-x86_64`。未命中已提交平台时,自动回退到本地编译(需编译器)。

## 在线验证各平台库 + 生成板级 bin(GitHub Actions)

`realfs/.github/workflows/realfs-prebuilt.yml`(仓库根 = realfs 目录时生效)会在四个
托管 VM 上:**编库 → 用该平台库跑三模式 round-trip → 生成 3 个板级 bin → 跨平台字节一致比对**。

- 触发:GitHub → Actions → `realfs-prebuilt` → **Run workflow**,按你板子填几何:
  `nor_size` / `nor512_size` / `nand_size` / `nand_page` / `nand_block_pages`
  (默认 `2M/512K/32M/2048/64`,**必须改成与固件 VFS 分区/芯片一致**,否则板子挂不起来)。
- CI 用**真实的 `mkrealfs.py` CLI**(用户实际命令)生成 bin,再用 `mkrealfs.py read` 读回校验。
- 产物(每平台两个 artifact):
  - `librealfs-<tag>`:预编译库(提交回 `realfs/prebuilt/`)。
  - `bins-<tag>`:`realfs_nor-direct_<tag>.bin` / `realfs_nor-512_<tag>.bin` / `realfs_nand_<tag>.bin`,
    各含一个 `test.txt`(写明平台+memory);烧到板子 `cat test.txt` 即可确认 mount+read。
- bin 是纯数据、跨平台字节相同(`compare` job 强制校验),物理上每种 memory 烧一个即可。

**触发该 workflow 需要推到 realfs-prebuilt 仓库的最小文件(仓库根 = realfs 目录,共 11 个):**
```
realfs.c  realfs.h  realfs_bdev.h  realfs_erasedev.h        # 核心
.github/workflows/realfs-prebuilt.yml                       # CI
tools/mkrealfs.py                                           # CLI 入口(CI 生成+读回都用它)
tools/realfs_py/build_lib.py                                # 编库
tools/realfs_py/realfs/__init__.py                          # 加载+API
tools/realfs_py/realfs/cli.py                               # CLI 实现(build/list/read)
tools/realfs_py/realfs/lbm.py                               # nand 的 LBM 封装
tools/realfs_py/realfs/csrc/realfs_shim.c                   # C ABI(自带 RAM 块设备/擦除设备)
```
不需要:`__main__.py`/`pyproject.toml`/`README`/`port/`/`prebuilt/`(库是产物)。

`list` / `read` 子命令也可本地检查镜像(nand 因镜像可能被裁剪,需 `--size` 分区大小):
```
mkrealfs.py list nand out.bin --size 32M --block-pages 64
mkrealfs.py read nand out.bin test.txt --size 32M --block-pages 64 -o got.txt
```

## NAND 镜像与坏块(重要)

NAND 镜像按 **"跳坏块"烧录模型**生成(与 `tools/image_scripts/lfs2lbm.py` 一致):
- 只输出**逻辑块(usable)**,每个逻辑块一个 PEB(空块输出空白 PEB);默认裁掉尾部空块,`--full` 保留全部 usable。
- **绝不输出 reserved 块**——它们是 LBM 的坏块跳转余量,必须保持擦除态,否则在有坏块的芯片上会占掉余量、把高逻辑块(含超级块)挤出分区。
- 前提:**烧录工具必须是跳坏块的**(每个 PEB 自带 `lblk`,落到哪个好块 LBM 都能重建映射)。
- 注意:REALFS 超级块环在**高逻辑端**(seg `usable-2`),所以尾部裁剪对 nand 省不了多少;且当坏块数超过 reserved 余量这种异常情况下,超级块可能烧不上导致挂载失败(REALFS-on-NAND 固有特性,板上格式化亦然)。

## 三种布局(必须与固件的 REALFS 配置一致)

| 模式 | 介质 | 说明 |
|---|---|---|
| `nor-direct` | SPI-NOR 直接 | 逻辑块 4096B == 4KB 擦除扇区,平坦块镜像即 flash 内容。 |
| `nor-512` | SPI-NOR 512B map | 每个 4KB 扇区 = 1 段(8×512B 页),擦除感知路径;平坦镜像。 |
| `nand` | SPI-NAND + LBM 薄 FTL | REALFS 逻辑镜像封装进 LBM 物理布局(页0=meta 头,页1=block 头,页2..=数据)。ECC/坏块由烧录工具/芯片下载时处理。 |

## 几何对齐(关键)

`--size` 必须等于固件 VFS 分区大小;NAND 的 `--page-size` / `--block-pages` 取实际芯片
参数(如 GD5F1GM7:2048B / 64 页)。NAND 的 `total/reserved/usable/seg_pages` 计算与
固件 `lbm_core.c` 一一对应,几何不一致会导致挂载失败。

## 目录

```
realfs_py/
  pyproject.toml
  realfs/
    __init__.py        # ctypes 加载 + 平台预编译库管理 + 三种模式 API
    __main__.py        # python -m realfs
    cli.py             # 命令行前端
    lbm.py             # NAND 的 LBM 物理层封装/反解
    csrc/realfs_shim.c # 真实内核之上的扁平 C ABI(自带 RAM 块设备 + RAM 擦除设备)
    prebuilt/          # 各平台预编译库 + SOURCES.sha256(CI 产出后提交)
```

`realfs_shim.c` **只链接已提交的 `../../realfs.c`**(真实核心);host 侧的 RAM 块设备
与 RAM 擦除设备都内联在 shim 里,因此工具**不依赖任何未提交的 host 文件**(不需要
`port/` 下的 sim 后端),镜像也不会与固件格式产生分歧。
