Linux操作系統(tǒng)第五章_第1頁
Linux操作系統(tǒng)第五章_第2頁
Linux操作系統(tǒng)第五章_第3頁
Linux操作系統(tǒng)第五章_第4頁
Linux操作系統(tǒng)第五章_第5頁
已閱讀5頁,還剩47頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第五章中斷與異常中斷的基本知識中斷描述符表的初始化中斷處理中斷的下半部處理機(jī)制中斷的應(yīng)用-時鐘中斷數(shù)據(jù)傳送控制方式選擇和衡量控制方式的原則:數(shù)據(jù)傳送速度足夠高系統(tǒng)開銷小,所需的處理控制程序少;能充分發(fā)揮硬件資源的能力;數(shù)據(jù)傳送控制方式程序直接控制方式中斷控制方式DMA方式通道方式ProgrammedDirectControl否外圍設(shè)備做接收或發(fā)送數(shù)據(jù)準(zhǔn)備接收到start命令標(biāo)志觸發(fā)器置“done”等待CPU來的下條指令準(zhǔn)備完畢?是否CPU發(fā)start命令等待執(zhí)行下條指令開始數(shù)據(jù)傳送設(shè)備標(biāo)志觸發(fā)器為done”?是(a)(b)優(yōu)點:控制簡單,不需要多少硬件支持缺點:1.CPU和外設(shè)只能串行工作;2.CPU在一段時間內(nèi)只能和一臺外設(shè)交換數(shù)據(jù),不能實現(xiàn)設(shè)備間的并行操作;3.無法發(fā)現(xiàn)和處理由于設(shè)備和其他硬件所產(chǎn)生的錯誤。Interrupt中斷控制方式的處理過程接收到CPU發(fā)來的start指令準(zhǔn)備數(shù)據(jù)并將其置入緩沖寄存器緩沖寄存器滿嗎?控制器發(fā)中斷信號向設(shè)備發(fā)start指令將中斷允許位置1調(diào)度程序調(diào)度其他進(jìn)程其他進(jìn)程執(zhí)行收到中斷信號了嗎?中斷處理被中斷進(jìn)程執(zhí)行否否是是設(shè)備CPU優(yōu)點:并行操作缺點:1.I/O控制器的數(shù)據(jù)緩沖寄存器滿,就會發(fā)中斷。此寄存器一般較小,則在一次數(shù)據(jù)傳送過程中,中斷次數(shù)較多,將耗去大量CPU時間;若設(shè)備間并行操作,則中斷次數(shù)增加,造成CPU無法響應(yīng)中斷和數(shù)據(jù)丟失。2.中斷方式是假設(shè)外設(shè)速度很低。如果外設(shè)速度很高,則造成CPU來不及取走數(shù)據(jù)緩沖寄存器中的數(shù)據(jù),造成數(shù)據(jù)丟失。中斷控制的主要優(yōu)點:CPU只有在I/O需要服務(wù)時才響應(yīng)。外部中斷:外部設(shè)備所發(fā)出的I/O請求。內(nèi)部中斷:也稱之為“異常”,是為解決機(jī)器運行時所出現(xiàn)的某些隨機(jī)事件及編程方便而出現(xiàn)的。<>中斷掠影中斷向量:8位無符號整數(shù)中斷源的編號0~255外設(shè)可屏蔽中斷:32~47屏蔽外部I/O請求

中斷線、IRQ異常及非屏蔽中斷:0~31異常:CPU內(nèi)部中斷非屏蔽中斷:計算機(jī)內(nèi)部硬件出錯引起的異常軟中斷:48~255中斷描述符表:描述中斷的相關(guān)信息中斷相關(guān)的匯編指令:<>5.1中斷的基本知識中斷向量-每個中斷源都被分配一個8位無符號整數(shù)作為類型碼,即中斷向量。(0~255)中斷的種類:中斷:外部可屏蔽中斷外部非屏蔽中斷異常:不使用中斷控制器,不能被屏蔽故障陷阱<>中斷向量-中斷源的類型Intelx86通過兩片中斷控制器8259A來響應(yīng)15個外中斷源,每個8259A可管理8個中斷源。外部設(shè)備擁有相應(yīng)權(quán)限時

,可以向特定的中斷線發(fā)送中斷請求信號IRQ。外部I/O請求的屏蔽:從CPU的角度,清除eflag的中斷標(biāo)志位(關(guān)中斷)從中斷控制器的角度,將中斷屏蔽寄存器的相應(yīng)位置位<>外設(shè)可屏蔽中斷

異常就是CPU內(nèi)部出現(xiàn)的中斷,即在CPU執(zhí)行特定指令時出現(xiàn)的非法情況。非屏蔽中斷就是計算機(jī)內(nèi)部硬件出錯時引起的異常情況。

Intel把非屏蔽中斷作為一種異常來處理。在CPU執(zhí)行一個異常處理程序時,就不再為其他異?;蚩善帘沃袛嗾埱蠓?wù)。

<>異常及非屏蔽中斷

Intelx86處理器發(fā)布了大約20種異常(具體數(shù)字與處理器模式有關(guān))。Linux內(nèi)核必須為每種異常提供一個專門的異常處理程序。

<>異常及非屏蔽中斷中斷描述符表(IDT):即中斷向量表,每個中斷占據(jù)一個表項(門描述符,8字節(jié))。<>中斷描述符表主要門描述符為:(1)中斷門(Interruptgate):類型碼為110,請求特權(quán)級(DPL)為0。

中斷門包含了一個中斷或異常處理程序所在段的選擇符和段內(nèi)偏移量。(2)陷阱門(Trapgate):類型碼為111,與中斷門類似,其唯一的區(qū)別是,不關(guān)中斷。(3)系統(tǒng)門(Systemgate):Linux內(nèi)核特別設(shè)置的,用來讓用戶態(tài)的進(jìn)程訪問Intel的陷阱門,DPL為3。系統(tǒng)調(diào)用就是通過系統(tǒng)門進(jìn)入內(nèi)核的。中斷描述符表寄存器IDTR:存放中斷描述符表在內(nèi)存的起始地址。中斷描述符表寄存器IDTR是一個48位的寄存器,其低16位保存中斷描述符表的大小,高32位保存中斷描述符表的基址。中斷描述符表調(diào)用過程指令CALL:CALL過程名調(diào)用中斷過程的指令I(lǐng)NT

INT中斷向量(0~255)中斷返回指令I(lǐng)RETIRET

加載中斷描述符表的指令LIDT

LIDT48位的偽描述符<>相關(guān)匯編指令

Linux內(nèi)核在系統(tǒng)的初始化階段要初始化可編程控制器8259A;將中斷描述符表的起始地址裝入IDTR寄存器,并初始化表中的每一項。

當(dāng)計算機(jī)運行在實模式時,中斷描述符表被初始化,并由BIOS使用。真正進(jìn)入了Linux內(nèi)核,中斷描述符表就被移到內(nèi)存的另一個區(qū)域,并為進(jìn)入保護(hù)模式進(jìn)行預(yù)初始化:用匯編指令LIDT對中斷向量表寄存器IDTR進(jìn)行初始化,即把IDTR置為0;把中斷描述符表IDT的起始地址裝入IDTR;setup_idt()函數(shù)填充中斷描述表中的256個表項。<>5.2中斷描述符表的初始化IDT表項的設(shè)置通過_set_gate()函數(shù)實現(xiàn)

調(diào)用該函數(shù)在IDT表中插入一個中斷門:voidset_intr_gate(unsignedintn,void*addr){_set_gate(idt_table+n,14,0,addr);}調(diào)用該函數(shù)在IDT表中插入一個陷阱門:staticvoid__init

set_trap_gate(unsignedintn,void*addr){_set_gate(idt_table+n,15,0,addr);}調(diào)用該函數(shù)在IDT表中插入一個系統(tǒng)門:staticvoid__initset_system_gate(unsignedintn,void*addr){_set_gate(idt_table+n,15,3,addr);}<>IDT表項的設(shè)置trap_init()函數(shù)用于設(shè)置中斷描述符表開頭的19個陷阱門和系統(tǒng)門。這些中斷向量都是CPU保留用于異常處理的,例:set_trap_gate(0,÷_error);set_trap_gate(1,&debug);set_trap_gate(19,&simd_coprocessor_error);set_system_gate(SYSCALL_VECTOR,&system_call);

<>初始化陷阱門和系統(tǒng)門中斷門的設(shè)置是由init_IRQ()函數(shù)中的一段代碼完成的:設(shè)置時必須跳過用于系統(tǒng)調(diào)用的向量0x80

中斷處理程序的入口地址是一個數(shù)組interrupt[],數(shù)組中的每個元素是指向中斷處理函數(shù)的指針。

<>中斷門的設(shè)置for(i=0;i<NR_IRQS;i++){intvector=FIRST_EXTERNAL_VECTOR+i;if(vector!=SYSCALL_VECTOR)set_intr_gate(vector,interrupt[i]);}中斷和異常的硬件處理:從硬件的角度看CPU如何處理中斷和異常中斷請求隊列的建立:方便外設(shè)共享中斷線

中斷處理程序的執(zhí)行

從中斷返回:調(diào)用恢復(fù)中斷現(xiàn)場的宏RESTORE_ALL,徹底從中斷返回

<>5.3中斷處理當(dāng)CPU執(zhí)行了當(dāng)前指令之后,CS和EIP這對寄存器中所包含的內(nèi)容就是下一條將要執(zhí)行指令的虛地址。在對下一條指令執(zhí)行前,CPU先要判斷在執(zhí)行當(dāng)前指令的過程中是否發(fā)生了中斷或異常。如果發(fā)生了一個中斷或異常,那么CPU將做以下事情:<>中斷和異常的硬件處理

確定所發(fā)生中斷或異常的向量i(在0~255之間)通過IDTR寄存器找到IDT表,讀取IDT表第i項(或叫第i個門)分“段”級、“門”級兩步進(jìn)行有效性檢查檢查是否發(fā)生了特權(quán)級的變化

中斷和異常處理中CPU的工作SSESPEFLAGSCSEIPERRORCODEEFLAGSCSEIPERRORCODE堆棧增長方向中斷發(fā)生前夕的SS:ESP返回地址錯誤碼<>中斷處理程序堆棧由于硬件條件的限制,很多硬件設(shè)備共享一條中斷線。為方便處理,Linux為每條中斷線設(shè)置了一個中斷請求隊列。中斷服務(wù)例程與中斷處理程序中斷線共享的數(shù)據(jù)結(jié)構(gòu)注冊中斷服務(wù)例程<>中斷請求隊列的建立中斷服務(wù)例程(InterruptServiceRoutine):每個中斷請求都有自己單獨的中斷服務(wù)例程。中斷處理程序:共享同一條中斷線的所有中斷請求有一個總的中斷處理程序。在Linux中,15條中斷線對應(yīng)15個中斷處理程序。<>中斷服務(wù)例程與中斷處理程序

structirqaction{void(*handler)(int,void*,structpt_regs*);unsignedlongflags;unsignedlongmask;constchar*name;void*dev_id;structirqaction*next;};

Handler:指向一個具體I/O設(shè)備的中斷服務(wù)例程Flags:用一組標(biāo)志描述中斷線與I/O設(shè)備之間的關(guān)系。SA_INTERRUPT:中斷處理程序執(zhí)行時必須禁止中斷SA_SHIRQ:允許其它設(shè)備共享這條中斷線。SA_SAMPLE_RANDOM:內(nèi)核可以用它做隨機(jī)數(shù)產(chǎn)生器。SA_PROBE:內(nèi)核正在使用這條中斷線進(jìn)行硬件設(shè)備探測。<>中斷線共享的數(shù)據(jù)結(jié)構(gòu)

<>structirqaction{void(*handler)(int,void*,structpt_regs*);unsignedlongflags;unsignedlongmask;constchar*name;void*dev_id;structirqaction*next;};

Name:I/O設(shè)備名dev_id:指定I/O設(shè)備的主設(shè)備號和次設(shè)備號(參見第9章)。Next:指向irqaction描述符鏈表的下一個元素

中斷線共享的數(shù)據(jù)結(jié)構(gòu)

初始化IDT表之后,必須通過request_irq()函數(shù)將相應(yīng)的中斷服務(wù)例程掛入中斷請求隊列,即對其進(jìn)行注冊。

在關(guān)閉設(shè)備時,必須通過調(diào)用free_irq()函數(shù)釋放所申請的中斷請求號。

<>注冊中斷服務(wù)例程

int

request_irq(unsigned

int

irq,void(*handler)(int,void*,struct

pt_regs*),unsignedlongirqflags,constchar*devname,void*dev_id)假定一個程序要對/dev/fd0/(第一個軟盤對應(yīng)的設(shè)備)設(shè)備進(jìn)行訪問,通常將IRQ6分配給軟盤控制器,給定這個中斷號6,軟盤驅(qū)動程序就可以發(fā)出下列請求,以將其中斷服務(wù)例程掛入中斷請求隊列:

request_irq(6,floppy_interrupt, SA_INTERRUPT|SA_SAMPLE_RANDOM,"floppy",NULL);

注冊中斷服務(wù)例程

所有的中斷處理程序都執(zhí)行四個基本的操作:在內(nèi)核棧中保存IRQ的值和寄存器的內(nèi)容。給與IRQ中斷線相連的中斷控制器發(fā)送一個應(yīng)答,這將允許在這條中斷線上進(jìn)一步發(fā)出中斷請求。執(zhí)行共享這個IRQ的所有設(shè)備的中斷服務(wù)例程(ISR)。跳到ret_from_intr()的地址后終止。<>中斷處理程序的執(zhí)行

CPU從中斷控制器的一個端口取得中斷向量I

根據(jù)I從中斷描述符表IDT中找到相應(yīng)的中斷門從中斷門獲得中斷處理程序IRQn_interrupt的入口地址

判斷是否要進(jìn)行堆棧切換調(diào)用do_IRQ()對所接收的中斷進(jìn)行應(yīng)答,并禁止這條中斷線調(diào)用handle_IRQ_event()來運行對應(yīng)的中斷服務(wù)例程-處理最緊急的任務(wù)。

<>中斷處理程序的執(zhí)行

IRQn_interrupt:pushl$n-256jmpcommon_interruptcommon_interrupt:SAVE_ALLcalldo_IRQjmpret_from_intrdo{status|=action->flags;action->handler(irq,action->dev_id,regs);action=action->next;}while(action);

當(dāng)處理所有外設(shè)中斷請求的函數(shù)do_IRQ()執(zhí)行時,內(nèi)核棧頂包含的就是do_IRQ()的返回地址,這個地址指向ret_from_intr。從中斷返回時,CPU要調(diào)用恢復(fù)中斷現(xiàn)場的宏RESTORE_ALL,徹底從中斷返回。

<>從中斷返回中斷服務(wù)例程在中斷請求關(guān)閉的條件下執(zhí)行,避免嵌套使中斷控制復(fù)雜化。

系統(tǒng)不能長時間關(guān)中斷運行,因此內(nèi)核應(yīng)盡可能快的處理完中斷請求,盡其所能把更多的處理向后推遲。內(nèi)核把中斷處理分為兩部分:上半部(tophalf)和下半部(bottomhalf),上半部內(nèi)核立即執(zhí)行,而下半部留著稍后處理。

<>5.4中斷的下半部處理機(jī)制

為什么把中斷分為兩部分來處理?一個快速的“上半部”來處理硬件發(fā)出的請求,它必須在一個新的中斷產(chǎn)生之前終止。這一部分做的工作很少。下半部運行時是允許中斷請求的,而上半部運行時是關(guān)中斷的,這是二者之間的主要區(qū)別。Linux內(nèi)核下半部的實現(xiàn)機(jī)制在內(nèi)核的演變:bottomhalf(簡稱bh)在2.4以后的版本:小任務(wù)(tasklet)下半部可以在多處理機(jī)上并行執(zhí)行,并有助于驅(qū)動程序的開發(fā)者進(jìn)行驅(qū)動程序的開發(fā)。

為什么把中斷分為兩部分來處理下半部是一個不能與其他下半部并發(fā)執(zhí)行的高優(yōu)先級小任務(wù)。

bh_base是一個指向下半部的指針數(shù)組,用于組織所有下半部

bh_base數(shù)組共有32項,每一項都是一種下半部。<>下半部

下半部外部設(shè)備TIMER_BH定時器TQUEUE_BH

周期性任務(wù)隊列SERIAL_BH

串行端口IMMEDIATE_BH

立即任務(wù)隊列Linux常用的下半部一個函數(shù)指針數(shù)組bh_base[],它把所有的后半部分都組織起來,其大小為32,數(shù)組中的每一項就是一個后半部分,即一個bh函數(shù)。設(shè)置了兩個32位無符號整數(shù)bh_active和bh_mask,每個無符號整數(shù)中的一位對應(yīng)著bh_base[]中的一個元素。在2.4以前的內(nèi)核中,每次執(zhí)行完do_IRQ()中的中斷服務(wù)例程以后,以及每次系統(tǒng)調(diào)用結(jié)束之前,就在一個叫do_bottom_half()的函數(shù)中執(zhí)行相應(yīng)的bh函數(shù)。在do_bottom_half()中對bh函數(shù)的執(zhí)行是在關(guān)中斷的情況下進(jìn)行的,這是因為,對單CPU來說,bh函數(shù)的執(zhí)行可以不嵌套;而對于多CPU來說,在同一時間內(nèi)最多只允許一個CPU執(zhí)行bh函數(shù)。那么,在新內(nèi)核的設(shè)計中,是改進(jìn)bh機(jī)制還是拋棄bh機(jī)制,建立一種新的機(jī)制?2.4選擇了一種折中的辦法,繼續(xù)保留bh機(jī)制,另外增加一種或幾種機(jī)制,并把它們納入一個統(tǒng)一的框架中,這就是2.4內(nèi)核中的軟中斷(softirq)機(jī)制。軟中斷機(jī)制:軟中斷卻在任何時候都不需要串行化。Tasklet機(jī)制:建立在軟中斷之上,同一個tasklet只能運行在一個CPU上,而不同的tasklet可以同時運行在不同的CPU上。在這種情況下,tasklet就不需要是可重入的,因此,編寫tasklet比編寫一個軟中斷要容易。

Bh機(jī)制在2.4中依然存在,但不是作為一個單獨的機(jī)制存在,而是建立在tasklet之上。因此,在2.4版中,設(shè)備驅(qū)動程序的開發(fā)者必須更新他們原來的驅(qū)動程序,用tasklet代替bh。下半部

小任務(wù)是指待處理的下半部,其數(shù)據(jù)結(jié)構(gòu)為tasklet_struct,每個結(jié)構(gòu)代表一個獨立的小任務(wù)。小任務(wù)既可以靜態(tài)地創(chuàng)建,也可以動態(tài)地創(chuàng)建。

<>小任務(wù)機(jī)制

structtasklet_struct{Structtasklet_struct*next;unsignedlongstate;atomic_tcount; void(*func)(unsignedlong);unsignedlongdata; };

如果準(zhǔn)備靜態(tài)地創(chuàng)建一個小任務(wù)(也就是對它直接引用),使用下面兩個宏中的一個:DECLARE_TASKLET(name,func,data)DECLARE_TASKLET_DISABLED(name,func,data)這兩個宏都能根據(jù)給定的名字靜態(tài)地創(chuàng)建一個tasklet_struct結(jié)構(gòu)。第一個宏把創(chuàng)建的小任務(wù)的引用計數(shù)器設(shè)置為0,因此,該小任務(wù)處于激活狀態(tài)。另一個把引用計數(shù)器設(shè)置為1,所以該小任務(wù)處于禁止?fàn)顟B(tài)。例如:DECLARE_TASKLET(my_tasklet,my_tasklet_handler,dev);這行代碼其實等價于structtasklet_structmy_tasklet={NULL,0,ATOMIC_INIT(0),tasklet_handler,dev};聲明和使用小任務(wù)voidtasklet_handler(unsignedlongdata)小任務(wù)不能睡眠,不能在小任務(wù)中使用信號量或者其它產(chǎn)生阻塞的函數(shù)。但它運行時可以響應(yīng)中斷。通過調(diào)用tasklet_schedule()函數(shù)并傳遞給它相應(yīng)的tasklet_struct指針,該小任務(wù)就會被調(diào)度以便適當(dāng)?shù)臅r候執(zhí)行:tasklet_schedule(&my_tasklet)在小任務(wù)被調(diào)度以后,只要有機(jī)會它就會盡可能早的運行。調(diào)用tasklet_disable()函數(shù)來禁止某個指定的小任務(wù)。tasklet_disable(&my_tasklet);調(diào)用tasklet_enable()函數(shù)可以激活一個小任務(wù)。tasklet_enable(&my_tasklet); 可以調(diào)用tasklet_kill()函數(shù)從掛起的隊列中去掉一個小任務(wù)。<>編寫并調(diào)度自己的小任務(wù)任務(wù)隊列就是指以雙向隊列形式連接起來的任務(wù)鏈表,每一個鏈表元素都描述了一個可執(zhí)行的內(nèi)核任務(wù)。tq_struct來描述任務(wù)隊列中的每一個鏈表成員。三個特殊的任務(wù)隊列:tq_immediate任務(wù)隊列,由IMMEDIATE_BH下半部運行,該隊列中包括要執(zhí)行的內(nèi)核函數(shù)和標(biāo)準(zhǔn)的下半部。

tq_timer任務(wù)隊列,由TQUEUE_BH下半部運行,每次時鐘中斷都激活這個下半部。tq_disk任務(wù)隊列,用于塊設(shè)備任務(wù)。<>任務(wù)隊列大部分PC機(jī)中有兩個時鐘源,分別是實時時鐘(RTC)和操作系統(tǒng)(OS)時鐘。實時時鐘也叫硬件時鐘,它靠電池供電,即使系統(tǒng)斷電,也可以維持日期和時間。RTC和OS時鐘之間的關(guān)系通常也被稱作操作系統(tǒng)的時鐘運作機(jī)制。不同的操作系統(tǒng),其時鐘運作機(jī)制也不同。

<>5.5中斷的應(yīng)用-時鐘中斷時鐘運作機(jī)制OS時鐘是由可編程定時/計數(shù)器產(chǎn)生的輸出脈沖觸發(fā)中斷而產(chǎn)生的。操作系統(tǒng)的“時間基準(zhǔn)”由設(shè)計者決定,Linux的時間基準(zhǔn)是1970年1月1日凌晨0點。OS時鐘記錄的時間就是系統(tǒng)時間。系統(tǒng)時間以“時鐘節(jié)拍”為單位。Linux中用全局變量jiffies表示系統(tǒng)自啟動以來的時鐘節(jié)拍數(shù)目。每次時鐘中斷jiffies就加1.

<>Linux時間系統(tǒng)每一次時鐘中斷的產(chǎn)生都觸發(fā)下列幾個主要的操作:自系統(tǒng)啟動以來所花費的時間加1更新時間和日期確定當(dāng)前進(jìn)程在CPU上已運行了多長時間,如果已經(jīng)超過了分配給它的時間,則搶占它更新資源使用統(tǒng)計數(shù)檢查定時器時間間隔是否已到,如果是,則調(diào)用適當(dāng)?shù)暮瘮?shù)

<>時鐘中斷處理程序時鐘中斷處理程序本身來完成通過TIMER_BH和TQUEUE_BH下半部調(diào)用的函數(shù)來完成timer_bh()函數(shù)與TIMER_BH下半部相關(guān)聯(lián),它在每個時鐘節(jié)拍都被激活。

TIMER_BH下半部以關(guān)中斷調(diào)用update_times()函數(shù),該函數(shù)會以關(guān)中斷來更新xtime。更新了系統(tǒng)時鐘xtime之后,update_times()再次打開中斷。時鐘中斷的下半部處理<>定時器是管理內(nèi)核所花時間的基礎(chǔ),也被稱為動態(tài)定時器或內(nèi)核定時器。

定時器的使用:執(zhí)行一些初始化工作,設(shè)置一個到期時間,指定

溫馨提示

  • 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

提交評論