spi flash linux,linuxshell自动化运维

大家好,关于spi flash linux很多朋友都还不太明白,今天小编就来为大家分享关于linuxshell自动化运维的知识,希望对各位有所帮助!

spi flash启动linux一般使用什么rootfs

一直对linux启动时挂载根文件系统的过程存在着很多疑问,今天在水木精华区找到了有用的资料,摘录如下:1。linux启动时,经过一系列初始化之后,需要mount根文件系统,为最后运行init进程等做准备,mount根文件系统有这么几种方式:

1)文件系统已经存在于硬盘(或者类似的设备)的某个分区上了,kernel根据启动的命令行参数(root=/dev/xxx),直接进行mount。这里有一个问题,在root文件系统本身还不存在的情况下,kernel如何根据/dev/xxx来找到对应的设备呢?注意:根文件系统和其他文件系统的mount方式是不一样的,kernel通过直接解析设备的名称来获得设备的主、从设备号,然后就可以访问对应的设备驱动了。所以在init/main.c中有很长一串的root_dev_names(如hda,hdab,sda,sdb,nfs,ram,mtdblock……),通过这个表就可以根据设备名称得到设备号。注意,bootloader或内核中设定的启动参数(root=/dev/xxx)只是一个代号,实际的根文件系统中不一定存在这个设备文件!

openwrt打开spiflash

openwrtspiflash分区适配过程openwrt spi flash分区适配过程这里基于 openwrt mt7620a平台来跟踪,主要是想理清 dts里的分区描述是如何一步步转化成内核分区行为。先来看看 dts中关于分区的描述:palmbus@10000000{spi@b00{status="okay";m25p80@0{#address-cells=<1>;#size-cells=<1>;compatible="w25q128";reg=<0 0>;linux,modalias="m25p80","w25q128";spi-max-frequency=<10000000>;partition@0{label="u-boot";reg=<0x0 0x30000>;read-only;};partition@30000{label="u-boot-env";reg=<0x30000 0x10000>;read-only;};factory: partition@40000{label="factory";reg=<0x40000 0x10000>;read-only;};partition@50000{label="firmware";reg=<0x50000 0xfb0000>;};};};dts描述的是一个树状结构。spi控制器挂在 platform总线上,spi flash(w25q128)挂在 spi总线上。探测到 spi flash的流程如下:1.plat_of_setup()遍历 palmbus上的设备,并为每一个动态创建 platform_device,添加到系统总线上 device_add()。对于 spi这里会创建一个名为"ralink,rt2880-spi"的 platfrom_device并添加到系统中。

2.drivers/spi/spi-rt2880.c中会注册 spi的 platform_driver,与上一步的 platfrom_device match上了之后,触发调用 rt2880_spi_probe()。3.spi_register_master()向系统注册 spi主控制器,并最后调用 of_register_spi_devices(master)看看 dts中在 spi总线上有哪些设备。4.对 dts中描述的每一个 spi总线下的设备,为其创建相应的 spi_device,同时根据 dts中描述的 reg, spi-cpha, spi-cpol, spi-cs-high, spi-3wire, spi-max-frequency等属性来配置该 spi设备。对于这里,创建了一个名为“m25p80”的 spi_device。5.drivers/mtd/device/m25p80.c中有名为“m25p80"的 spi_driver,于是 match上了。触发执行 m25p_probe()。6.m25p_probe()中读到了这颗 spi flash的 id后,确认了一些基本信息(如页大小、块大小),最后调用 mtd_device_parse_register()开始真正的分区。分区解析器part_parser用来按照某种规则将分区信息解析出来。这些规则可以有很多,内核里调用 register_mtd_parser()即可注册一个新的解析器。drivers/mtd/mtdpart.c中维护了一个链表 part_parsers,解析器按注册顺序添加到这个链表里。parse_mtd_partitions()中,如果未指定解析器的话,则默认只允许用 cmdlinepart, ofpart两种解析器。对于我们这里,实际上起作用的是 ofpart。

static struct mtd_part_parser ofpart_parser={.owner= THIS_MODULE,.parse_fn= parse_ofpart_partitions,.name="ofpart",};parse_ofpart_partitions()遍历 dts中 spi flash设备下的分区描述信息,取出其中的 reg, label, name, read-only, lock等信息以填充一个 struct mtd_partition结构体。上面 dts里描述了 4个分区,就有一个大小为 4的 struct mtd_partition数组,最后由 add_mtd_partitions()添加为各 mtd分区。分区的情况可以待系统启动后在/proc/mtd文件中查看到。# cat/proc/mtddev: size erasesize namemtd0: 00030000 00010000"u-boot"mtd1: 00010000 00010000"u-boot-env"mtd2: 00010000 00010000"factory"mtd3: 00fb0000 00010000"firmware"mtd4: 00ea9283 00010000"rootfs"mtd5: 00b30000 00010000"rootfs_data"根文件系统的解析上面/proc/mtd的内容中相比 dts中的描述多了两个分区 rootfs, rootfs_data。这两个分区是何时添加的呢?看看添加 mtd分区的函数:int add_mtd_partitions(struct mtd_info*master,const struct mtd_partition*parts,int nbparts)

{struct mtd_part*slave;uint64_t cur_offset= 0;int i;printk(KERN_NOTICE"Creating%d MTD partitions on\"%s\":\n", nbparts, master->name);for(i= 0; i< nbparts; i++){slave= allocate_partition(master, parts+ i, i, cur_offset);if(IS_ERR(slave))return PTR_ERR(slave);mutex_lock(&mtd_partitions_mutex);list_add(&slave->list,&mtd_partitions);mutex_unlock(&mtd_partitions_mutex);add_mtd_device(&slave->mtd);mtd_partition_split(master, slave);cur_offset= slave->offset+ slave->mtd.size;}return 0;}最后调用了 mtd_partition_split()。static void mtd_partition_split(struct mtd_info*master, struct mtd_part*part){static int rootfs_found= 0;if(rootfs_found)return;if(!strcmp(part->mtd.name,"rootfs")){rootfs_found= 1;if(config_enabled(CONFIG_MTD_ROOTFS_SPLIT))split_rootfs_data(master, part);}if(!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME)&&

config_enabled(CONFIG_MTD_SPLIT_FIRMWARE))split_firmware(master, part);arch_split_mtd_part(master, part->mtd.name, part->offset,part->mtd.size);}如果:1.rootfs还没有被找到2.当前分区名是"firmware"3.内核配置时开启了 CONFIG_MTD_SPLIT_FIRMWARE则调用 split_firmware()来解析。在该函数中做了以下几件事:1.找 type为 MTD_PARSER_TYPE_FIRMWARE的分区解析器来分析。2."uimage-fw"解析器读出 firmware分区的头部,成功找到一个 uImage。3.跃过 uImage,紧接着成功找到 squashfs的头信息,于是找到了格式为 squashfs的 rootfs。4.解析器在找到一个分区后,会调用 __mtd_add_partition()将此分区添加到系统中。5.__mtd_add_partition()最后又调用 mtd_partition_split(),因为此时 rootfs已经找到,所以会调用 split_rootfs_data()找 rootfs_data分区。6.rootfs为 squashfs分区,该格式的文件系统只读,且头信息里有标记分区大小。所以很容易就可以找到 rootfs_data的起始位置。

5.9

百度文库VIP限时优惠现在开通,立享6亿+VIP内容

立即获取

openwrtspiflash分区适配过程

openwrtspiflash分区适配过程

openwrt spi flash分区适配过程

这里基于 openwrt mt7620a平台来跟踪,主要是想理清 dts里的分区描述是如何一步步转化成内核分区行为。

先来看看 dts中关于分区的描述:

palmbus@10000000{

spi@b00{

status="okay";

m25p80@0{

第 1页

Linux SPI-NAND 驱动开发指南

Linux SPI-NAND驱动开发指南概述

1.1目的

本指南旨在详细介绍Sunxi SPINand mtd/ubi驱动,为驱动和应用开发者提供便利。

1.2适用范围

适用于所有sunxi平台的NAND MTD/UBI驱动开发。

1.3参与人员

包括NAND模块开发者和应用开发者在内的相关人员。

关键概念

MTD:Linux子系统中的内存技术设备,负责Flash驱动部分。

UBI:基于MTD的子系统,管理NAND特性,屏蔽底层细节。

坏块:由制造工艺和设备性质导致的不可用存储单元。

开发流程

3.1结构设计

NAND MTD/UBI驱动由5个核心组件构成,如图所示:

3.2源码位置

驱动代码位于Linux 5.4内核的mtd/awnand/spinand目录下。

关键数据定义

flash设备信息:包含型号、ID、芯片内部结构等详细参数。

chip操作接口:如读写、擦除、ecc处理和缓存管理等。

操作请求结构:定义了操作的目标页面和数据结构。

UBI ECC header:存储擦除计数器等信息。

UBI VID header:逻辑和物理块映射的详细描述。

接口说明

3.4.1 MTD层接口:包括 erase、read、read_oob、write、write_oob、检查坏块和标记坏块等。

3.4.2物理层接口:针对芯片级别的读写、擦除和坏块操作。

模块配置

4.1 U-Boot配置:涉及特定菜单项,如图所示。

4.2内核配置:涉及UBI、NAND和SPI相关配置,如SPI设备、DMA和SID设置。

4.3 env.cfg:在构建过程中,通过添加特定变量来定制驱动环境。

阅读剩余
THE END