国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
從2.4 到2.6:Linux 內(nèi)核可裝載模塊機(jī)制的改變對設(shè)備驅(qū)動(dòng)的影響

從 2.4 到 2.6:Linux 內(nèi)核可裝載模塊機(jī)制的改變對設(shè)備驅(qū)動(dòng)的影響

周婷 , 軟件工程師

2006 年 2 月 09 日

從 2.4 到 2.6,Linux 內(nèi)核在可裝載模塊機(jī)制、設(shè)備模型、一些核心 API 等方面發(fā)生較大改變,設(shè)備驅(qū)動(dòng)開發(fā)人員面臨著將驅(qū)動(dòng)從 2.4 移植到 2.6 內(nèi)核,或是使驅(qū)動(dòng)同時(shí)支持2.4 與 2.6 內(nèi)核的任務(wù)。站在設(shè)備驅(qū)動(dòng)開發(fā)人員的角度,驅(qū)動(dòng)由一個(gè)或幾個(gè)外部可加載內(nèi)核模塊組成,本文針對 2.6 內(nèi)核里模塊機(jī)制的改變對編寫設(shè)備驅(qū)動(dòng)程序的影響,從內(nèi)核模塊的編譯、裝載時(shí)的版本檢查、初始化與退出、模塊使用計(jì)數(shù)、輸出內(nèi)核符號(hào)、命令行輸入?yún)?shù)、許可證聲明等方面比較了 2.4 與 2.6 內(nèi)核的區(qū)別;并總結(jié)了使設(shè)備驅(qū)動(dòng)同時(shí)支持 2.4 與 2.6 內(nèi)核的一系列模板。

1. 獲取內(nèi)核版本

當(dāng)設(shè)備驅(qū)動(dòng)需要同時(shí)支持不同版本內(nèi)核時(shí),在編譯階段,內(nèi)核模塊需要知道當(dāng)前使用的內(nèi)核源碼的版本,從而使用相應(yīng)的內(nèi)核 API。2.4 與 2.6 內(nèi)核下,源碼頭文件 linux/version.h 定義有:

LINUX_VERSION_CODE ― 內(nèi)核版本的二進(jìn)制表示,主、從、修訂版本號(hào)各對應(yīng)一個(gè)字節(jié);

KERNEL_VERSION(major, minor, release) - 由主、從、修訂版本號(hào)構(gòu)造二進(jìn)制版本號(hào)。

在同時(shí)支持2.4與2.6 內(nèi)核的設(shè)備驅(qū)動(dòng)程序中,經(jīng)??梢钥吹揭韵麓a段:


清單1:判斷內(nèi)核版本的代碼段。
                        #include <linux/version.h>                        #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)                        #define LINUX26                        #endif                        #ifdef LINUX26                        /*code in 2.6 kernel*/                        #else                        /*code in 2.4 kernel */                        #endif                        





2.內(nèi)核模塊機(jī)制的改變

2.1模塊編譯

從2.4到2.6,外部可裝載內(nèi)核模塊的編譯、連接過程以及Makefile的書寫都發(fā)生了改變。

2.4內(nèi)核中,模塊的編譯只需內(nèi)核源碼頭文件;需要在包含linux/modules.h之前定義MODULE;編譯、連接后生成的內(nèi)核模塊后綴為.o。

2.6內(nèi)核中,模塊的編譯需要配置過的內(nèi)核源碼;編譯、連接后生成的內(nèi)核模塊后綴為.ko;編譯過程首先會(huì)到內(nèi)核源碼目錄下,讀取頂層的Makefile文件,然后再返回模塊源碼所在目錄。


清單2:2.4 內(nèi)核模塊的Makefile模板
                        #Makefile2.4                        KVER=$(shell uname -r)                        KDIR=/lib/modules/$(KVER)/build                        OBJS=mymodule.o                        CFLAGS=-D__KERNEL__ -I$(KDIR)/include -DMODULE -D__KERNEL_SYSCALLS__ -DEXPORT_SYMTAB                        -O2 -fomit-frame-pointer  -Wall  -DMODVERSIONS -include $(KDIR)/include/linux/modversions.h                        all: $(OBJS)                        mymodule.o: file1.o file2.o                        ld -r -o $@ $^                        clean:                        rm -f *.o                        

在2.4 內(nèi)核下,內(nèi)核模塊的Makefile與普通用戶程序的Makefile在結(jié)構(gòu)和語法上都相同,但是必須在CFLAGS中定義-D__KERNEL__-DMODULE,指定內(nèi)核頭文件目錄-I$(KDIR)/include。 有一點(diǎn)需注意,之所以在CFLAGS中定義變量,而不是在模塊源碼文件中定義,一方面這些預(yù)定義變量可以被模塊中所有源碼文件可見,另一方面等價(jià)于將這些預(yù)定義變量定義在源碼文件的起始位置。在模塊編譯中,對于這些全局的預(yù)定義變量,一般在CFLAGS中定義。


清單3:2.6 內(nèi)核模塊的Makefile模板
                        # Makefile2.6                        ifneq ($(KERNELRELEASE),)                        #kbuild syntax. dependency relationshsip of files and target modules are listed here.                        mymodule-objs := file1.o file2.o                        obj-m := mymodule.o                        else                        PWD  := $(shell pwd)                        KVER ?= $(shell uname -r)                        KDIR := /lib/modules/$(KVER)/build                        all:                        $(MAKE) -C $(KDIR) M=$(PWD)                        clean:                        rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions                        endif                        

KERNELRELEASE是在內(nèi)核源碼的頂層Makefile中定義的一個(gè)變量,在第一次讀取執(zhí)行此Makefile時(shí),KERNELRELEASE沒有被定義, 所以make將讀取執(zhí)行else之后的內(nèi)容。如果make的目標(biāo)是clean,直接執(zhí)行clean操作,然后結(jié)束。當(dāng)make的目標(biāo)為all時(shí),-C $(KDIR) 指明跳轉(zhuǎn)到內(nèi)核源碼目錄下讀取那里的Makefile;M=$(PWD) 表明然后返回到當(dāng)前目錄繼續(xù)讀入、執(zhí)行當(dāng)前的Makefile。當(dāng)從內(nèi)核源碼目錄返回時(shí),KERNELRELEASE已被被定義,kbuild也被啟動(dòng)去解析kbuild語法的語句,make將繼續(xù)讀取else之前的內(nèi)容。else之前的內(nèi)容為kbuild語法的語句, 指明模塊源碼中各文件的依賴關(guān)系,以及要生成的目標(biāo)模塊名。mymodule-objs := file1.o file2.o表示mymoudule.o 由file1.o與file2.o 連接生成。obj-m := mymodule.o表示編譯連接后將生成mymodule.o模塊。

補(bǔ)充一點(diǎn),"$(MAKE) -C $(KDIR) M=$(PWD)"與"$(MAKE) -C $(KDIR) SUBDIRS =$(PWD)"的作用是等效的,后者是較老的使用方法。推薦使用M而不是SUBDIRS,前者更明確。

通過以上比較可以看到,從Makefile編寫來看,在2.6內(nèi)核下,內(nèi)核模塊編譯不必定義復(fù)雜的CFLAGS,而且模塊中各文件依賴關(guān)系的表示簡潔清晰。


清單4: 可同時(shí)在2.4 與 2.6 內(nèi)核下工作的Makefile
                        #Makefile for 2.4 & 2.6                        VERS26=$(findstring 2.6,$(shell uname -r))                        MAKEDIR?=$(shell pwd)                        ifeq ($(VERS26),2.6)                        include $(MAKEDIR)/Makefile2.6                        else                        include $(MAKEDIR)/Makefile2.4                        endif                        

2.2模塊裝載時(shí)的版本檢查

Linux內(nèi)核一直在更新、完善,在a版本內(nèi)核源碼下編譯的模塊在b版本內(nèi)核下通常不能運(yùn)行,所以必須有一種機(jī)制,限制在a版本內(nèi)核下編譯生成的模塊在b版本內(nèi)核下被加載。

2.4與2.6內(nèi)核在可裝載內(nèi)核模塊的版本檢查機(jī)制方面發(fā)生了根本性的改變,不過這些改變對設(shè)備驅(qū)動(dòng)開發(fā)人員而言基本是透明的。為了使模塊裝載時(shí)的版本檢查機(jī)制生效,2.4 內(nèi)核下,只需在CFLAGS中定義


                        -DMODVERSIONS -include $(KDIR)/include/linux/modversions.h;                        

2.6內(nèi)核下,開發(fā)人員無須采用任何操作。

不過,在此仍有必要闡明2.4與2.6內(nèi)核對可加載模塊的版本檢查機(jī)制。

2.4內(nèi)核下, 執(zhí)行`cat /proc/ksyms`可看到內(nèi)核符號(hào)在名字后還跟隨著一串校驗(yàn)字符串,此校驗(yàn)字符串與內(nèi)核版本有關(guān)。在內(nèi)核源碼頭文件linux/modules 目錄下存在許多*.ver文件,這些文件起著為內(nèi)核符號(hào)添加校驗(yàn)后綴的作用,如ksyms.ver 文件里有一行 #define printk _set_ver(printk)。linux/modversions.h 文件會(huì)包含全部的 ver文件 。所以當(dāng)模塊包含linux/modversions.h文件后,編譯時(shí),模塊里使用的內(nèi)核符號(hào)實(shí)質(zhì)是帶有校驗(yàn)后綴的內(nèi)核符號(hào)。在加載模塊時(shí),如果模塊中所使用內(nèi)核符號(hào)的校驗(yàn)字符串與當(dāng)前運(yùn)行內(nèi)核所導(dǎo)出的相應(yīng)的內(nèi)核符號(hào)的校驗(yàn)字符串不一致,即當(dāng)前內(nèi)核空間并不存在模塊所使用的內(nèi)核符號(hào),就會(huì)出現(xiàn)"Invalid module format "的錯(cuò)誤。

為內(nèi)核符號(hào)添加校驗(yàn)字符串來驗(yàn)證模塊的版本與內(nèi)核的版本是否匹配是繁雜和浪費(fèi)內(nèi)核空間的;而且隨著SMP(對稱多處理器)、PREEMPT(可搶占內(nèi)核)等機(jī)制在2.6內(nèi)核的引入和完善,模塊運(yùn)行時(shí)對內(nèi)核的依賴不僅取決于內(nèi)核版本,還取決于內(nèi)核的配置,此時(shí)內(nèi)核符號(hào)的校驗(yàn)碼是否一致不能成為判斷模塊可否被加載的充分條件。2.6 內(nèi)核下,在linux/vermagic.h中定義有VERMAGIC_STRING,VERMAGIC_STRING不僅包含內(nèi)核版本號(hào),還包含有內(nèi)核使用的gcc版本,SMP與PREEMPT等配置信息。模塊在編譯時(shí),我們可以看到屏幕上會(huì)顯示"MODPOST"。在此階段, VERMAGIC_STRING會(huì)添加到模塊的modinfo段。 在內(nèi)核源碼目錄下scripts\mod\modpost.c文件中可以看到模塊后續(xù)處理部分的代碼。模塊編譯生成后,通過`modinfo mymodule.ko`命令可以查看此模塊的vermagic等信息。2.6 內(nèi)核下的模塊裝載器里保存有內(nèi)核的版本信息,在裝載模塊時(shí),裝載器會(huì)比較所保存的內(nèi)核vermagic與此模塊的modinfo段里保存的vermagic信息是否一致,兩者一致時(shí),模塊才能被裝載。譬如Fedora core 4 與core 2 使用的都是2.6 版本內(nèi)核, 在Fedore Core 2下去加載Fedora Core4下編譯生成的hello.ko,會(huì)出現(xiàn)"invalid module format" 錯(cuò)誤。


                        #insmod hello.ko                        Invalid module format                        hello: version magic ‘2.6.11-1.1369_FC4 686 REGPARM 4KSTACKS gcc-4.0‘                        should be ‘2.6.5-1.358 686 REGPARM 4KSTACKS gcc-3.3‘                        

2.3模塊的初始化與退出

在2.6內(nèi)核中,內(nèi)核模塊必須調(diào)用宏module_init 與module_exit() 去注冊初始化與退出函數(shù)。在2.4 內(nèi)核中,如果初始化函數(shù)命名為init_module()、退出函數(shù)命名為cleanup_module(),可以不必使用module_init 與module_exit 宏。推薦使用module_init 與module_exit宏,使代碼在2.4與2.6內(nèi)核中都能工作。


清單5:適用于2.4與2.6內(nèi)核的模塊的初始化與退出模板
                        #include <linux/module.h>  /* Needed by all modules */                        #include <linux/init.h>    /* Needed for init&exit macros */                        static int mod_init_func(void)                        {                        /*code here*/                        return 0;                        }                        static void mod_exit_func(void)                        {                        /*code here*/                        }                        module_init(mod_init_func);                        module_exit(mod_exit_func);                        

需要注意的是初始化與退出函數(shù)必須在宏module_init和module_exit使用前定義,否則會(huì)出現(xiàn)編譯錯(cuò)誤。

2.4 模塊使用計(jì)數(shù)

模塊在被使用時(shí),是不允許被卸載的。2.4內(nèi)核中,模塊自身通過MOD_INC_USE_COUNT、MOD_DEC_USE_COUNT宏來管理自己被使用的計(jì)數(shù)。2.6內(nèi)核提供了更健壯、靈活的模塊計(jì)數(shù)管理接口try_module_get(&module)及module_put(&module)取代2.4中的模塊使用計(jì)數(shù)管理宏;模塊的使用計(jì)數(shù)不必由自身管理,而且在管理模塊使用計(jì)數(shù)時(shí)考慮到SMP與PREEMPT機(jī)制的影響。

int try_module_get(struct module *module):用于增加模塊使用計(jì)數(shù);若返回為0,表示調(diào)用失敗,希望使用的模塊沒有被加載或正在被卸載中。

void module_put(struct module *module):減少模塊使用計(jì)數(shù)。

try_module_get 與module_put的引入與使用與2.6內(nèi)核下的設(shè)備模型密切相關(guān)。模塊是用來管理硬件設(shè)備的,2.6 內(nèi)核為不同類型的設(shè)備定義了struct module *owner 域,用來指向管理此設(shè)備的模塊。如字符設(shè)備的定義:


                        struct cdev {                        struct kobject kobj;                        struct module *owner;                        struct file_operations *ops;                        struct list_head list;                        dev_t dev;                        unsigned int count;                        };                        

從設(shè)備使用的角度出發(fā),當(dāng)需要打開、開始使用某個(gè)設(shè)備時(shí),使用try_module_get(dev->owner)去增加管理此設(shè)備的owner模塊的使用計(jì)數(shù);當(dāng)關(guān)閉、不再使用此設(shè)備時(shí),使用module_put(dev->owner)減少對管理此設(shè)備的owner模塊的使用計(jì)數(shù)。這樣,當(dāng)設(shè)備在使用時(shí),管理此設(shè)備的模塊就不能被卸載;只有設(shè)備不再使用時(shí)模塊才能被卸載。

2.6內(nèi)核下,對于為具體設(shè)備寫驅(qū)動(dòng)的開發(fā)人員而言,基本無需使用try_module_get與module_put,因?yàn)榇藭r(shí)開發(fā)人員所寫的驅(qū)動(dòng)通常為支持某具體設(shè)備的owner模塊,對此設(shè)備owner模塊的計(jì)數(shù)管理由內(nèi)核里更底層的代碼如總線驅(qū)動(dòng)或是此類設(shè)備共用的核心模塊來實(shí)現(xiàn),從而簡化了設(shè)備驅(qū)動(dòng)開發(fā)。





2.5 模塊輸出的內(nèi)核符號(hào)

2.4 內(nèi)核下,缺省情況時(shí)模塊中的非靜態(tài)全局變量及函數(shù)在模塊加載后會(huì)輸出到內(nèi)核空間。

2.6 內(nèi)核下,缺省情況時(shí)模塊中的非靜態(tài)全局變量及函數(shù)在模塊加載后不會(huì)輸出到內(nèi)核空間,需要顯式調(diào)用宏EXPORT_SYMBOL才能輸出。所以在2.6 內(nèi)核的模塊下,EXPORT_NO_SYMBOLS宏的調(diào)用沒有意義,是空操作。在同時(shí)支持2.4與2.6內(nèi)核的設(shè)備驅(qū)動(dòng)中,可以通過以下代碼段來輸出模塊的內(nèi)核符號(hào)


清單6: 同時(shí)支持2.4與2.6的輸出內(nèi)核符號(hào)代碼段
                        #include <linux/module.h>                        #ifndef LINUX26                        EXPORT_NO_SYMBOLS;                        #endif                        EXPORT_SYMBOL(var);                        EXPORT_SYMBOL(func);                        

需要注意的是如需在2.4內(nèi)核下使用 EXPORT_SYMBOL,必須在 CFLAGS中定義 EXPORT_SYMTAB,否則編譯將會(huì)失敗。

從良好的代碼風(fēng)格角度出發(fā),模塊中不需要輸出到內(nèi)核空間且不需為模塊中其它文件所用的全局變量及函數(shù)最好顯式申明為static類型,需要輸出的內(nèi)核符號(hào)以模塊名為前綴。

模塊加載后,2.4內(nèi)核下可通過 /proc/ksyms、 2.6 內(nèi)核下可通過/proc/kallsyms查看模塊輸出的內(nèi)核符號(hào)





2.6 模塊的命令行輸入?yún)?shù)

在裝載內(nèi)核模塊時(shí),用戶可以向模塊傳遞一些參數(shù),如`modprobe modname var=value`,否則,var將使用模塊內(nèi)定義的缺省值。

2.4內(nèi)核下,linux/module.h中定義有宏MODULE_PARM(var,type) 用于向模塊傳遞命令行參數(shù)。var為接受參數(shù)值的變量名,type為采取如下格式的字符串[min[-max]]{b,h,i,l,s}。min及max用于表示當(dāng)參數(shù)為數(shù)組類型時(shí),允許輸入的數(shù)組元素的個(gè)數(shù)范圍;b:byte;h:short;i:int;l:long;s:string。

2.6內(nèi)核下,宏MODULE_PARM(var,type)不再被支持。在頭文件linux/moduleparam.h里定義了如下宏:


                        module_param(name, type, perm)                        module_param_array(name, type, nump, perm)                        

type 類型可以是byte、short,、ushort、 int、 uint、long、ulong、charp, bool or invbool, 不再采用2.4內(nèi)核中的字符串形式,而且在模塊編譯時(shí)會(huì)將此處申明的type與變量定義的類型進(jìn)行比較,判斷是否一致。

perm表示此參數(shù)在sysfs文件系統(tǒng)中所對應(yīng)的文件節(jié)點(diǎn)的屬性。2.6內(nèi)核使用sysfs文件系統(tǒng),這是一個(gè)建立在內(nèi)存中比proc更強(qiáng)大的文件系統(tǒng)。sysfs文件系統(tǒng)可以動(dòng)態(tài)、實(shí)時(shí),有組織層次地反應(yīng)當(dāng)前系統(tǒng)中的硬件、驅(qū)動(dòng)等狀態(tài)。當(dāng)perm為0時(shí),表示此參數(shù)不存在sysfs文件系統(tǒng)下對應(yīng)的文件節(jié)點(diǎn)。 模塊被加載后,在/sys/module/ 目錄下將出現(xiàn)以此模塊名命名的目錄。如果此模塊存在perm不為0的命令行參數(shù),在此模塊的目錄下將出現(xiàn)parameters目錄,包含一系列以參數(shù)名命名的文件節(jié)點(diǎn),這些文件的權(quán)限值等于perm,文件的內(nèi)容為參數(shù)的值。

nump 為保存輸入的數(shù)組元素個(gè)數(shù)的變量的指針。當(dāng)不需保存實(shí)際輸入的數(shù)組元素個(gè)數(shù)時(shí),可以設(shè)為NULL。從2.6.0至2.6.10 版本,須將變量名賦給nump;從2.6.10 版本開始,須將變量的引用賦給nump,這更易為開發(fā)人員理解。加載模塊時(shí),使用逗號(hào)分隔輸入的數(shù)組元素。


清單7: 適用于2.4與2.6內(nèi)核的模塊輸入?yún)?shù)模板
                        #include <linux/module.h>                        #ifdef LINUX26                        #include <linux/moduleparam.h>                        #endif                        int debug = 0;                        char *mode = "800x600";                        int tuner[4] = {1, 1, 1, 1};                        #ifdef LINUX26                        int tuner_c = 1;                        #endif                        #ifdef LINUX26                        MODULE_PARM(debug, "i");                        MODULE_PARM(mode, "s");                        MODULE_PARM(tuner,"1-4i");                        #else                        module_param(debug, int, 0644);                        module_param(mode, charp, 0644);                        #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)                        module_param_array(tuner, int, &tuner_c, 0644);                        #else                        module_param_array(tuner, int, tuner_c, 0644);                        #endif                        #endif                        

模塊編譯生成后,加載模塊時(shí)可以輸入:`modprobe my_module mode=1024x768 debug=1 tuner=22,33`。

在linux/moduleparam.h還定義有:


                        module_param_array_named(name, array, type, nump, perm)                        module_param_call(name, set, get, arg, perm)                        module_param_named(name, value, type, perm)                        

讀者可以參閱linux/moduleparam.h查看這些宏的詳細(xì)描述,有一點(diǎn)需注意,在2.6內(nèi)核里,module_param這一系列宏使用的都是小寫名字。

2.7 模塊的許可證聲明

從2.4.10版本內(nèi)核開始,模塊必須通過MODULE_LICENSE宏聲明此模塊的許可證,否則在加載此模塊時(shí),會(huì)收到內(nèi)核被污染"kernel tainted" 的警告。從linux/module.h文件中可以看到,被內(nèi)核接受的有意義的許可證有 "GPL","GPL v2","GPL and additional rights","Dual BSD/GPL","Dual MPL/GPL","Proprietary"。

在同時(shí)支持2.4與2.6內(nèi)核的設(shè)備驅(qū)動(dòng)中,模塊可按如下方式聲明自己的許可證。


清單8: 適用于2.4與2.6內(nèi)核的模塊許可證聲明模板
                        #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)                        MODULE_LICENSE("GPL");                        #endif                        

2.8 小結(jié)

此外,2.6內(nèi)核里還有一些模塊機(jī)制的改變,不常為驅(qū)動(dòng)開發(fā)人員用到。如加載內(nèi)核模塊的接口request_module在2.4 下為request_module(const char * module_name);在2.6內(nèi)核下為request_module(const char *fmt, ...)。在2.6 內(nèi)核下,驅(qū)動(dòng)開發(fā)人員可以通過調(diào)用


                        request_module("msp3400");                        request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev));                        

這種更靈活的方式加載其它內(nèi)核模塊。

2.6內(nèi)核在linux/module.h中還提供了MODULE_ALIAS(alias)宏,模塊可以通過調(diào)用此宏為自己定義一或若干個(gè)別稱。而在2.4內(nèi)核下,用戶只能在/etc/modules.conf中為模塊定義別稱。

通過以上比較可以看到,從2.4到2.6內(nèi)核,可裝載模塊管理機(jī)制的改變使設(shè)備驅(qū)動(dòng)的開發(fā)變得更加簡潔、靈活、健壯。





參考資料





關(guān)于作者

作者:周婷,軟件工程師,S3 Graphics 上海研發(fā)中心,工作方向: 視頻解碼。email: moting9@hotmail.com

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
linux內(nèi)核驅(qū)動(dòng)模塊的編譯及加載
Linux內(nèi)核模塊的編譯基礎(chǔ)知識(shí)
開發(fā)一個(gè)簡單的內(nèi)核程序
linux驅(qū)動(dòng)入門(轉(zhuǎn))
linux
教你寫第一個(gè)Linux設(shè)備驅(qū)動(dòng)程序
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服