国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

1. 驅(qū)動(dòng)開(kāi)發(fā)--基礎(chǔ)知識(shí)

這篇具有很好參考價(jià)值的文章主要介紹了1. 驅(qū)動(dòng)開(kāi)發(fā)--基礎(chǔ)知識(shí)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

該文內(nèi)容源于朱有鵬老師的課程,按照自己的理解進(jìn)行匯總,方便查閱。如有侵權(quán),請(qǐng)告知?jiǎng)h除。

1 驅(qū)動(dòng)的概念

  1. 驅(qū)動(dòng)一詞的字面意思
  2. 物理上的驅(qū)動(dòng)
  3. 硬件中的驅(qū)動(dòng)
  4. linux內(nèi)核驅(qū)動(dòng)
    ??軟件層面的驅(qū)動(dòng)廣義上就是指:這一段代碼操作硬件去動(dòng),所以這一段代碼就叫硬件的驅(qū)動(dòng)程序。(本質(zhì)上是電力提供了動(dòng)力,而驅(qū)動(dòng)程序提供了操作邏輯方法)。
    ??狹義上驅(qū)動(dòng)程序就是專指操作系統(tǒng)中用來(lái)操控硬件的邏輯方法部分代碼。

2 linux體系架構(gòu)

驅(qū)動(dòng)開(kāi)發(fā),linux--驅(qū)動(dòng)開(kāi)發(fā),驅(qū)動(dòng)開(kāi)發(fā),linux,驅(qū)動(dòng),Makefile,linux驅(qū)動(dòng)體系架構(gòu)
(1)分層思想
(2)驅(qū)動(dòng)的上面是系統(tǒng)調(diào)用API
(3)驅(qū)動(dòng)的下面是硬件
(4)驅(qū)動(dòng)自己本身也是分層的

3 模塊化設(shè)計(jì)

3.1 微內(nèi)核和宏內(nèi)核

(1)宏內(nèi)核(又稱為單內(nèi)核):將內(nèi)核從整體上作為一個(gè)大過(guò)程實(shí)現(xiàn),并同時(shí)運(yùn)行在一個(gè)單獨(dú)的地址空間。所有的內(nèi)核服務(wù)都在一個(gè)地址空間運(yùn)行,相互之間直接調(diào)用函數(shù),簡(jiǎn)單高效。(緊耦合)
(2)微內(nèi)核:功能被劃分成獨(dú)立的過(guò)程,過(guò)程間通過(guò)IPC進(jìn)行通信。模塊化程度高,一個(gè)服務(wù)失效不會(huì)影響另外一個(gè)服務(wù)。典型如windows。(松耦合)
(3)linux:本質(zhì)上是宏內(nèi)核,但是又吸收了微內(nèi)核的模塊化特性,體現(xiàn)在以下2個(gè)層面:

靜態(tài)模塊化  :   在編譯時(shí)實(shí)現(xiàn)可裁剪,特征是想要功能裁剪改變必須重新編譯。
動(dòng)態(tài)模塊化  :   zImage可以不重新編譯燒錄,甚至可以不關(guān)機(jī)重啟就實(shí)現(xiàn)模塊的安裝和卸載。

4 linux設(shè)備驅(qū)動(dòng)分類

4.1 驅(qū)動(dòng)分類

(1)分3類:字符設(shè)備驅(qū)動(dòng)、塊設(shè)備驅(qū)動(dòng)、網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)
(2)分類原則:設(shè)備本身讀寫操作的特征差異

4.2 三類驅(qū)動(dòng)程序詳細(xì)對(duì)比分析

(1)字符設(shè)備,準(zhǔn)確的說(shuō)應(yīng)該叫“字節(jié)設(shè)備”,軟件操作設(shè)備時(shí)是以字節(jié)為單位進(jìn)行的。典型的如LCD、串口、LED、蜂鳴器、觸摸屏······
(2)塊設(shè)備,塊設(shè)備是相對(duì)于字符設(shè)備定義的,塊設(shè)備被軟件操作時(shí)是以塊(多個(gè)字節(jié)構(gòu)成的一個(gè)單位)為單位的。設(shè)備的塊大小是設(shè)備本身設(shè)計(jì)時(shí)定義好的,軟件是不能去更改的,不同設(shè)備的塊大小可以不一樣。常見(jiàn)的塊設(shè)備都是存儲(chǔ)類設(shè)備,如:硬盤、NandFlash、iNand、SD····
(3)網(wǎng)絡(luò)設(shè)備,網(wǎng)絡(luò)設(shè)備是專為網(wǎng)卡設(shè)計(jì)的驅(qū)動(dòng)模型,linux中網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)主要目的是為了支持API中socket相關(guān)的那些函數(shù)工作。

4.3 為什么字符設(shè)備驅(qū)動(dòng)最重要

(1)常見(jiàn)大量設(shè)備都屬于字符設(shè)備
驅(qū)動(dòng)開(kāi)發(fā),linux--驅(qū)動(dòng)開(kāi)發(fā),驅(qū)動(dòng)開(kāi)發(fā),linux,驅(qū)動(dòng),Makefile,linux驅(qū)動(dòng)體系架構(gòu)
??linux一切皆文件,則linux下的字符設(shè)備驅(qū)動(dòng)也是以文件的形式呈現(xiàn)。既然是文件,那無(wú)外乎文件的一系列操作,其實(shí)我們之所以可以對(duì)文件進(jìn)行一系列操作最為本質(zhì)的原因就是文件系統(tǒng)的實(shí)現(xiàn)。在linux內(nèi)核中(中間抽象一層,這就好比阿里當(dāng)年想把快遞拿下,搞出了菜鳥(niǎo)驛站,管你什么快遞,都放到我這里,我來(lái)為用戶服務(wù)!),在各種類型的文件系統(tǒng)上在加一層,抽象出了VFS,也正是VFS的實(shí)現(xiàn)對(duì)于我們來(lái)說(shuō)管你底層是什么類型的文件系統(tǒng)對(duì)上完全沒(méi)有影響。

驅(qū)動(dòng)開(kāi)發(fā),linux--驅(qū)動(dòng)開(kāi)發(fā),驅(qū)動(dòng)開(kāi)發(fā),linux,驅(qū)動(dòng),Makefile,linux驅(qū)動(dòng)體系架構(gòu)
從架構(gòu)圖上可以清晰的發(fā)現(xiàn),字符設(shè)備驅(qū)動(dòng)的架構(gòu)是如此簡(jiǎn)單,當(dāng)應(yīng)用層操作的時(shí)候通過(guò)系統(tǒng)調(diào)用轉(zhuǎn)到內(nèi)核層,內(nèi)核中實(shí)現(xiàn)文件操作的時(shí)候就是驅(qū)動(dòng)代碼實(shí)現(xiàn),并沒(méi)有調(diào)用任何文件系統(tǒng), 相當(dāng)于我們直接和vfs對(duì)接就ok!

(2)舉例說(shuō)明非標(biāo)準(zhǔn)類型字符設(shè)備驅(qū)動(dòng)
基于ZYNQ平臺(tái)開(kāi)發(fā)的字符驅(qū)動(dòng),屬于非標(biāo)準(zhǔn)類型字符設(shè)備驅(qū)動(dòng)。

5 驅(qū)動(dòng)程序的安全性要求

5.1 驅(qū)動(dòng)是內(nèi)核的一部分

  1. 驅(qū)動(dòng)已經(jīng)成為內(nèi)核中最龐大的組成部分
  2. 內(nèi)核會(huì)直接以函數(shù)調(diào)用的方式調(diào)用驅(qū)動(dòng)代碼
  3. 驅(qū)動(dòng)的動(dòng)態(tài)安裝和卸載都會(huì)“更改”內(nèi)核

5.2 驅(qū)動(dòng)對(duì)內(nèi)核的影響

  1. 驅(qū)動(dòng)程序崩潰甚至?xí)?dǎo)致內(nèi)核崩潰
  2. 驅(qū)動(dòng)的效率會(huì)影響內(nèi)核的整體效率
  3. 驅(qū)動(dòng)的漏洞會(huì)造成內(nèi)核安全漏洞

5.3 常見(jiàn)驅(qū)動(dòng)安全性問(wèn)題

  1. 未初始化指針
  2. 惡意用戶程序
  3. 緩沖區(qū)溢出
  4. 競(jìng)爭(zhēng)狀態(tài)

6 驅(qū)動(dòng)應(yīng)該這么學(xué)

6.1 先學(xué)好C語(yǔ)言

6.2 掌握相關(guān)預(yù)備知識(shí)

  1. 硬件操作方面
  2. 應(yīng)用層API

6.3 驅(qū)動(dòng)學(xué)習(xí)階段

  1. 注重實(shí)踐,一步一步寫驅(qū)動(dòng)
  2. 框架思維,多考慮整體和上下層
  3. 先通過(guò)簡(jiǎn)單設(shè)備學(xué)linux驅(qū)動(dòng)框架
  4. 學(xué)會(huì)總結(jié)、記錄,這會(huì)有助于理解

6.4 驅(qū)動(dòng)開(kāi)發(fā)的準(zhǔn)備工作

(1)正常運(yùn)行l(wèi)inux系統(tǒng)的開(kāi)發(fā)板。要求開(kāi)發(fā)板中的linux的zImage必須是自己編譯的,不能是別人編譯的。
(2)內(nèi)核源碼樹(shù),其實(shí)就是一個(gè)經(jīng)過(guò)了配置編譯之后的內(nèi)核源碼。
(3)nfs掛載的rootfs,主機(jī)ubuntu中必須搭建一個(gè)nfs服務(wù)器。

6.4.1 驅(qū)動(dòng)開(kāi)發(fā)的步驟

  1. 驅(qū)動(dòng)源碼編寫、Makefile編寫、編譯
  2. insmod裝載模塊、測(cè)試、rmmod卸載模塊

6.4.2 實(shí)踐

1)copy原來(lái)提供的x210kernel.tar.bz2,找一個(gè)干凈的目錄(我的目錄/x210_driver/kernel),解壓之,并且配置編譯。編譯完成后得到了:1. 內(nèi)核源碼樹(shù)。2.編譯ok的zImage

2)fastboot將第1步中得到的zImage燒錄到開(kāi)發(fā)板中去啟動(dòng)(或者將zImage丟到tftp的共享目錄,uboot啟動(dòng)時(shí)tftp下載啟動(dòng)),將來(lái)驅(qū)動(dòng)編譯好后,就可以在這個(gè)內(nèi)核中去測(cè)試。因?yàn)檫@個(gè)zImage和內(nèi)核源碼樹(shù)是一伙的,所以驅(qū)動(dòng)安裝時(shí)版本校驗(yàn)不會(huì)出錯(cuò)。

6.5 最簡(jiǎn)單的模塊源碼分析

最簡(jiǎn)單的驅(qū)動(dòng)模塊源碼:

#include <linux/module.h>		// module_init  module_exit
#include <linux/init.h>			// __init   __exit

// 模塊安裝函數(shù)
static int __init chrdev_init(void)
{	
	printk(KERN_INFO "chrdev_init helloworld init\n");
	return 0;
}

// 模塊卸載函數(shù)
static void __exit chrdev_exit(void)
{
	printk(KERN_INFO "chrdev_exit helloworld exit\n");
}

module_init(chrdev_init);   //執(zhí)行這個(gè)宏就相當(dāng)于進(jìn)到模塊安裝函數(shù)里面執(zhí)行函數(shù)
module_exit(chrdev_exit);   //執(zhí)行這個(gè)宏就相當(dāng)于進(jìn)到模塊卸載函數(shù)里面執(zhí)行函數(shù)

// MODULE_xxx這種宏作用是用來(lái)添加模塊描述信息
MODULE_LICENSE("GPL");				// 描述模塊的許可證
MODULE_AUTHOR("aston");				// 描述模塊的作者
MODULE_DESCRIPTION("module test");	// 描述模塊的介紹信息
MODULE_ALIAS("alias xxx");			// 描述模塊的別名信息

6.5.1 常用的模塊操作命令

模塊命令功能
lsmod (list module, 將模塊列表顯示) 功能是打印出當(dāng)前內(nèi)核中已經(jīng)安裝過(guò)的模塊列表
insmod(install module,安裝模塊) 功能是向當(dāng)前內(nèi)核中去安裝一個(gè)模塊,用法是insmod xxx.ko

modinfo(module information,模塊信息) 功能是打印出一個(gè)內(nèi)核模塊的自帶信息,用法是modinfo xxx.ko
rmmod(remove module,卸載模塊) 功能是從當(dāng)前內(nèi)核中卸載一個(gè)已經(jīng)安裝了的模塊,用法是rmmod xxx(注意卸載模塊時(shí)只需要輸入模塊名即可,不能加.ko后綴)

modprobe、depmod 暫時(shí)用不到,后面再說(shuō)

6.5.2 模塊的安裝

(1) 先lsmod再insmod看安裝前后系統(tǒng)內(nèi)模塊記錄。實(shí)踐測(cè)試標(biāo)明內(nèi)核會(huì)將最新安裝的模塊放在lsmod顯示的最前面。
(2) insmod與module_init宏。模塊源代碼中用module_init宏聲明了一個(gè)函數(shù)(在我們這個(gè)例子里是chrdev_init函數(shù)),作用就是指定chrdev_init這個(gè)函數(shù)和insmod命令綁定起來(lái),也就是說(shuō)當(dāng)我們insmod module_test.ko時(shí),insmod命令內(nèi)部實(shí)際執(zhí)行的操作就是幫我們調(diào)用chrdev_init函數(shù)。照此分析,那insmod時(shí)就應(yīng)該能看到chrdev_init中使用printk打印出來(lái)的一個(gè)chrdev_init字符串,但是實(shí)際沒(méi)看到。原因是ubuntu中攔截了,要怎么才能看到呢?在ubuntu中使用dmesg命令就可以看到了。

(3) 模塊安裝時(shí)insmod內(nèi)部除了調(diào)用module_init宏所聲明的函數(shù)外,實(shí)際還做了一些別的事(譬如lsmod能看到多了一個(gè)模塊也是insmod在內(nèi)部做了記錄),但是我們就不用管了。

6.5.3 模塊的版本信息

  1. 使用modinfo查看模塊的版本信息
  2. 內(nèi)核zImage中也有一個(gè)確定的版本信息
  3. insmod時(shí)模塊的vermagic必須和內(nèi)核的相同,否則不能安裝,報(bào)錯(cuò)信息為:insmod: ERROR: could not insert module module_test.ko: Invalid module format
  4. 模塊的版本信息是為了保證模塊和內(nèi)核的兼容性,是一種安全措施
  5. 如何保證模塊的vermagic和內(nèi)核的vermagic一致?編譯模塊的內(nèi)核源碼樹(shù)就是編譯正在運(yùn)行的這個(gè)內(nèi)核的那個(gè)內(nèi)核源碼樹(shù)即可。說(shuō)白了就是模塊和內(nèi)核要同出一門。

6.5.4 模塊卸載

  1. module_exit和rmmod的對(duì)應(yīng)關(guān)系
  2. lsmod查看rmmod前后系統(tǒng)的模塊記錄變化

6.5.5 模塊中常用宏

宏名 作用
MODULE_LICENSE(“GPL”) 描述模塊的許可證
MODULE_AUTHOR(“aston”) 描述模塊的作者
MODULE_DESCRIPTION(“module test”) 描述模塊的介紹信息
MODULE_ALIAS(“alias xxx”) 描述模塊的別名信息

注:模塊的許可證,一般聲明為GPL許可證,而且最好不要少,否則可能會(huì)出現(xiàn)莫名其妙的錯(cuò)誤(譬如一些明顯存在的函數(shù)提升找不到)。

6.5.6 函數(shù)修飾符

  1. __init,本質(zhì)上是個(gè)宏定義,在內(nèi)核源代碼中就有#define __init xxxx。這個(gè)__init的作用就是將被他修飾的函數(shù)放入.init.text段中去(本來(lái)默認(rèn)情況下函數(shù)是被放入.text段中)。整個(gè)內(nèi)核中的所有的這類函數(shù)都會(huì)被鏈接器鏈接放入.init.text段中,所以所有的內(nèi)核模塊的__init修飾的函數(shù)其實(shí)是被統(tǒng)一放在一起的。內(nèi)核啟動(dòng)時(shí)統(tǒng)一會(huì)加載.init.text段中的這些模塊安裝函數(shù),加載完后就會(huì)把這個(gè)段給釋放掉以節(jié)省內(nèi)存。2)
  2. __exit原理也一樣。

6.5.7 printk函數(shù)詳解

printk是內(nèi)核態(tài)信息打印函數(shù),功能和比標(biāo)準(zhǔn)C庫(kù)的printf類似。
函數(shù)原型:int printk(const char *fmt, …)

消息打印級(jí)別:fmt----消息級(jí)別:不同級(jí)別使用不同字符串表示,數(shù)字越小,級(jí)別越高

#define KERN_EMERG “<0>” 用于緊急消息, 常常是那些崩潰前的消息.

#define KERN_ALERT “<1>” 需要立刻動(dòng)作的情形.

#define KERN_CRIT “<2>” 嚴(yán)重情況, 常常與嚴(yán)重的硬件或者軟件失效有關(guān).

#define KERN_ERR “<3>” 用來(lái)報(bào)告錯(cuò)誤情況; 設(shè)備驅(qū)動(dòng)常常使用 KERN_ERR 來(lái)報(bào)告硬件故障.

#define KERN_WARNING “<4>” 有問(wèn)題的情況的警告, 這些情況自己不會(huì)引起系統(tǒng)的嚴(yán)重問(wèn)題.

#define KERN_NOTICE “<5>” 正常情況, 但是仍然值得注意. 在這個(gè)級(jí)別一些安全相關(guān)的情況會(huì)報(bào)告.

#define KERN_INFO “<6>” 信息型消息. 在這個(gè)級(jí)別, 很多驅(qū)動(dòng)在啟動(dòng)時(shí)打印它們發(fā)現(xiàn)的硬件的信息.

#define KERN_DEBUG “<7>” 用作調(diào)試消息.

(1)printk在內(nèi)核源碼中用來(lái)打印信息的函數(shù),用法和printf非常相似。
(2)printk和printf最大的差別:printf是C庫(kù)函數(shù),是在應(yīng)用層編程中使用的,不能在linux內(nèi)核源代碼中使用;printk是linux內(nèi)核源代碼中自己封裝出來(lái)的一個(gè)打印函數(shù),是內(nèi)核源碼中的一個(gè)普通函數(shù),只能在內(nèi)核源碼范圍內(nèi)使用,不能在應(yīng)用編程中使用。

(3)printk相比printf來(lái)說(shuō)還多了個(gè):打印級(jí)別的設(shè)置。printk的打印級(jí)別是用來(lái)控制printk打印的這條信息是否在終端上顯示的。應(yīng)用程序中的調(diào)試信息要么全部打開(kāi)要么全部關(guān)閉,一般用條件編譯來(lái)實(shí)現(xiàn)(DEBUG宏),但是在內(nèi)核中,因?yàn)閮?nèi)核非常龐大,打印信息非常多,有時(shí)候整體調(diào)試內(nèi)核時(shí)打印信息要么太多找不到想要的要么一個(gè)沒(méi)有沒(méi)法調(diào)試。所以才有了打印級(jí)別這個(gè)概念。

(4)操作系統(tǒng)的命令行中也有一個(gè)打印信息級(jí)別屬性,值為0-7。當(dāng)前操作系統(tǒng)中執(zhí)行printk的時(shí)候會(huì)去對(duì)比printk中的打印級(jí)別和我的命令行中設(shè)置的打印級(jí)別,小于我的命令行設(shè)置級(jí)別的信息會(huì)被放行打印出來(lái),大于的就被攔截的。
可以用cat /proc/sys/kernel/printk查看打印級(jí)別;
可以用echo 4 /proc/sys/kernel/printk來(lái)設(shè)置打印級(jí)別為4
譬如我的ubuntu中的打印級(jí)別默認(rèn)是4,那么printk中設(shè)置的級(jí)別比4小的就能打印出來(lái),比4大的就不能打印出來(lái)。

(5)ubuntu中這個(gè)printk的打印級(jí)別控制沒(méi)法實(shí)踐,ubuntu中不管你把級(jí)別怎么設(shè)置都不能直接打印出來(lái),必須dmesg命令去查看。

6.5.8 關(guān)于驅(qū)動(dòng)模塊中的頭文件

驅(qū)動(dòng)源代碼中包含的頭文件和原來(lái)應(yīng)用編程程序中包含的頭文件不是一回事。應(yīng)用編程中包含的頭文件是應(yīng)用層的頭文件,是應(yīng)用程序的編譯器帶來(lái)的(譬如gcc的頭文件路徑在 /usr/include下,這些東西是和操作系統(tǒng)無(wú)關(guān)的)。驅(qū)動(dòng)源碼屬于內(nèi)核源碼的一部分,驅(qū)動(dòng)源碼中的頭文件其實(shí)就是內(nèi)核源代碼目錄下的include目錄下的頭文件。所以包含頭文件時(shí)要像#include <linux/module.h> ,#include <linux/init.h> 一樣找到相應(yīng)路徑的頭文件再包含。

6.5.9 驅(qū)動(dòng)編譯的Makefile分析

makefile源碼

#ubuntu的內(nèi)核源碼樹(shù),如果要編譯在ubuntu中安裝的模塊就打開(kāi)這2個(gè)
#KERN_VER = $(shell uname -r)
#KERN_DIR = /lib/modules/$(KERN_VER)/build	

#開(kāi)發(fā)板的linux內(nèi)核的源碼樹(shù)目錄
KERN_DIR = /root/driver/kernel

obj-m	+= module_test.o

all:
	make -C $(KERN_DIR) M=`pwd` modules 

cp:
	cp *.ko /root/porting_x210/rootfs/rootfs/driver_test

.PHONY: clean	
clean:
	make -C $(KERN_DIR) M=`pwd` modules clean

(1)KERN_DIR,變量的值就是用來(lái)編譯這個(gè)模塊的內(nèi)核源碼樹(shù)的目錄,分為在Ubuntu中和開(kāi)發(fā)板中兩種
(2)obj-m += module_test.o,表示我們要將module_test.c文件編譯成一個(gè)模塊
(3)make -C $(KERN_DIR) M=pwd modules 這個(gè)命令用來(lái)實(shí)際編譯模塊,工作原理就是:利用make -C進(jìn)入到我們指定的內(nèi)核源碼樹(shù)目錄下,然后在源碼目錄樹(shù)下借用內(nèi)核源碼中定義的模塊編譯規(guī)則去編譯這個(gè)模塊,編譯完成后把生成的文件還拷貝到當(dāng)前目錄下,完成編譯。
(4)make clean ,用來(lái)清除編譯痕跡

總結(jié):模塊的makefile非常簡(jiǎn)單,本身并不能完成模塊的編譯,而是通過(guò)make -C進(jìn)入到內(nèi)核源碼樹(shù)下,借用內(nèi)核源碼的體系來(lái)完成模塊的編譯鏈接的。這個(gè)Makefile本身是非常模式化的,3和4部分是永遠(yuǎn)不用動(dòng)的,只有1和2需要?jiǎng)?。?nèi)核源碼樹(shù)的目錄,必須根據(jù)自己的編譯環(huán)境確定的。

參考資料

Makefile

注:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-702841.html

  1. module_param(參考文末鏈接) // 即使文件已經(jīng)定義參數(shù)值,參數(shù)傳遞會(huì)覆蓋已經(jīng)定義的。
  2. 模塊化設(shè)計(jì),自己寫好的代碼按功能單獨(dú)封裝在一個(gè)KO里面,EXPORT_SYMBOL之后就將函數(shù)放到了全局符號(hào)表(一個(gè)鏈?zhǔn)浇Y(jié)構(gòu)),內(nèi)核可以找到相應(yīng)的函數(shù)。其他模塊可以調(diào)用它實(shí)現(xiàn)代碼的共用。有點(diǎn)類似于動(dòng)態(tài)庫(kù)。

到了這里,關(guān)于1. 驅(qū)動(dòng)開(kāi)發(fā)--基礎(chǔ)知識(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包