nvmem(9)
πΈ NAME πΈ
okay so this is nvmem(9) from the Kernel Developer's Manual β yes bestie, kernel land has lore too π
. The whole squad is: nvmem, nvmem_get_cell_len, nvmem_read_cell_by_name, nvmem_read_cell_by_idx, nvmem_write_cell_by_name, nvmem_write_cell_by_idx. That's the lineup, periodt.
β¨ SYNOPSIS β¨
The exact build/config bits and prototypes, no edits, no vibes-only paraphrase:
options FDT
device nvmem
#include <sys/extres/nvmem/nvmem.h>
int
nvmem_get_cell_len(phandle_t node, const char *name);
int
nvmem_read_cell_by_name(phandle_t node, const char *name, void *cell,
size_t buflen);
int
nvmem_read_cell_by_idx(phandle_t node, int idx, void *cell,
size_t buflen);
int
nvmem_write_cell_by_name(phandle_t node, const char *name, void *cell,
size_t buflen);
int
nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell,
size_t buflen);
π DESCRIPTION π
On some embedded boards, the manufacturer stored some data on a NVMEM (Non-Volatile Memory), and it's generally stored in some eeprom or fuses. Like, that's the whole setup, no cap.
The nvmem API is made of helper functions for consumers plus device methods for providers. Two sides of the same glow-up, fr fr.
π§ FUNCTIONS π§
nvmem_get_cell_len(phandle_t node, const char *name)
Get the size of the cell based on the reg property on the node. Return the size, or ENOENT if the cell name wasn't found. That's it, that's the vibe.
nvmem_read_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen)
Get the cell content based on the name. Return 0 on success, or ENOENT if the cell doesn't exist, ENXIO if no provider device was found, and EINVAL if the size isn't correct.
nvmem_read_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen)
Get the cell content based on the id. Return 0 on success, or ENOENT if the cell doesn't exist, ENXIO if no provider device was found, and EINVAL if the size isn't correct. Same energy, different lookup.
nvmem_write_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen)
Write the cell content based on the name. Return 0 on success, or ENOENT if the cell doesn't exist, ENXIO if no provider device was found, and EINVAL if the size isn't correct.
nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen)
Write the cell content based on the id. Return 0 on success, or ENOENT if the cell doesn't exist, ENXIO if no provider device was found, and EINVAL if the size isn't correct.
π¦ DEVICE METHODS π¦
nvmem_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)
Provider device method to read a cell content. Provider bestie behavior, slay.
nvmem_write(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)
Provider device method to write a cell content. Writes are giving main character energy too.
π EXAMPLES π
Consider this DTS:
/* Provider */
eeprom: eeprom@20000 {
board_id: id@0 {
reg = <0x0 0x4>;
};
};
/* Consumer */
device@30000 {
...
nvmem-cells = <&board_id>
nvmem-cell-names = "boardid";
};
The device driver for eeprom@20000 needs to expose itself as a provider:
#include "nvmem_if.h"
int
foo_nvmem_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)
{
/* Read the data */
}
int
foo_attach(device_t dev)
{
phandle_t node;
node = ofw_bus_get_node(dev);
...
/* Registering the device so the consumers can find us */
OF_device_register_xref(OF_xref_from_node(node), dev);
...
}
static device_method_t foo_methods[] = {
...
/* nvmem interface */
DEVMETHOD(nvmem_read, foo_nvmem_read),
/* Terminate method list */
DEVMETHOD_END
};
The consumer device driver for device@30000 can now read the nvmem data:
int
bar_attach(device_t dev)
{
phandle_t node;
uint32_t boardid;
...
node = ofw_bus_get_node(dev);
nvmem_read_cell_by_name(node, "boardid", (void *)&boardid, sizeof(boardid));
...
}
π HISTORY π
The nvmem related function first appear in FreeBSD 12.0. The nvmem interface and manual page was written by Emmanuel Vadot <manu@FreeBSD.org>. Iconic authorship moment, honestly.
π and that's the whole page, bestie. Cute sign-off: this one is from Debian, dated July 24, 2018, and it's filed under nvmem(9). Slay. π
π¦ where this page comes from
- freebsd 14.5: base 14.5
- freebsd 15.1: base 15.1
- Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms