rongbc opened a new pull request, #20014:
URL: https://github.com/apache/nuttx/pull/20014
## Summary
`mtd_partition(mtd, firstblock, nblocks)` takes the partition offset and
size in units of the **underlying device "blocks"** (`geo.blocksize`), not
erase blocks. The implementation is authoritative:
- `drivers/mtd/mtd_partition.c:875` computes `blkpererase = erasesize /
blocksize`;
- `drivers/mtd/mtd_partition.c:885-886` divides the incoming
`firstblock`/`nblocks` by `blkpererase` to derive erase-block boundaries
(`erasestart`/`eraseend`), i.e. the inputs are treated as `blocksize` units;
- `part_bread`/`part_bwrite` (`drivers/mtd/mtd_partition.c:274`/`:296`) use
`priv->firstblock` directly as a block index into the parent device;
- the doc comment at `include/nuttx/mtd/mtd.h:286` ("The offset in bytes to
the first block") is stale — the implementation is what callers must match.
Four board drivers instead accumulated `partoffset` and computed the
partition size in **erase-block** units and passed them straight to
`mtd_partition()`. On devices where `blocksize != erasesize` — W25/SST25 SPI
NOR (256B vs 4KB) and SAMD5E5 program memory (512B vs 8KB cluster) — every
partition came out `erasesize/blocksize` (16x) too small, and partitions after
the first were misaligned/overlapping. On the W25 this is hardware-confirmed: a
512KB partition is reported as 32KB (see Testing).
This change converts `partoffset` and `partszbytes` to `geo.blocksize` units
at the `mtd_partition()` call site while keeping the loop's erase-block
accumulation:
```c
blkpererase = geo.blocksize > 0 ? erasesize / geo.blocksize : 1;
mtd_part = mtd_partition(mtd, partoffset * blkpererase,
partszbytes / geo.blocksize);
partoffset += partszbytes / erasesize;
```
Affected boards:
- `stm32f103-minimum` (W25Q32FV on SPI1)
- `at32f437-mini` (W25, same code as upstream `stm32f103-minimum`)
- `stm32f429i-disco` (SST25F064; the buggy path is enabled in the shipped
`extflash` defconfig)
- `metro-m4` (SAMD5E5 program memory via `mtd_progmem`)
The remaining `mtd_partition()` call sites were audited and are correct:
`b-l475e-iot01a`/`stm32l476vg-disco` already use `geo.blocksize`;
`mikroe-stm32f4` hardcodes the 256B conversion; the progmem OTA boards
(imxrt/nrf5x/samv7/stm32h7) pass page units that equal `geo.blocksize`; the
ESP32/ESP32C3/ESP32S3, BL602, TLSR82, RTL8720C and `fs/partition` paths are
internally consistent.
## Impact
- **Users**: partition sizes on the affected boards are now correct. With
the buggy code, a 512KB partition was reported (and usable) as 32KB only;
partitions already formatted with the buggy code occupy only
`blocksize/erasesize` of the intended region and should be
re-created/reformatted after this change.
- **Build**: no new configuration options, no new dependencies, no API/ABI
change (`mtd_partition()` signature untouched). Pure board-level code change.
- **Hardware**: only boards that enable the affected partition paths and
have `blocksize != erasesize` are affected; devices with `blocksize ==
erasesize` (e.g. `CONFIG_W25_SECT512`) behave unchanged.
- **Documentation**: none (the stale comment at
`include/nuttx/mtd/mtd.h:286` could be fixed separately; out of scope here).
- **Security**: none.
## Testing
**Hardware (bug reproduction, before fix)** — environment:
| Item | Value |
| --- | --- |
| NuttX baseline | master @ `15678acf` |
| Board | `stm32f103-minimum` code, reproduced on its derived board
`stm32f103-mini-v2` (STM32F103RCT6) |
| External FLASH | W25Q16 (2MB, SPI1, CS=PA2) |
| Config | `CONFIG_STM32F103MINIMUM_FLASH=y`,
`CONFIG_STM32F103MINIMUM_FLASH_PART=y`, `CONFIG_MTD_SMART=y`,
`CONFIG_FS_SMARTFS=y`; partition list `512,512,512,512` (4×512KB) |
| Toolchain / build | arm-none-eabi-gcc 10.3-2021.10; `./tools/configure.sh
-l stm32f103-minimum:xxx && make` |
Test steps and result:
1. Flash the build, boot, then `mksmartfs /dev/smart0p1` and mount it.
2. The partition reports **32KB instead of the expected 512KB** (512KB ÷ 16
= 32KB; 16 = erasesize/blocksize = 4096/256). Partitions after the first are
also misaligned.
3. 32KB happens to be a multiple of the 4KB erase block, so the partition is
created without error — it is simply the wrong size.
**After the fix (this workspace, compile-level):**
- Host: Linux; toolchain arm-none-eabi-gcc 10.3-2021.10; NuttX master @
`15678acf` + this change.
- `stm32f103-minimum/src/stm32_w25.c` and `at32f437-mini/src/at32_w25.c`:
`-fsyntax-only` with the partition path emulated
(`CONFIG_STM32_SPI1`/`CONFIG_AT32_SPI1`, `CONFIG_MTD_W25`,
`CONFIG_*_FLASH_PART`, `CONFIG_FS_SMARTFS`, `CONFIG_MTD_SMART`, ...) → **exit
0, no errors**.
- `stm32f429i-disco/src/stm32_bringup.c` and
`samd5e5/metro-m4/src/sam_smartfs.c`: full-file syntax check is not possible in
this workspace (generated `include/nuttx/config.h`/`include/arch/chip` point at
a stale, different board build); the exact edited statements were extracted
from disk into a type-stub harness reproducing the real signatures and compiled
with `-Wall -Wextra` → **exit 0, no errors**.
- Tree-wide grep confirms no remaining `mtd_partition(..., partszbytes /
erasesize)` call sites.
**Expected post-fix hardware result (to be confirmed on board):** repeating
the same steps above, `/dev/smart0p1` should report **512KB**, and
`/dev/mtd0p*` offsets should be contiguous and non-overlapping.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]