问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

openwrt打开spiflash

发布网友 发布时间:2023-01-09 18:30

我来回答

1个回答

热心网友 时间:2023-10-24 03:23

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 页
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
中联重科ZE1250E挖掘机技术参数 全球黑卡是什么? 你们知道学日语哪个培训机构好吗?推荐推荐吧。 描写高情商的晚安短句(你只能靠自己,别无选择) 让你陷入沉思的深沉朋友圈文案 比较冷淡的伤感朋友圈 赛尔号泰达性格天真刷什么? 我抓了只满个体的泰达,性格温顺,请问应该刷什么学习力 “肯同雪月吊兰荪”的出处是哪里 ...高,怎么还亏损这么多钱,开通的财通证券,用的同花顺炒股软件... 怎么看股票中(安信)的均线 十个月阿拉斯加一天遛狗跑多少公里算合适,今天我开车跑的十多公里就累的不行了?我的是巨型的, 什么狗一天能跑1000里? 哈士奇一口气能跑几公里 8个月的阿拉斯加怎么训练 雪橇犬拉雪橇一天距离 奥特曼空想特摄怎么解锁赛文 奥特曼系列ol突破需要贵几 要怎样报名pmp 联想小新pro16怎么开启窗口小工具 联想平板打开梦幻西游没有悬浮按钮 写作文用什么样的稿纸 女人练深蹲的九大好*人练深蹲有什么好处为什么练深蹲对女人好 熟牛肝的保存方法有哪些 奔驰b级属于什么类型的车 借私人25000块钱两年后要还多少利息 奔驰B级中控图解 奔驰B级中控台功能介绍 不知为什么,我一个大男人也特别喜欢锦缎被子 手表日历如何调整 石英表怎么调日历 我想配一套家庭k歌的设备,20-30平空间,现在就只有一个笔记本电脑,相配功放、音响,不知道怎么搭配好? 梦见玉蛇 梦见玉蛇断了 又什么又什么的句子三年级 来电奇缘电视剧大结局 送给需要的你 梦见光着身体在街上走 梦见自己光身子在大街上 梦见光着身在大街上走 做梦梦见自己光全身在街上走预示着什么 一条微博最多可以传几个视频 电脑怎么登录智慧职教 智慧职教教师端怎么登录 荣耀xd21坏了 三年级下册课时笒为什么不用登天都峰而是用爬天都峰 荣耀xd27路由器电信版参数 橄榄油擦脸的正确步骤 橄榄油怎么擦脸 做西米露冷却后加了热水,奶就凝固了,有什么办法补救 命令与征服3_泰伯利亚战 1.09修改器 怎么用啊,应该放在哪,这么启动。怎么在游戏中按了键没作用? 命令与征服3凯恩之怒修改器如何用? 国网低压计量十芯线怎样区分 围棋的棋盘上的点是怎么规定的?