mmc子系统框架

10 篇文章 11 订阅
订阅专栏
3 篇文章 2 订阅
订阅专栏

Linux kernel把mmc,sd以及sdio三者的驱动代码整合在一起,俗称mmc子系统。源码位于drivers/mmc下。其下有三个子目录,分别是:card、core、host,其中,card用于构建一个块设备作为上层与mmc子系统沟通的桥梁;core抽象了mmc,sd,sdio三者的通用操作;host则是各类平台上的host驱动代码,包括如TI Omap的omap_hsmmc,三星的s3cmci等。具体的SOC,会根据实际情况再次封装(比如rockchip采用新思designwave的IP),就重新封装为struct dw_mci。DesignWare是SoC/ASIC设计者最钟爱的设计IP库和验证IP库。它包括一个独立于工艺的、经验证的、可综合的虚拟微架构的元件集合,包括逻辑、算术、存储和专用元件系列,超过140个模块。

一、Mmc子系统涉及总线(SD为例)

1、Host驱动相应的driver和device挂载在Linux内核内置的虚拟抽象总线platform_bus_type。设备树指定compatible属性与源码匹配后调用对应的probe函数来初始化对应平台的host硬件。

2、Card驱动相应的driver和device挂载在mmc自己创建的虚拟总线mmc_bus_type下。该总线的结构体定义在driver/mmc/core/bus.c;因为是统一的协议,mmc_driver在内核已经写好并已注册driver/mmc/card/block.c-->mmc_blk_init()-->mmc_register_driver(&mmc_driver); SD卡中extended CSD寄存器中存储分区信息,上电检测到了SD卡,或者上电之后的热拔插操作,触发mmc_rescan查找检测到SD卡插入后,会通过读取该寄存器的值,获取mmc card的分区信息等,然后注册对应的mmc_card device,因mmc driver仅有一个,因此针对mmc bus而言其match函数直接返回1,表示匹配成功(因为是统一的协议),而不需要像spi/i2c总线的match接口那样对设备和驱动进行匹配检测;随后调用mmc_driver的probe函数(拔出卡则反之操作)。

3、mmc_driver的probe函数针对该mmc card的每一个分区,均执行如下操作:
①、为每一个分区,创建对应的通用磁盘设备gendisk;
②、设置gendisk的fops为mmc_bdops;
③、为每一个通用磁盘设备,均创建request_queue及其处理方法;
④、为该通用磁盘设备创建mmc block块i/o请求机制;
⑤、将该分区的通用磁盘设备注册至块设备i/o,以便应用层可通过块设备访问该mmc card 分区。

设备-总线-驱动模型:

在分析MMC子系统的设备-总线-驱动模型时,可以借助已经分析的i2c驱动模型、spi驱动模型的实现,来学习mmc子系统的驱动模型,通过与i2c驱动模型、spi驱动模型的对比,也可以加深我们对mmc子系统驱动模型的理解(从已知去学习未知,可提供我们的学习效率)。我们知道针对复杂的设备,则需要借助控制器进行通信,而针对i2c、spi、mmc而言,均需要对应的控制器实现与该类设备的通信。而针对这三类控制器,其模块都进行了抽象,其中i2c控制器抽象为i2c adapter、spi控制器抽象为spi master,而针对mmc控制器,则抽象为mmc host;而针对这三种类型设备的抽象,i2c设备抽象为i2c client、spi设备抽象为spi device、mmc device抽象为mmc card。 

下面分析下这三类驱动模型的异同:

1、均为控制器创建了对应的class,用于将对应的控制器设备链接至对应的class上

2、针对i2c adapter、spi master这两类而言,其驱动模型中均创建了对应的链表,将所有注册的控制器设备链接在一起,而mmc子系统并没有为mmc host创建类似的链表;

3、I2c/spi设备不属于热插拔设备,因此在具体系统的板级文件或者设备树中,需要针对系统中存在的i2c/spi设备定义注册信息,从而在LINUX系统初始化时完成i2c/spi设备的注册;而针对mmc子系统其属于热插拔的,因此在系统初始化时不需要单独进行设备的注册;

4、针对mmc子系统而言,针对mmc card的注册,mmc子系统提供了rescan接口,而该接口作为延迟工作队列的回调函数。针对mmc card而发起rescan扫描的时机如下:

①在mmc host添加的时候,执行一次mmc card的扫描操作

②热拔插过程执行扫描

这里大概分三个情况来描述热插拔识别流程:

①SOC带卡检测引脚,即mmc控制器部分带专门的中断寄存器位(MCI中断)

②SOC不带卡检测引脚,即用普通中断引脚做检测(即sdmmc_cd引脚)

③没有专门的寄存器,也没有用cd的gpio中断,采用轮询POLL

 二、分析mmc子系统框架函数调用流程(以SD卡为例)

关于SD卡的HOST最初始设备树节点在rk3399.dtsi 
sdmmc: dwmmc@fe320000 {
        compatible = "rockchip,rk3399-dw-mshc",
                     "rockchip,rk3288-dw-mshc";
					............................
					}

Host驱动相应的driver和device挂载在Linux内核内置的虚拟抽象总线platform_bus_type。我们设备树host device与driver匹配后调用对应的probe函数来初始化对应平台的host硬件。 

drivers\mmc\host\dw_mmc-rockchip.c
dw_mci_rockchip_probe(struct platform_device *pdev)
	--> dw_mci_pltfm_register(pdev, drv_data); //解析设备树信息,用来构造一个dw_mci *host;
		--> dw_mci_probe(dw_mci *host); //将上面构造好的dw_mci *host结构体传参进来;
			--> setup_timer(&host->cmd11_timer,dw_mci_cmd11_timer, (unsigned long)host); //设置一些定时器,定时发送一些命令
			--> host->dma_ops = host->pdata->dma_ops;
			--> ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, host->irq_flags, "dw-mci", host);
			//这个dw_mci_interrupt中断函数会被注册两次,一次是emmc(irq=25),一次是sd卡(irq=26),所以源码虽然只注册了一次,但是实际上注册了两次,用的都是同一个中断处理函数
			//这个是mci寄存器的中断,我们的这款soc可以根据这个寄存器来判断发送,接收,SD卡热拔插的行为,都会触发这个中断,在这个中断处理函数里面再细分是什么操作触发的中断,进行处理,比如热拔插:
			--> dw_mci_init_slot(dw_mci *host, i); // 定义了mmc_host *mmc;,用我们封装了一层的dw_mci *host去填充注册他
				--> mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
					--> INIT_DELAYED_WORK(&host->detect, mmc_rescan); //初始化工作队列,里面有扫描SD卡的函数
				--> mmc->ops = &dw_mci_ops; //mmc_host_ops类型的变量,用于定义本mmc_host的操作接口(包括与mmc card通信的接口request、卡检测相关的接口等)
				--> mmc_add_host(mmc);
					--> mmc_start_host(mmc_host *host);
						--> mmc_schedule_delayed_work(&host->detect, delay); //上电添加mmc_host的时候,先主动执行一次mmc_rescan函数
			--> dw_mci_enable_cd(host); //cd = card detect ≠ sdmmc_cd 引脚中断,主要看函数内容,像这款soc就是在里面开启mci寄存器的SD卡热拔插中断
				--> temp = mci_readl(host, INTMASK); temp  |= SDMMC_INT_CD; mci_writel(host, INTMASK, temp); //开启mci寄存器的SD卡热拔插中断

假设热拔插SD卡引起了中断: 

dw_mci_interrupt()
	if (pending & SDMMC_INT_CD)
		dw_mci_handle_cd(dw_mci *host);
			--> mmc_detect_change(slot->mmc,msecs_to_jiffies(host->pdata->detect_delay_ms));
				--> _mmc_detect_change(host, delay, true);
					--> mmc_schedule_delayed_work(&host->detect, delay); //开启工作队列
						--> mmc_rescan() //最终会调用此函数

重点看看mmc_rescan检测SD卡热拔插的函数,我们在设备树中的SD卡定义了 supports-sd 所以:
drivers\mmc\core\host.c 
mmc_of_parse
	if (of_property_read_bool(np, "supports-sd"))
		host->restrict_caps |= RESTRICT_CARD_TYPE_SD; 

mmc_rescan()
	if (host->bus_ops && !host->bus_dead && !(host->caps & MMC_CAP_NONREMOVABLE)) //上电第一次调用这个函数时候,还没有设置host->bus_ops,所以会执行后面的语句来设置host->bus_ops
		host->bus_ops->detect(host);
	--> mmc_rescan_try_freq(host, max(freqs[i], host->f_min)) //以各种频率给host发,选择最合适的频率
			if ((host->restrict_caps & RESTRICT_CARD_TYPE_SD) && !mmc_attach_sd(host)) return 0; 所以就会调用mmc_attach_sd
		--> mmc_attach_sd(host)
			--> mmc_attach_bus(host, &mmc_sd_ops);
				--> host->bus_ops = ops; //这里的ops就是上面的mmc_ops参数
			--> mmc_sd_init_card(host, rocr, NULL);
				--> card = mmc_alloc_card(host, &sd_type);
			--> mmc_add_card(host->card);
				--> device_add(&card->dev);
					--> bus_add_device(dev); //Add the device to its bus's list of devices, 会给mmc_bus注册一个devices,会和系统自动注册的mmc_driver匹配,调用它的probe函数
                        ......
                        --> mmc_driver->probe
	                        --> mmc_blk_probe() //如上分析的,会读取SD卡的寄存器获取分区信息,根据分区信息注册block等。

放一张图中好看些:

三、mmc子系统的数据结构 (以emmc的为例)

mmc_host数据结构:

Mmc card: 

①host完成mmc_card与mmc_host的绑定;
②dev完成将该mmc_card与系统中的设备、总线、驱动的关联(即完成与系统设备驱动总线的关联与绑定操作);
③卡类型与卡状态记录
④卡相关的寄存器信息记录(主要从mmc card中读取),包括cid、csd、scr、ssr等内容
⑤Mmc card的分区信息,主要完成块设备的创建(由mmc driver实现)若为sdio设备,则有cccr、cis等(关于sdio的部分,请参考sdio协议相关的文档)

 mmc_ios:

该结构体主要定义mmc总线相关的参数,主要包括时钟频率、电源、总线模式、电源状态、总线带宽、支持的信号电压值等等这些参数的设置可通过mmc_host_ops->set_ios实现。

mmc_host_ops:

该数据结构定义了mmc_host的操作方法

mmc_bus_ops:

该接口主要是针对mmc card的sleep/awake的操作,因mmc card也需要进行sleep/awake等接口,这些接口类似于设备驱动的电源管理(suspend/resume)相关的接口。该结构体中的成员,不需要我们进行实现,mmc子系统已经完成,mmc子系统根据mmc各协议版本针对sleep/awake的支持情况,实现对应的操作。

 参考这位博主:LINUX MMC子系统分析之一 概述_jerry_chg的博客-CSDN博客_linux mmc子系统

Linux内核笔记(驱动篇)之 【深入浅出MMC子系统
哆哆jarvis的博客
01-07 1804
本文基于内核版本4.1.15分析,随着内核版本升级,部分数据结构会发生变化,但是整体流程没有发生变化。先附上读写eMMC大体经过,目的在于了解过程,具体细节不作过多分析。
【LED子系统深度剖析】二、LED子系统框架分析
Donge's Blog
03-29 1956
Linux驱动开发系列文章| LED子系统:该篇详细讲解了Linux内核中LED子系统框架,目录结构及核心文件✍
mmc子系统
qq_31057589的博客
05-05 571
MMC(Multi-Media Card)子系统Linux内核中的一个模块,主要用于管理SD卡和eMMC等可移动存储设备。块层(Block layer):负责处理SD卡等存储设备的块层操作,如读写,分区,格式化等。在块层中,SD卡和eMMC设备以MMC块设备的形式被表示。SDIO子系统:负责管理SDIO卡设备,SDIO卡可以提供不同类型的接口,如WiFi,蓝牙等。
EMMC5.1协议讲解(emmc总线)
最新发布
SUNtao99的博客
09-13 1173
软件可不看,内容对硬件上电的说明
Linux内核MMC框架
weixin_43982460的博客
03-03 2180
1.mmc的概念 1.MMC MultiMedia Card,多媒体存储卡, 但后续泛指一个接口协定(一种卡式),能符合这接口的内存器都可称作mmc储存体,工作电压:高电压为2.7~3.6 V,低电压为1.65~1.95 V,可选. 2.MMC总线 mmc总线是和I2C总线、SPI总线类似的一种总线结构。 卡与主控制器间串行传送,工作时钟频率范围为0~200 MHz,mmc总线上最多可识别64 K个mmc设备,在总线上不超过10个卡时,可运行到最高频率。 3.mmc设备 使用mmc接口规范(MCI, Mul
Linux MMC子系统
win9
09-07 1884
MMC:MultiMedia Card(多媒体卡) MMC子系统从最开始的MMC,发展到包括如下的Card: MMC卡:具有MMC和SPI两种工作模式。 1.MMC是默认工作模式,具有MMC的全部特性。 2.SPI是其一个子集,用于低速系统。 SD卡:Secure DigtalMemory Card 兼容MMC标准,比MMC多一个引脚保护功能,速度快4倍。
mmc 子系统研究
raoxu1154492168的博客
04-06 529
目录结构,文件介绍 mmc 子系统目录为 主要包含3个部分的内容 card core host 3个目录的内容,作用分别为: card层:将sd卡实现为块设备 core层:实现不同的协议和规范,为host层的驱动提供了接口函数 host层:手动实现具体的mmc和sd设备 下面将通过代码具体介绍,这几层是如何实现上述功能的 块设备驱动介绍 基本概念 块设备与字符设备的区别: 字符设备按照字符流的方式被有序访问,如串口和键盘就都属于字符设备,如果一个硬件设备是以字符流的方式访问的话,那就应该将它归于字符设备
浅析Linux内核mmc子系统-sdio
m0_73494896的博客
09-17 1838
上面这段代码注册了内核在start_kernel()中会调用的函数,如map_io提供将各IP寄存器地址到内核虚拟地址的转换,init_early()函数由start_kernel()--->setup_arch()--->mdesc->init_early()调用,其余的init_irq,handle_irq()等会在start_kernel()中分别调用。到2.2.4为止,host的device和driver都已经创建,匹配后调用host对应的probe函数:omap_hsmmc_probe()。
MMC子系统之SDIO卡驱动
艾伦
08-17 640
SDIO
⑳tiny4412 Linux驱动开发之MMC子系统驱动程序
qq_23922117的博客
10-24 862
本次我们来说一下MMC子系统的控制器的开发部分,这部分也是和硬件平台相关的,在说这个之前,我们先来了解一下相关硬件的基础知识和概念. MMC MMC全称MultiMedia Card,由西门子公司和SanDisk公司1997年推出的多媒体记忆卡标准。MMC卡尺寸为32mm x24mm x 1.4mm,它将存贮单元和控制器一同做到了卡上,智能的控制器使得MMC保证兼容性和灵活性。MMC卡具有MMC...
U-Boot 之十 详解 MMC 子系统、命令、初始化流程
技术干货
01-08 1400
Linux kernel 一样,U-Boot 也是使用 MMC subsystem 统一管理 eMMC、SD 等存储设备,这些设备统称为 MMC 设备。U-Boot 提供了一系列的 MMC 命令来方便用户查看及管理 MMC 设备。
MMC子系统介绍
liaoye's blog
05-27 2944
MMC子系统介绍 MMC代码分布 MMC子系统代码主要在drivers/mmc目录下,共有三个目录:          Card:存放闪存卡(块设备)的相关驱动,如MMC/SD卡设备驱动,SDIOUART;          Host:针对不同主机端的SDHC、MMC控制器的驱动,这部分需要由驱动工程师来完成;          Core:整个MMC的核心层,这部分完成不同协议和规范的实
关于linux mmc/sd驱动程序架构
Linux Android Web
11-02 371
http://blog.csdn.net/zangcf/article/details/8809028 关于linux mmc/sd驱动程序架构 今天花了时间简单看了mmc/sd部门内容和代码,我觉得形式上,这个部分和i2c非常相似 系统也是分成core层,host层(对应i2c的adapter),设备层 如果这样讲,那么core层主要功能应该是提供host注册,总线注册,设备注册
MMC子系统】 一、MMC/SD/SDIO介绍
Donge's Blog
12-29 2115
该节学习的MMC子系统,也称为块设备驱动,正如其名,与字符驱动相比,MMC子系统以块为单位进行操作。同时,由于MMC Card、SD Card、SDIO Card等设备协议基本大同小异,所以在中使用MMC子系统来统一管理!上面我们了解到,使用统一的子系统模型来管理MMC、SD、SDIO等设备,那么为什么要这样设计呢?答案当然是:三者协议有一定的共通性。多媒体卡设备,从本质上看,
LINUX MMC子系统分析之二 MMC子系统驱动模型分析(包括总线、设备、驱动)
lickylin的专栏
03-07 2309
本模块主要介绍MMC子系统与设备-总线-驱动模型的关联,并介绍该MMC子系统是如何借助LINUX内核的设备-总线-驱动模型实现自己的驱动模型的。针对MMC子系统而言,主要使用了系统中的两个模型:设备-总线-驱动模型、块设备驱动模型。 设备-总线-驱动模型 在分析MMC子系统的设备-总线-驱动模型时,我们可以借助之前已经分析的i2c驱动模型、spi驱动模型的实现,来学习...
Linux MMC驱动架构浅析
li的博客
03-03 3340
Linux MMC驱动架构浅析 MMC驱动模型 Linux内核设计了MMC子系统,用于管理MMC/SD等设备,MMC/SD存储设备是一种典型的块设备。MMC子系统框架结构如下图所示。 块设备(MMC_BLOCK) 块设备的相关驱动,即实现块设备的驱动程序,负责驱动MMC core抽象出来的虚拟的card设备,并对接内核其它的framework(例如块设备、TTY、wifi)等实现具体的功能。如MMC/SD卡设备驱动按照 linux块设备驱动程序的框架实现一个MMC/SD卡的块设备驱动,在 block.c
MMC 卡驱动分析
yyp872的专栏
07-16 1325
最近花时间研究了一下 MMC 卡驱动程序,开始在网上找了很多关于 MMC 卡驱动的分析文章,但大都是在描述各个层,这对于初学者来讲帮助并不大,所以我就打算把自己的理解写下来,希望对大家有用。个人觉得理解 LINUX 内核当中 MMC/SD 卡驱动程序构架是学习 MMC 卡驱动程序的重点,只有理解了它的基本框架流程才能真正理解一个块设备驱动程序的写法,同时才能真正理解 LINUX 设备驱动模型是如
MMC子系统分析
IT利刃出鞘的博客
09-30 2725
目录 子系统概述 相关节点 card路径代码分析 读写流程 控制器代码分析 控制器入口 mmc_rescan mmc_rescan_try_freq mmc_blk_probe mmc_attach_sd流程 打印分区信息流程 设备树速度模式 reboot调用到的流程 子系统概述 Linux kernel把mmc,sd以及sdio三者的驱动代码整合在一起,称m...
写文章

热门文章

  • rockchip的adc按键驱动 3940
  • 字符驱动、输入子系统、platform总线、LCD驱动、USB驱动 3141
  • 第19课:nand flash驱动 2597
  • IIC驱动 2514
  • mmc子系统框架 2310

分类专栏

  • 驱动学习笔记 10篇
  • rockchip驱动框架 3篇
  • 内存管理
  • 设备树
  • I/O子系统
  • 文件系统
  • 进程管理

最新评论

  • mmc子系统框架

    内核分析笔记: 一个sd卡,一个emmc,都调用同一份源码,实际注册了两个中断。

  • mmc子系统框架

    WCN code life: 你好,这个dw_mci_interrupt中断函数会被注册两次,一次是emmc(irq=25),一次是sd卡(irq=26),所以源码虽然只注册了一次,但是实际上注册了两次,用的都是同一个中断处理函数 请问下 这个地方实际注册2次是什么意思,这个函数会触发2次? 我遇到了core 去 send cmd11,但是没走到这个中断函数的情况,有什么建议吗

  • 驱动程序基石:异步通知

    内核分析笔记: 韦东山老师的,我自己做个笔记表情包

  • 驱动程序基石:异步通知

    杜白尼: 看了好几篇异步通信的文章,您写的非常全,而且逻辑清晰又直观。向您学习。

  • 字符驱动、输入子系统、platform总线、LCD驱动、USB驱动

    WuXinnnnnn: 你真棒

大家在看

  • MFC扩展库BCGControlBar Pro v35.1新版亮点 - 改进编辑控件性能
  • 线性可分支持向量机的原理推导 9-27拉格朗日乘子和不等式约束关系 公式解析
  • 闲鱼API接口有哪些常用的API呢?
  • 《商品详情的“快问快答”:API界的极速赛车》
  • WebGl 实现图片平移、缩放和旋转 45

最新文章

  • 驱动程序基石:异步通知
  • 驱动程序基石:POLL机制
  • 块设备驱动框架的总结(flash为例)
2022年6篇
2021年6篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内核分析笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家公园小品玻璃钢雕塑设计及定制工艺玻璃钢雕塑定做重庆人物玻璃钢雕塑批发广东透明玻璃钢雕塑摆件玻璃钢喷水雕塑小品水晶玻璃钢人物雕塑厂家电话自贡玻璃钢卡通雕塑西宁玻璃钢雕塑专业厂家青浦区玻璃钢雕塑哪家好常州玻璃钢雕塑制作设计商场中庭美陈装饰现代创意水景雕塑玻璃钢七夕情人节商场端架美陈福建大型商场创意商业美陈策划公园标识玻璃钢彩绘雕塑设计吉首玻璃钢雕塑报价商场美陈摆件厂家商场美陈展示流程浙江户外商场美陈价格美陈玻璃钢雕塑制作广安玻璃钢广场雕塑定制商丘不锈钢牛玻璃钢彩绘雕塑阳江玻璃钢雕塑厂家北京市玻璃钢智能雕塑深圳常见商场美陈订购河南室外玻璃钢仿铜雕塑小品商场广告美陈大型玻璃钢雕塑的好评语商场礼盒美陈德州市雕塑玻璃钢雕塑厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化