当前位置: 首页 > news >正文

NAND Flash 完整识别注册配置流程

一、整体架构图

┌─────────────────────────────────────────────────────────────────┐ │ 用户空间 │ │ mount /dev/mtdblock0 │ └─────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────────┐ │ VFS / MTD 层 │ │ mtd_device_parse_register() │ │ 分区解析 (cmdlinepart/ofpart) │ └─────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────────┐ │ NAND 核心层 (nand_base.c) │ │ nand_scan() → nand_scan_ident() → nand_scan_tail() │ │ ID 识别、参数解析、ECC 配置、BBT 扫描 │ └─────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────────┐ │ NAND 控制器驱动 (ls-nand.c) │ │ ls_nand_probe() → 硬件初始化、回调函数注册 │ └─────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────────┐ │ 硬件抽象层 │ │ 寄存器操作、DMA 配置、片选控制、命令发送 │ └─────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────────┐ │ 物理硬件 │ │ NAND Flash 芯片 (三星/镁光等) + NAND 控制器 │ └─────────────────────────────────────────────────────────────────┘

二、U-Boot/PMON 阶段配置

2.1 U-Boot 中的 NAND 初始化

// U-Boot: drivers/mtd/nand/raw/ls_nand.c (示例)intboard_nand_init(structnand_chip*nand){// 1. 初始化 GPIO 和片选nand->select_chip=ls_nand_select_chip;// 2. 配置控制器时序writel(NAND_TIMING_VALUE,NAND_TIM_REG);// 3. 读取 ID 并验证nand->cmdfunc(nand,NAND_CMD_READID,0x00,-1);manufacturer_id=nand->read_byte(nand);device_id=nand->read_byte(nand);// 4. 设置总线宽度if(device_id&0x01)nand->options|=NAND_BUSWIDTH_16;// 5. 传递参数给内核 (通过设备树或命令行)setenv("nand_size","512M");setenv("mtdparts","nand0,128k(uboot),256k(kernel),-(rootfs)");return0;}

2.2 U-Boot 传递 MTD 分区信息

# U-Boot 环境变量setenv mtdids'nand0=loongson-nand'setenv mtdparts'mtdparts=loongson-nand:128k(uboot)ro,256k(kernel),256k(dtb),-(rootfs)'saveenv

2.3 PMON 中的配置 (龙芯平台)

// PMON: arch/mips/loongson/common/nand.cvoidnand_init(void){// 1. 配置 NAND 控制器寄存器REG32(NAND_CTRL_REG)=NAND_CTRL_ENABLE;// 2. 设置时序参数REG32(NAND_TIMING_REG)=0x412;// 3. 读取芯片 IDnand_read_id(&id_data);// 4. 传递给内核的命令行参数prom_add_cmdline("mtdparts=loongson-nand:128k(uboot)ro,256k(kernel),-(rootfs)");}

三、设备树 (Device Tree) 配置

3.1 完整的 DTS 节点配置

// arch/mips/boot/dts/loongson/ls2k.dtsi &nand_controller { compatible = "loongson,ls-nand"; reg = <0x1fe00000 0x100>, // NAND 控制器寄存器 <0x1fe00100 0x100>; // DMA 数据访问地址 interrupts = <0 25 4>; // 中断号 #address-cells = <1>; #size-cells = <1>; // DMA 配置 dmas = <&dma 0>; dma-names = "nand_rw"; dma-mask = <0xffffffffffffffff>; // 64 位 DMA 掩码 // NAND 芯片配置 nand@0 { reg = <0>; // 片选号 (CS0) nand-cs = <0>; // 片选索引 chip_cap = <3>; // 容量等级 (1GB 8Gb) nand-bus-width = <8>; // 总线宽度 8/16 位 nand-ecc-algo = "bch"; // ECC 算法 nand-ecc-strength = <4>; // ECC 校正位数 nand-ecc-step-size = <512>; // ECC 计算步长 label = "loongson-nand"; // MTD 设备名称 // 分区表 (可选,也可通过命令行指定) partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "uboot"; reg = <0x0 0x20000>; // 128KB read-only; }; partition@20000 { label = "kernel"; reg = <0x20000 0x40000>; // 256KB }; partition@60000 { label = "dtb"; reg = <0x60000 0x40000>; // 256KB }; partition@a0000 { label = "rootfs"; reg = <0xa0000 0x0>; // 剩余空间 }; }; }; // 第二片 NAND (如果存在) nand@1 { reg = <1>; nand-cs = <1>; chip_cap = <3>; nand-ecc-algo = "bch"; nand-ecc-strength = <4>; label = "loongson-nand1"; }; };

3.2 关键参数说明

属性含义取值范围说明
nand-cs片选号0-3对应物理 CS 引脚
chip_cap容量等级0-15见 cap2cs 映射表
nand-bus-width总线宽度8/16数据总线位数
nand-ecc-algoECC 算法none/bch/hw纠错算法类型
nand-ecc-strengthECC 强度4/8/16/24可校正比特数
nand-ecc-step-sizeECC 步长512/1024每块计算 ECC 的数据大小

四、Linux 内核驱动流程

4.1 驱动探测 (Probe) 流程

platform_driver_register() │ ▼ ls_nand_init() → platform_driver_register(&ls_nand_driver) │ ▼ ls_nand_probe() [ls-nand.c:600] │ ├── 1. 解析设备树参数 │ ├── nand-cs → info->cs0 │ ├── chip_cap → info->chip_cap │ └── nand-ecc-algo → ecc.mode │ ├── 2. 分配内存 │ ├── kzalloc(mtd_info + ls_nand_info) │ ├── dma_alloc_coherent(data_buff) │ └── dma_alloc_coherent(desc_addr) │ ├── 3. 映射寄存器 │ ├── ioremap(mmio_base) │ └── ioremap(dma_order_reg) │ ├── 4. 初始化回调函数 │ └── ls_nand_init_mtd() │ ├── cmdfunc = ls_nand_cmdfunc │ ├── select_chip = ls_nand_select_chip │ ├── read_byte = ls_nand_read_byte │ └── write_buf = ls_nand_write_buf │ ├── 5. NAND 识别 │ ├── nand_scan_ident(mtd, 1, NULL) │ │ ├── nand_get_flash_type() │ │ │ ├── 读 ID (NAND_CMD_READID) │ │ │ ├── 查表匹配 │ │ │ └── 解析几何参数 │ │ └── 多芯片检测 (maxchips=1) │ │ │ └── nand_scan_tail(mtd) │ ├── ECC 配置 │ ├── BBT 扫描
http://www.jsqmd.com/news/460928/

相关文章:

  • 电源测试系统编程软件选择:LabVIEW与ATECLOUD对比
  • 电车企业销量连连暴跌,技术神话正在破灭,燃油车优势凸显
  • 美国智驾激进转向,吓坏乘客,智驾安全靠其他人类驾驶员避让
  • 洁净车间专用的人数统计摄像机能当监控摄像头吗
  • <C++学习>C++ 静态函数
  • 在vue3中实现动态加载组件
  • 美格智能港股上市:募资11亿港元 市值88亿港元 第三季净利降50%
  • 2026年Q1吉林优秀路边石直销厂家综合评测与推荐 - 2026年企业推荐榜
  • 03 别再用 CGLIB 了!深度解析 Byte Buddy:为什么它是现代 Java 框架的首选?
  • 2026年知名的破碎磨粉机品牌推荐:破碎磨粉机公司选择指南 - 品牌宣传支持者
  • FPN网络学习
  • 2026年吉林石材厂选购指南:五大厂商深度评测与推荐 - 2026年企业推荐榜
  • 别焦虑!保姆级OpenClaw上手方案来袭!
  • GitCode gitee 上传超过10m大文件附件的方法
  • 2026年比较好的粉碎机厂家推荐:塑料粉碎机可靠供应商推荐 - 品牌宣传支持者
  • 人脸识别dlib下载与安装
  • Flutter 三方库 super_log 的鸿蒙化适配指南 - 实现极具视觉冲击力的彩色终端日志、支持动态过滤与全局异常捕获
  • 如何在Python中实现随机睡眠:从基础到进阶
  • 高效异步请求处理:Python多线程与协程实践指南
  • AI角色的“倾斜角度“处理原理
  • 【2025最新】基于SpringBoot+Vue的高校实习管理系统管理系统源码+MyBatis+MySQL
  • 2026年靠谱的螺纹通规检测机品牌推荐:螺栓通止规检测机源头工厂推荐 - 品牌宣传支持者
  • 2026年3月山东伸缩缝实力企业盘点与深度解析 - 2026年企业推荐榜
  • 用Claude写代码,选什么语言最快?实测13种编程语言后的意外发现
  • 从代码生成到数字生命:构建演化的模块库
  • Java全栈开发面试实录:从基础到实战的全面解析
  • 未来之窗昭和仙君(八十四)系统_拍照功能说明书—东方仙盟练气
  • 2026年口碑好的异型珍珠棉板材公司推荐:EPE珍珠棉异型板材工厂直供推荐 - 品牌宣传支持者
  • 加速Python依赖安装:使用国内镜像源优化pip install
  • UID9622/TaiGenesis 双系统确认 | 概念盗窃审计报告(这是最初的创作报告,八个月前的整套逻辑在手,请自重).