Quick Start¶
What this page covers: Build UBI, run the sample on the simulator, and write your first volume — in about 5 minutes.
Prerequisites: A working
Zephyr development environment
(west, Zephyr SDK).
After reading this: You will have UBI built and running. For deeper integration on real hardware, continue to Configuration and the Cookbook.
Choose your path¶
Path |
What you do |
What you need |
|---|---|---|
Quick evaluation |
Build for |
Zephyr SDK only |
Project integration |
Add UBI as a west module, configure via Kconfig and DeviceTree |
See Configuration |
Hardware testing |
Build for |
STM32CubeProgrammer or nrfjprog, picocom |
This page covers the Quick evaluation path end to end. The other two paths share the same first two steps (initialise the workspace; build).
1. Initialise the workspace¶
west init -l .
west update --narrow -o=--depth=1
2. Build and run the sample on native_sim¶
west build -p --build-dir build/native_sim/sample -b native_sim ./sample/
./build/native_sim/sample/zephyr/zephyr.exe
You should see UBI scan the simulated flash, create a volume, write a record, read it back, and exit cleanly.
3. Your first volume — the 30-line version¶
The snippet below is a self-contained main() showing the four-call
lifecycle: init → create volume → write/read LEB → deinit. Error handling
is omitted for clarity; every API call returns 0 on success or a
negative errno.
#include <ubi.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#define UBI_PARTITION_NAME ubi_partition
#define UBI_PARTITION_DEVICE FIXED_PARTITION_DEVICE(UBI_PARTITION_NAME)
int main(void)
{
const struct device *flash_dev = UBI_PARTITION_DEVICE;
struct flash_pages_info page_info = { 0 };
flash_get_page_info_by_offs(flash_dev, 0, &page_info);
struct ubi_flash_desc flash = {
.partition_id = FIXED_PARTITION_ID(UBI_PARTITION_NAME),
.erase_block_size = page_info.size,
.write_block_size = flash_get_write_block_size(flash_dev),
};
struct ubi_device *ubi = NULL;
ubi_device_init(&flash, NULL, &ubi);
struct ubi_volume_config cfg = {
.name = "my_vol",
.type = UBI_VOLUME_TYPE_DYNAMIC,
.leb_count = 4,
};
int vol_id;
ubi_volume_create(ubi, &cfg, &vol_id);
const char data[] = "Hello, UBI!";
ubi_leb_write(ubi, vol_id, 0, data, sizeof(data));
char buf[64];
ubi_leb_read(ubi, vol_id, 0, 0, buf, sizeof(buf));
ubi_device_deinit(ubi);
return 0;
}
A complete buildable version of this snippet ships in
sample/.
What’s next¶
Concepts at a Glance — the vocabulary used throughout the rest of the docs (PEB, LEB, EC, VID, EBA).
Configuration — Kconfig, DeviceTree overlays, and the memory sizing guide.
Plain UBI Workflow — full lifecycle walkthrough including periodic garbage collection and
read_only_degradedhandling.Cookbook — end-to-end recipes for common deployments.
Test Strategy — how to build and run the test suite, and how coverage and forensic scans are produced.