Linux nvmem 子系统全面解析:综合场景、内核机制、实战分析

支持作者新书《Yocto项目实战教程:高效定制嵌入式Linux系统》,点击京东购买

Linux nvmem 子系统全面解析:综合场景、内核机制、实战分析


一、nvmem 是什么?

nvmem 是 Linux 内核中提供的一套给 EEPROM/非易逝存储器 (如 OTP/EFUSE/小宽带 SPI Flash) 综合读写与管理的子系统。

该子系统被应用在不少需要少量压缩信息存储的场景,包括:

  • 网卡 MAC 地址
  • 工厂生产时写入的二进制数据
  • 产品编号/序列号
  • 音频/摄像头/光线设备的标志/校准值

过去这类需每个驱动单独写通信代码,有重复、难以处理同一设备多个使用者等缺点。nvmem 子系统就是为了解决这些问题而出现。


在这里插入图片描述

二、核心概念

1. Cell 、Provider 、Consumer

  • nvmem provider: 提供数据给其他模块或用户端,如 at24 这种 EEPROM 驱动就是 provider

  • nvmem cell: 分割成的一段有意义数据,如 MAC 地址的地址段(经常在 EEPROM 中的 0x00~0x05 地址)

  • nvmem consumer: 使用这段数据的设备/驱动,如网卡驱动读取 MAC

2. 设备树模型

nvmem@50 {
    compatible = "atmel,24c02";
    reg = <0x50>;
    #address-cells = <1>;
    #size-cells = <1>;

    mac_addr: mac@0 {
        reg = <0x0 0x6>;
    };
};
ethernet@30be0000 {
    nvmem-cells = <&mac_addr>;
    nvmem-cell-names = "mac-address";
};

三、驱动端:注册 nvmem 设备

1. EEPROM 为例

#include <linux/nvmem-provider.h>

static const struct nvmem_config eeprom_nvmem_cfg = {
    .name = "eeprom-2-0050",
    .dev = &client->dev,
    .size = size,
    .word_size = 1,
    .stride = 1,
    .read_only = true,
    .reg_read = at24_reg_read,
};

at24->nvmem = devm_nvmem_register(&client->dev, &eeprom_nvmem_cfg);

2. 必填配置项

说明
name设备名
dev对应 struct device
size数据大小
reg_read读取函数
reg_write写入函数(非必)

四、消费端:获取 nvmem 数据

1. nvmem_cell_get()

struct nvmem_cell *cell;
cell = nvmem_cell_get(dev, "mac-address");

2. nvmem_cell_read()

size_t len;
void *data;
data = nvmem_cell_read(cell, &len);
if (!IS_ERR(data))
    memcpy(mac, data, ETH_ALEN);

五、用户端读取

cat /sys/bus/nvmem/devices/eeprom-2-0050/nvmem | hexdump -C

如果设备树中配置了 MAC 地址 cell:

cat /sys/firmware/devicetree/base/ethernet@30be0000/nvmem-cell-names

六、实战分析:at24.c 中如何集成 nvmem

at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
if (IS_ERR(at24->nvmem)) {
    pm_runtime_disable(dev);
    if (!pm_runtime_status_suspended(dev))
        regulator_disable(at24->vcc_reg);
    return PTR_ERR(at24->nvmem);
}

这段代码在 at24_probe() 最后执行,如果注册失败会引发该设备 probe fail。

常见错误如下:

[    1.853129] at24: probe of 2-0050 failed with error -16

通常是 nvmem 名称冲突/注册重复/配置错误。


七、面试问题 & 可口说化答案

问题 1:你怎么说明 nvmem 子系统?

nvmem 是 Linux 内核中对非易逝存储器进行抽象和分组管理的一套框架。它分为 provider 和 consumer,支持设备树创建 cell,可被驱动或用户端通用读取。经常用于 MAC 地址、压缩值、历史历练信息等存储设备。

问题 2:如何从 EEPROM 读 MAC 地址?

通过 nvmem 子系统:

  • EEPROM 作为 provider,在设备树中配置 cell
  • Ethernet 驱动作为 consumer,配置 nvmem-cells
  • 驱动中调用 nvmem_cell_get() + nvmem_cell_read() 读取 MAC

八、总结

  • nvmem 子系统是非易逝存储器管理的标准化接口,读/写分离,简化了多驱动共用同一段数据的约束。
  • 在 Yocto/嵌入式项目中,推荐使用 Descriptor GPIO + nvmem 配置模型,让终端产品更可读懂、可控、可优化。

支持作者新书《Yocto项目实战教程:高效定制嵌入式Linux系统》,点击京东购买

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值