設(shè)備管理結(jié)構(gòu)及驅(qū)動程序編寫實(shí)例_第1頁
設(shè)備管理結(jié)構(gòu)及驅(qū)動程序編寫實(shí)例_第2頁
設(shè)備管理結(jié)構(gòu)及驅(qū)動程序編寫實(shí)例_第3頁
設(shè)備管理結(jié)構(gòu)及驅(qū)動程序編寫實(shí)例_第4頁
設(shè)備管理結(jié)構(gòu)及驅(qū)動程序編寫實(shí)例_第5頁
已閱讀5頁,還剩56頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第10章 設(shè)備管理第一頁,共六十二頁。第10章 主要內(nèi)容

本章主要介紹了設(shè)備管理方面的有關(guān)知識:◆系統(tǒng)管理設(shè)備的方式。◆驅(qū)動程序運(yùn)作過程。◆驅(qū)動程序的具體實(shí)例。第二頁,共六十二頁。第10章 目錄

10.1

設(shè)備管理結(jié)構(gòu)

10.2

驅(qū)動程序

10.3

驅(qū)動程序編寫實(shí)例第三頁,共六十二頁。第10章 目錄

10.1

設(shè)備管理結(jié)構(gòu)

10.2

驅(qū)動程序

10.3

驅(qū)動程序編寫實(shí)例第四頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):

設(shè)備管理即輸入輸出子系統(tǒng),分為上下兩部分:1.上層的,與設(shè)備無關(guān)的,這部分根據(jù)輸入輸出請求,通過特定的設(shè)備驅(qū)動程序接口,來與設(shè)備進(jìn)行通信。2.下層的,與設(shè)備有關(guān)的,常稱為設(shè)備驅(qū)動程序,它直接與相應(yīng)設(shè)備打交道,并且向上層提供一組訪問接口。概述第五頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):

設(shè)備管理的目標(biāo)是對所有的外接設(shè)備進(jìn)行良好的讀、寫、控制等操作。

待解決問題:

怎樣將任意的一個設(shè)備的所有操作進(jìn)行歸納,設(shè)計出統(tǒng)一的接口。內(nèi)核常常使用設(shè)備類型、主設(shè)備號和次設(shè)備號來標(biāo)識一個具體的設(shè)備。概述第六頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):概述Linux中的設(shè)備管理應(yīng)用了設(shè)備文件這個概念來統(tǒng)一設(shè)備的訪問接口。

簡單的說,系統(tǒng)試圖使它對所有各類設(shè)備的輸入、輸出看起來就好像對普通文件的輸入、輸出一樣。第七頁,共六十二頁。

如圖10-1所示,應(yīng)用程序通過Linux的系統(tǒng)調(diào)用與內(nèi)核通信。第八頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):概述

由于Linux中將設(shè)備當(dāng)作文件來處理,所以對設(shè)備進(jìn)行操作的系統(tǒng)調(diào)用和對文件操作的類似,主要包括open()、read()、write()、ioctl()、close()等。應(yīng)用程序發(fā)出系統(tǒng)調(diào)用指令以后,會從用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài),通過內(nèi)核將open()這樣的系統(tǒng)調(diào)用轉(zhuǎn)換成對物理設(shè)備的操作。第九頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):

字符設(shè)備以字節(jié)為單位進(jìn)行數(shù)據(jù)處理。字符設(shè)備通常只允許按順序訪問,一般不使用緩存技術(shù)。如鼠標(biāo),聲卡等。

塊設(shè)備以塊為單位進(jìn)行處理,塊的大小通常為0.5KB到32KB等。字符設(shè)備與塊設(shè)備第十頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):字符設(shè)備與塊設(shè)備

大多數(shù)塊設(shè)備允許隨機(jī)訪問,而且常常采用緩存技術(shù)。塊設(shè)備有硬盤、光盤驅(qū)動器等。可以查看文件/proc/devices獲得。這里主要討論字符設(shè)備,有興趣的讀者可參考其它書籍中有關(guān)塊設(shè)備的內(nèi)容。

第十一頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):

設(shè)備管理中,除了設(shè)備類型(字符設(shè)備或塊設(shè)備)以外,內(nèi)核還需要一對稱做主、次設(shè)備號的參數(shù),才能唯一表示設(shè)備。主設(shè)備號和次設(shè)備號第十二頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):主設(shè)備號和次設(shè)備號

主設(shè)備號(majornumber)相同的設(shè)備使用相同的驅(qū)動程序,而次設(shè)備號(minornumber)用來區(qū)分具體設(shè)備的實(shí)例。

例如:第一IDE接口上的所有磁盤及其分區(qū)共用同一主設(shè)備號3,而次設(shè)備號則為0,1,2,3…。第十三頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):

Linux習(xí)慣上將設(shè)備文件放在目錄/dev或其子目錄之下。設(shè)備文件命名(通常由兩部分組成)規(guī)則為:第一部分通常較短,可能只有2或3個字母組成,用來表示設(shè)備大類。

例如:普通硬盤如IDE接口的為“hd”,軟盤為“fd”。Linux設(shè)備命名習(xí)慣第十四頁,共六十二頁。10.1設(shè)備管理結(jié)構(gòu):Linux設(shè)備命名習(xí)慣

第二部分通常為數(shù)字或字母用來區(qū)別設(shè)備實(shí)例。例如:

/dev/hda、/dev/hdb、/dev/hdc表示第一、二、三塊硬盤;而dev/hda1、/dev/hda2、/dev/hda3則表示第一硬盤的第一、二、三分區(qū)。第十五頁,共六十二頁。第10章 目錄

10.1

設(shè)備管理結(jié)構(gòu)

10.2

驅(qū)動程序

10.3

驅(qū)動程序編寫實(shí)例第十六頁,共六十二頁。10.2驅(qū)動程序:

在Linux操作系統(tǒng)中驅(qū)動程序是操作系統(tǒng)內(nèi)核與硬件設(shè)備之間的橋梁,它屏蔽了硬件的細(xì)節(jié)(如總線協(xié)議、DMA操作等),在應(yīng)用程序看來硬件設(shè)備只是一個特殊的文件。驅(qū)動程序基本功能第十七頁,共六十二頁。10.2驅(qū)動程序:驅(qū)動程序基本功能1.對設(shè)備初始化和釋放。如對音頻設(shè)備而言包括向內(nèi)核注冊設(shè)備,設(shè)置音頻的輸入輸出參數(shù)(如采樣頻率、采樣寬度等)、分配音頻設(shè)備使用的內(nèi)核內(nèi)存等工作。

2.對設(shè)備進(jìn)行管理。包括實(shí)時參數(shù)設(shè)置以及提供對設(shè)備的操作接口。驅(qū)動程序的基本功能為:第十八頁,共六十二頁。10.2驅(qū)動程序:驅(qū)動程序基本功能

3.讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)并回送應(yīng)用程序請求的數(shù)據(jù)。這需要在用戶空間、內(nèi)核空間、總線及外設(shè)之間傳輸數(shù)據(jù)。

4.檢測和處理設(shè)備出現(xiàn)的錯誤。第十九頁,共六十二頁。結(jié)合大家比較熟悉的鍵盤來了解其運(yùn)作過程:第二十頁,共六十二頁。10.2驅(qū)動程序:驅(qū)動程序的運(yùn)作過程

當(dāng)一個程序讀/dev/tty文件(此為鍵盤)時,就會執(zhí)行系統(tǒng)調(diào)用sys_read()(在fs/read_write.c中),該系統(tǒng)調(diào)用在判別出所讀文件是一個字符設(shè)備文件時,即會調(diào)用rw_char()函數(shù)(在fs/char_dev.c中),該函數(shù)則會根據(jù)所讀設(shè)備的設(shè)備類型,主、次設(shè)備號等參數(shù),由字符設(shè)備讀寫函數(shù)表(設(shè)備開關(guān)表)調(diào)用rw_tty(),最終調(diào)用到這里的終端讀操作函數(shù)tty_read()

第二十一頁,共六十二頁。10.2驅(qū)動程序:驅(qū)動程序的運(yùn)作過程

當(dāng)用戶在鍵盤上鍵入了一個字符時,會引起鍵盤中斷響應(yīng),此時鍵盤中斷處理程序就會從鍵盤控制器讀入對應(yīng)的鍵盤掃描碼,然后根據(jù)使用的鍵盤掃描碼映射表譯成相應(yīng)字符,放入tty讀隊列read_q中。第二十二頁,共六十二頁。10.2驅(qū)動程序:驅(qū)動程序的運(yùn)作過程

然后調(diào)用中斷處理程序的do_tty_interrupt()函數(shù),它又直接調(diào)用行規(guī)則函數(shù)copy_to_cooked()對該字符進(jìn)行過濾處理,并放入tty輔助隊列secondary中,供上述tty_read()讀取。第二十三頁,共六十二頁。10.2驅(qū)動程序:驅(qū)動程序的運(yùn)作過程

同時把該字符放入tty寫隊列write_q中,并調(diào)用寫控制臺函數(shù)con_write()。 此時如果該終端的回顯(echo)屬性是設(shè)置的,則該字符會顯示到屏幕上(注:do_tty_interrupt()和copy_to_cooked()函數(shù)在tty_io.c中實(shí)現(xiàn))。第二十四頁,共六十二頁。10.2驅(qū)動程序:open():打開設(shè)備,并初始化設(shè)備準(zhǔn)備進(jìn)行操作。可以為NULL,這樣每次打開設(shè)備總會成功,而且不通知設(shè)備驅(qū)動程序。

read():從設(shè)備中讀數(shù)據(jù),需要提供字符串指針。

write():向字符設(shè)備寫數(shù)據(jù),需要提供所寫內(nèi)容指針。

ioctl():控制設(shè)備,例如控制光盤的彈出等。需要提供符合設(shè)備預(yù)先定義的命令字。常用接口介紹第二十五頁,共六十二頁。10.2驅(qū)動程序:常用接口介紹llseek():重新定位讀、寫位置,需要提供偏移量參數(shù)。

flush():清除內(nèi)容。

release():關(guān)閉設(shè)備,并釋放資源等。

mmap():將設(shè)備內(nèi)存映射到進(jìn)程地址空間。通常只有塊設(shè)備驅(qū)動程序使用。第二十六頁,共六十二頁。10.2驅(qū)動程序:

struct {structmodule*owner; loff_t(*llseek)(structfile*,loff_t,int); ssize_t(*read)(structfile*,char*,size_t,loff_t*); ssize_t(*write)(structfile*,constchar *,size_t,loff_t*); int(*readdir)(structfile*,void*,filldir_t);常用函數(shù)原型1.設(shè)備操作函數(shù)原形第二十七頁,共六十二頁。

unsignedint(*poll)(structfile*,struct poll_table_struct*); int(*ioctl)(structinode*,structfile*,unsigned int,unsignedlong); int(mmap)(structfile*,structvm_area_struct*); int(*open)(structinode*,structfile*); int(*flush)(structfile*); int(*release)(structinode*,structfile*);第二十八頁,共六十二頁。10.2驅(qū)動程序:常用函數(shù)原型

int(*fsync)(structdentry*,int datasync); int(*fasync)(int,structfile*,int); int(*lock)(structfile*,intstruct*); ssize_t(*readv)(structfile*,conststructiovec *,unsignedlong,loff_t*); ssize_t(*writev)(structfile*,conststructiovec *,unsignedlong,loff_t*); }第二十九頁,共六十二頁。10.2驅(qū)動程序:常用函數(shù)原型 intregister_chrdev(unsignedintmajor,constchar*name,struct*fops) { if(major==0) { write_lock(&chrdevs_lock);2.向系統(tǒng)注冊的函數(shù)原形第三十頁,共六十二頁。10.2驅(qū)動程序:常用函數(shù)原型

for(major=MAX_CHRDEV-1;major>0;major--) { if(chrdevs[major].fops==NULL) { chrdevs[major].name=name; chrdevs[major].fops=fops; write_unlock(&chrdevs_lock); returnmajor; } }第三十一頁,共六十二頁。10.2驅(qū)動程序:常用函數(shù)原型

write_unlock(&chrdevs_lock); return-EBUSY; } if(major>MAX_CHRDEV) return-EINVAL; write_lock(&chrdevs_lock);第三十二頁,共六十二頁。10.2驅(qū)動程序:常用函數(shù)原型

if(chrdevs[major].fops&&chrdevs[major].fops!=fops) { write_unlock(&chrdevs_lock); return-EBUSY; } chrdevs[major].name=name; chrdevs[major].fops=fops; write_unlock(&chrdevs_lock); return0; }第三十三頁,共六十二頁。第10章 目錄

10.1

設(shè)備管理結(jié)構(gòu)

10.2驅(qū)動程序

10.3

驅(qū)動程序編寫實(shí)例第三十四頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例

為了更清楚地講述Linux中設(shè)備驅(qū)動程序的編寫,加深讀者對啟動程序的了解。下面介紹一個簡單的設(shè)備驅(qū)動的實(shí)現(xiàn)過程。由于基于特殊的硬件設(shè)備實(shí)現(xiàn)的驅(qū)動程序難度較大,而且不方便驗(yàn)證,下面舉一個虛擬設(shè)備驅(qū)動程序的例子。第三十五頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:

實(shí)現(xiàn)虛擬設(shè)備的寫入、讀出等操作。這個驅(qū)動程序并不是基于特定硬件設(shè)備的,實(shí)際上僅僅是對內(nèi)存進(jìn)行讀、寫操作。設(shè)備功能介紹第三十六頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:設(shè)備功能介紹

1.函數(shù)mydrv_read()的功能是從mybuf[100]中讀取字符串,并傳遞給調(diào)用的進(jìn)程。

2.函數(shù)mydrv_write()的功能是將調(diào)用的進(jìn)程傳入的字符串賦值給mybuf,如果字符串的長度超過100,則只取前100個字符。

3.函數(shù)mydrv_ioctl()中僅僅實(shí)現(xiàn)了一個控制功能:清除mybuf存儲區(qū)。第三十七頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:

首先,要根據(jù)設(shè)備功能的需要,編寫結(jié)構(gòu)中的操作函數(shù)。

其次,要向系統(tǒng)注冊該設(shè)備,包括字符設(shè)備的注冊,devfs節(jié)點(diǎn)的注冊與中斷響應(yīng)函數(shù)的注冊。然后就可以利用對應(yīng)的文件進(jìn)行設(shè)備操控了。具體如下:具體實(shí)現(xiàn)第三十八頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)

#include<linux/module.h> #include<linux/kernel.h> #include<linux/fs.h> #include<linux/types.h> #include<linux/malloc.h> #include<asm/uaccess.h> #include<asm/page.h> #include<linux/ermo.h> #include<linux/config.h>1.源程序:第三十九頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)#defineMYDRV_CLS_IO('c',0x01) //定義清存儲區(qū)命令字

charmybuf[100]; //存儲區(qū)域

intmydrv_major=99; //主設(shè)備號

devfs_handle_tdev_handle; //保存設(shè)備文件系統(tǒng)的注冊句柄

//第一步:編寫函數(shù)第四十頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)ssize_tmydrv_read(structfile*filp,char*buf,size_tcount,loff_t*f_pos);//函數(shù)聲明

staticssize_tmydrv_write(structfile*filp,constchar*buf,size_tcount,loff_t*ppos); staticintmydrv_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg); intmydrv_open(structinode*inode,structfile*filp); intmydrv_release(structinode*inode,structfile*filp);//函數(shù)聲明第四十一頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)structmydrv_ops={ //設(shè)備函數(shù)接口

open:mydrv_open,//實(shí)現(xiàn)對設(shè)備的操作

read:mydrv_read,write:mydrv_write,ioctl:mydrv_ioctl, release:mydrv_release; }; //mydrv_read()將內(nèi)核空間的mybuf中的字符串賦給用戶空間的buf區(qū)第四十二頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)ssize_tmydrv_read(structfile*filp,char*bur,size_tcount,loff_t*f_pos) //filp:指向設(shè)備文件的指針;f_pos:偏移量

intlength=strlen(mybuf); if(count>99)count=99; //忽略大于100部分

count=length-*f_pos; //計算字符個數(shù)的技巧第四十三頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)if(copy_to_user(buf,mybuf,count)){ //重內(nèi)核區(qū)復(fù)制到用戶區(qū)

printk("errorreading,copy_to_user\n”); retum-EFAULT; } *f_pos+=count;//下一個

retumcount; } //mydtv_write()將用戶空間的buf字符串賦給內(nèi)核空間的mybuf[]數(shù)組中第四十四頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)staticssize_tmydrv_write(structfile*filp,constchar*buf,size_tcount,loff_t*ppos){ intnum; num=count<100?count:100; if(copy_from_user(mybuf,buf,num))//mybufbuf return-EFAULT; printk("mydrv_writesucceed!\n”); returnnum; }第四十五頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)staticintmydrv_ioctl(structinode*inode,structfile*file,//如果傳人的命令字是

unsignedintcmd,unsignedlongarg){//MYDRV-CLS則清除mybuf數(shù)組內(nèi)容

switch(cmd){ caseMYDRV_CLS: mybuf[0]=0x0; return0; default: return-EINVAL; } } //打開mydrv設(shè)備時調(diào)用第四十六頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)#defineMAX_MYDRV_DEV2 intmydrv_open(structinode*inode,structfile*filp){//inede:設(shè)備文件節(jié)點(diǎn)

unsignedintdev=MINOR(inode->i_rdev); if(mydrv_num) return-1;第四十七頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)if(dev>=MAX_MYDRV_DEV) return-ENODEV; filp->f_ap=&mydrv_ops;//指向操作函數(shù)

printk(“opensuccess\n”); MOD_INC_USE_COUNT;//只是簡單地加1 return0; } //關(guān)閉mydrv設(shè)備,這里只是將引用次數(shù)減1 intmydrv_release(structinode*inode,structfile*filp){ MOD_DEC_USE_COUNT; return0; }第四十八頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)//第二步:向系統(tǒng)注冊該設(shè)備

//module的安裝,采用兩種方式進(jìn)行了設(shè)備的注冊

intinit_module(void) { intresult; printk(“initing...\n”); result=devfs_register_chrdev(mydrv_major,“mydrv”,&mydrv_ops);第四十九頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)if(result<0){ printk(KERN_WARNING“mydrv:unabletogetmajor%d\n”,mydrv_major); returnresult; } dev_handle=devfs_register(NULL,“mydrv",DEVFS_FL_DEFAULT,99,0, S_IFCHR,&mydrv_ops,NULL); //devfs_register(devfs_handle_tdir,constchar*name,unsignedintflags, //unsignedintmajor,unsignedintminor,umode_tmode,void*ops,void*info)第五十頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)if(mydrv_major:==0) mydrv_major=result; strcpy(mybuf,"Hello,pleasewriteanything(length<100)tomydrv.”); printk(“succeedingettingbuffer\n"); printk("%s\n",mybuf); retum0; } //module的卸載,進(jìn)行設(shè)備的注銷第五十一頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)voidcleanup_module(void) { devfs_unregister_chrdev(mydrv_major,“mydrv”); devfs_unregister(dev_handle); printk("exiting...\n"); }第五十二頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)2.設(shè)備驅(qū)動程序編譯和安裝

采用下面的命令可以對mydrv.c進(jìn)行編譯:

[root@Linuxroot]#gcc-cmydrv.c–D__KERNEL__-DMODULE-O2-g-Wall-o

如果沒有出錯的話,將會在本目錄下生成一個mydrv.o文件。第五十三頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)

下面的操作必須是以root身份進(jìn)行的(用命令su轉(zhuǎn)換成root身份): 先執(zhí)行模塊的插入操作,

[root@Unuxroot]#/sbin/insmodmydrv.o第五十四頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)

如果設(shè)備文件系統(tǒng)已經(jīng)應(yīng)用起來的話,此時在設(shè)備文件系統(tǒng)掛接的目錄(通常是/dev)下,就可以找到mydrv文件節(jié)點(diǎn)了。如果沒有應(yīng)用設(shè)備文件系統(tǒng),則需要手工為設(shè)備添加文件節(jié)點(diǎn):

[root@Linux/dev]#mknodmydrvc990

此時就可以對設(shè)備進(jìn)行讀、寫、ioctl等操作了。第五十五頁,共六十二頁。10.3驅(qū)動程序編寫實(shí)例:具體實(shí)現(xiàn)

當(dāng)不再需要對設(shè)備進(jìn)行操作時,可以采用下面的命

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論