本文为 FEMU开源SSD仿真平台 源码深度解析系列,专注讲解 ftl.c 核心实现。
适合方向:SSD存储仿真、FTL算法、NAND Flash仿真、毕业设计/科研实验。


一、前言:什么是FEMU与FTL

1.1 FEMU简介

FEMU 是一个基于QEMU的开源SSD仿真器,专门用于白盒/黑盒SSD仿真、性能测试、FTL算法研究,广泛用于学术界与工业界存储系统实验。

1.2 FTL是什么

FTL(Flash Translation Layer) 是SSD的核心灵魂,负责:

  • 逻辑地址(LBA/LPN) ↔ 物理地址(PPA) 映射
  • 垃圾回收(GC)
  • 磨损均衡
  • 坏块管理
  • 写放大控制

本文解析的 ftl.c,就是FEMU中完整实现FTL核心功能的源码文件。

二、ftl.c 整体功能定位

ftl.c = FEMU的FTL层核心实现

它的核心作用:

  1. 接收上层IO读写请求
  2. 完成逻辑页号(LPN) → 物理页地址(PPA)转换
  3. 管理NAND Flash的块、线、通道、Plane
  4. 执行GC(垃圾回收)
  5. 支持FDP(NVMe Flexible Data Placement)数据放置扩展

三、源码结构与核心模块划分

ftl.c 代码分为 6大核心模块:

模块1:全局声明与工具函数

static void *ftl_thread(void *arg);
static inline bool should_gc(struct ssd *ssd);
static inline struct ppa get_maptbl_ent(struct ssd *ssd, uint64_t lpn);
static void ssd_init_lines(struct ssd *ssd);
  • 定义GC判断、映射表读写、地址转换等基础工具
  • 提供LPN ↔ PPA快速转换

模块2:SSD初始化逻辑

void ssd_init(FemuCtrl *n)
{
    ssd_init_params(spp, n);
    ssd_init_maptbl(ssd);
    ssd_init_rmap(ssd);
    ssd_init_lines(ssd);
    ...
}

功能:

  • 初始化SSD硬件参数
  • 初始化映射表(maptbl)与反向映射表(rmap)
  • 初始化Line(超级块)管理
  • 区分FDP模式/普通模式

模块3:地址映射(核心)

static inline struct ppa get_maptbl_ent(...)
static inline void set_maptbl_ent(...)
static inline void set_rmap_ent(...)
  • maptbl:LPN → PPA(正向映射)
  • rmap:PPA → LPN(反向映射,GC必须用到)

模块4:写指针与空间分配

static struct ppa get_new_page(struct ssd *ssd)
static void ssd_advance_write_pointer(struct ssd *ssd)
  • 模拟SSD实际写入顺序
  • 按Channel/Lun/Block/Page依次分配新物理页

模块5:垃圾回收GC(最核心)

static int do_gc(struct ssd *ssd, bool force)
static struct line *select_victim_line(...)
static void clean_one_block(...)

GC流程:

  1. 选择无效页最多的Line作为受害者
  2. 迁移有效页到新位置
  3. 擦除整块
  4. 重新加入空闲队列

模块6:IO读写入口

static uint64_t ssd_read(struct ssd *ssd, NvmeRequest *req)
static uint64_t ssd_write(struct ssd *ssd, NvmeRequest *req)
static uint64_t ssd_trim(struct ssd *ssd, NvmeRequest *req)
  • 处理上层NVMe读写指令
  • 写操作会自动触发GC
  • Trim指令用于标记无效页

模块7:FDP扩展支持

uint64_t nvme_do_write_fdp(...)
static int do_gc_fdp_style(...)

FDP = NVMe灵活数据放置,支持流隔离、按RU回收、降低写放大。

四、核心函数逐行解析

4.1 ssd_init():SSD全局初始化

void ssd_init(FemuCtrl *n)
{
    ssd_init_params(spp, n);      // 配置SSD参数
    ssd_init_maptbl(ssd);         // 初始化映射表
    ssd_init_rmap(ssd);          // 反向映射
    ssd_init_lines(ssd);         // 初始化超级块
    qemu_thread_create(&ssd->ftl_thread, ...);  // 启动FTL线程
}

作用: 启动时一次性构建好整个SSD的存储结构与映射表。

4.2 ssd_write():写流程

static uint64_t ssd_write(struct ssd *ssd, NvmeRequest *req)
{
    // 1. 检查是否需要GC
    while (should_gc_high(ssd)) {
        do_gc(ssd, true);
    }

    // 2. 旧地址失效
    mark_page_invalid(ssd, &ppa);

    // 3. 分配新物理页
    ppa = get_new_page(ssd);

    // 4. 更新映射表
    set_maptbl_ent(ssd, lpn, &ppa);
    set_rmap_ent(ssd, lpn, &ppa);

    // 5. 推进写指针
    ssd_advance_write_pointer(ssd);
}

写流程总结:
GC检查 → 旧页失效 → 分配新页 → 更新映射 → 推进指针

4.3 do_gc():垃圾回收

static int do_gc(struct ssd *ssd, bool force)
{
    victim_line = select_victim_line(ssd, force);

    // 迁移有效数据
    for (ch, lun) {
        clean_one_block(ssd, &ppa);
        mark_block_free(ssd, &ppa);
    }

    // 标记Line为空闲
    mark_line_free(ssd, &ppa);
}

GC本质: 腾挪有效数据 → 擦除块 → 回收空间

4.4 ftl_thread():FTL后台线程

static void *ftl_thread(void *arg)
{
    while (1) {
        // 处理读写IO
        process_io();

        // 后台GC
        if (should_gc(ssd)) {
            do_gc(ssd, false);
        }
    }
}
  • 独立线程异步处理IO与GC
  • 不阻塞上层系统

五、重要的数据结构

5.1 PPA:物理页地址

struct ppa {
    uint32_t ch;      // 通道
    uint32_t lun;     // 逻辑单元
    uint32_t pl;      // plane
    uint32_t blk;     // 块
    uint32_t pg;      // 页
};

代表NAND Flash中唯一物理位置。

5.2 Line:超级块(FEMU特色)

  • Line = 跨所有Channel/Lun的一组Block
  • 目的:提升并行读写性能

5.3 maptbl & rmap

  • maptbl[LPN] = PPA
  • rmap[PPA] = LPN

GC必须依靠反向映射才能找到有效数据归属。

六、FDP特性:高级FTL模式

你提供的代码中包含大量 FDP相关函数:

  • nvme_do_write_fdp
  • do_gc_fdp_style
  • fdp_get_new_page
  • mark_page_invalid_fdp

FDP作用:

  1. 数据按流隔离(冷热数据分离)
  2. RU(回收单元)独立管理
  3. 降低写放大WAF
  4. 提升GC效率

适合用于企业级SSD、QoS保障、数据库SSD优化。

七、总结:ftl.c 到底在做什么?

  • 执行 ./run-blackbox.sh
  • QEMU启动
  • FEMU加载 ftl.c
  • 模拟出一块完整行为的NVMe SSD

建议学习路径:
ssd_init → ssd_write → do_gc → FDP扩展

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐