![socket數(shù)據(jù)發(fā)送過程zz_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-4/16/863c503b-f419-45d2-b27a-74857b1202b9/863c503b-f419-45d2-b27a-74857b1202b91.gif)
![socket數(shù)據(jù)發(fā)送過程zz_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-4/16/863c503b-f419-45d2-b27a-74857b1202b9/863c503b-f419-45d2-b27a-74857b1202b92.gif)
![socket數(shù)據(jù)發(fā)送過程zz_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-4/16/863c503b-f419-45d2-b27a-74857b1202b9/863c503b-f419-45d2-b27a-74857b1202b93.gif)
![socket數(shù)據(jù)發(fā)送過程zz_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-4/16/863c503b-f419-45d2-b27a-74857b1202b9/863c503b-f419-45d2-b27a-74857b1202b94.gif)
![socket數(shù)據(jù)發(fā)送過程zz_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-4/16/863c503b-f419-45d2-b27a-74857b1202b9/863c503b-f419-45d2-b27a-74857b1202b95.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、.socket數(shù)據(jù)發(fā)送過程zz本文在基于以下三個(gè)條件所寫的:1OSI七層網(wǎng)絡(luò)通信模型。2所闡述的函數(shù)是基于Linux2.6.1內(nèi)核。3在面向連接的通信協(xié)議TCP/IPV4的根底上。由于七層模型應(yīng)用層,表示層,會(huì)話層,傳輸層,網(wǎng)絡(luò)層,數(shù)據(jù)鏈路層,物理層可以簡(jiǎn)化為以下五層構(gòu)造應(yīng)用層Application Layer,傳輸層Transport Layer,網(wǎng)絡(luò)層Network Layer,數(shù)據(jù)鏈路層Data Link Layer,物理層Physical Layer.其中七層模型中的前三層都?xì)w結(jié)為五層構(gòu)造中的應(yīng)用層。為了簡(jiǎn)化討論,本文主要從這五層構(gòu)造來討論。Layer 5:應(yīng)用層Application
2、 Layer在TCP協(xié)議上,當(dāng)通過三方握手建立了連接之后,就進(jìn)入數(shù)據(jù)包的本質(zhì)發(fā)送階段,在本文中以send命令來闡述。當(dāng)通過send將數(shù)據(jù)包發(fā)送之后,glibc函數(shù)庫會(huì)啟用另外一個(gè)其定義的別用名函數(shù)_libc_sendto,該函數(shù)最后會(huì)間接執(zhí)行到sendto系統(tǒng)調(diào)用:inline_syscall#nrname,args;/#nr說明是該系統(tǒng)調(diào)用帶有nr個(gè)args參數(shù)sendto系統(tǒng)調(diào)用的參數(shù)值是6,而name就是sendto從上面的分析可以看出glibc將要執(zhí)行的下面一條語句是inline_syscall6name,arg1,arg2,arg3,arg4,arg5,arg6在該函數(shù)中一段主要功能
3、實(shí)現(xiàn)代碼如下:_asm_ _volatile_"callsys#%0%1=%2%3%4%5%6%7%8":inline_syscall_r0_out_constraint_sc_0,"=r"_sc_19,"=r"_sc_16,"=r"_sc_17,"=r"_sc_18,"=r"_sc_20,"=r"_sc_21:"0"_sc_0,"2"_sc_16,"3"_sc_17,"4"_
4、sc_18,"1"_sc_19,"5"_sc_20,"6"_sc_21:inline_syscall_clobbers;_sc_ret=_sc_0,_sc_err=_sc_19;該代碼采用了嵌入?yún)R編詳細(xì)介紹查閱嵌入?yún)R編相關(guān)書籍,其中:_sc_0=sendto;_sc_19-_sc_21分別是arg1-arg6;inline_syscall_r0_out_constraint:功能相當(dāng)于"=r",選用一個(gè)存放器來存儲(chǔ)輸出變量。"0"-"6"分別是%0-%6,代表_sc_0-_s
5、c_21接下來函數(shù)最終通過Linux中頂頂有名的INT 0X80陷入系統(tǒng)核心。詳細(xì)的過程可以參考內(nèi)核相關(guān)書籍。下面是一個(gè)兄弟對(duì)INT 0X80的簡(jiǎn)要介紹:在陷入系統(tǒng)內(nèi)核以后,最終會(huì)調(diào)用系統(tǒng)所提供的系統(tǒng)調(diào)用函數(shù)sys_sendto,該函數(shù)直接調(diào)用了_sock_sendmsg,該函數(shù)對(duì)進(jìn)程做一個(gè)簡(jiǎn)單的權(quán)限檢查之后就觸發(fā)套接字socket中定義的虛擬sendmsg的函數(shù),進(jìn)而進(jìn)入到下一層傳輸層處理。Layer 4:傳輸層Transport Layer由上層的討論可知,系統(tǒng)觸發(fā)了sendmsg虛擬接口函數(shù),其實(shí)就是傳輸層中的tcp_sendmsg或是udp_sendmsg,看你所使用的協(xié)議而定。本文介
6、紹tcp_sendmsg.該函數(shù)需要做如下工作:1為sk_buff后面簡(jiǎn)稱skb分配空間,該函數(shù)首先嘗試在套接字緩沖隊(duì)列中尋找空閑空間,假設(shè)找不到就使用tcp_alloc_pskb為其重新分配空間。2下面這步就會(huì)tcp_sendmsg函數(shù)的主要部分了,將數(shù)據(jù)拷貝到緩沖區(qū)。它分為如下兩種情況:2.1假設(shè)skb還有剩余空間的話,就使用skb_add_data來向skb尾部添加數(shù)據(jù)包。代碼如下:ifskb_tailroomskb0/*We have some space in skb head.Superb!*/ifcopy skb_tailroomskbcopy=skb_tailroomskb;i
7、ferr=skb_add_dataskb,from,copy!=0 gotodo_fault;2.2假設(shè)skb沒有了可用空間,內(nèi)核會(huì)使用TCP_PAGE宏來為發(fā)送的數(shù)據(jù)包分配一個(gè)高速緩存頁空間,當(dāng)該頁被正確地分配后就調(diào)用Copy_from_usertopage地址,fromusr空間,n將用戶空間數(shù)據(jù)包復(fù)制到page所在的地址空間。但是我們都知道數(shù)據(jù)包在協(xié)議層之間的傳輸是通過skb的,難道將數(shù)據(jù)包復(fù)制到這個(gè)新分配的page中,內(nèi)核就可以去睡大覺了嗎?當(dāng)然不是!接下來內(nèi)核就要來處理這個(gè)問題了,那么怎樣來處理呢?此時(shí)就需要使用到skb中的另外一個(gè)數(shù)據(jù)區(qū)struct skb_shared_info,
8、但是該數(shù)據(jù)區(qū)在創(chuàng)立skb時(shí)是沒有為其分配空間的,也就是說它開場(chǎng)純粹就是個(gè)指針,而沒有詳細(xì)的告訴它要指向什么地方。這時(shí)大家應(yīng)該知道它可以指向什么地方了,對(duì),就是page!在內(nèi)核中對(duì)這種情況的詳細(xì)是通過fill_page_descstruct sk_buff*skb,int I,struct page*page,int off,int size來實(shí)現(xiàn)的,代碼如下:staticinlinevoidfill_page_descstruct sk_buff*skb,int i,struct page*page,int off,int sizeskb_frag_t*frag=&skb_shinfo
9、skb-fragsi;frag-page=page;frag-page_offset=off;frag-size=size;skb_shinfoskb-nr_frags=i+1;這里需要注意的是struct skb_shared_info只能通過skb_shinfo來獲取,在該構(gòu)造體中skb_flag_t類型的flagsi就是詳細(xì)指向page的數(shù)組。2.3至此skb數(shù)據(jù)包的裝載工作算是完畢了,接下來就需要做一些后續(xù)工作,包括是否要分片,以及后來的TCP協(xié)議頭的添加。先看在tcp_sendmsg中的最后一個(gè)重要函數(shù)tcp_push,它的調(diào)用格式如下:staticinlinevoidtcp_pus
10、hstruct sock*sk,struct tcp_opt*tp,int flags,int mss_now,int nonagle細(xì)心的朋友會(huì)發(fā)現(xiàn),在該函數(shù)中傳輸?shù)木谷徊皇莝kb,而是一個(gè)名為sock的構(gòu)造體,那這又是什么東東呢?個(gè)人理解是它在頂層協(xié)議層之間例如:應(yīng)用層和傳輸層之間的傳輸起著非常重要的作用,相當(dāng)于溝通兩層之間的紐帶。再深化查找下該構(gòu)造體的構(gòu)成,我們很容易發(fā)現(xiàn)這樣一個(gè)構(gòu)造體變量:struct sk_buff_head,有名稱我們可以知道它是用來描繪skb頭部信息的一個(gè)構(gòu)造體,它指向了buffer的數(shù)據(jù)區(qū)。這下我們也明白了點(diǎn),這個(gè)構(gòu)造體其實(shí)還充當(dāng)了一個(gè)隊(duì)列作用,是用來存儲(chǔ)skb
11、的數(shù)據(jù)區(qū)。協(xié)議層之間傳輸完之后,詳細(xì)到該層處理時(shí)內(nèi)核就會(huì)從sk_buff_head逐個(gè)中取出skb數(shù)據(jù)區(qū)來處理,例如添加協(xié)議頭等。好了,tcp_sendmsg到此完畢了它的使命了,下面將要需要的一個(gè)函數(shù)就是在tcp_push中直接用到的一個(gè)函數(shù):_tcp_push_pending_frames,該函數(shù)又直接調(diào)用tcp_write_xmit函數(shù)來進(jìn)一步對(duì)數(shù)據(jù)包處理,它包括一下兩步:1檢查是否需要對(duì)數(shù)據(jù)包進(jìn)展分片,條件是只要skb中全部數(shù)據(jù)長(zhǎng)度大于當(dāng)前路由負(fù)荷量就需要分片。2采用skb_cloneskb,GFP_ATOMIC為TCP_HEAD分配一個(gè)sk_buff空間,這里需要注意的是skb_cl
12、one分配空間的特點(diǎn),它首先是按照參數(shù)skb來來復(fù)制出一個(gè)新的sk_buff,新的skb和舊的skb共享數(shù)據(jù)變量緩存區(qū),但是構(gòu)造體緩沖區(qū)不是共享的,這似乎和copy on write機(jī)制有些相似。3在分配了一個(gè)新的skb之后,內(nèi)核就會(huì)執(zhí)行tcp_transmit_skb.其實(shí)內(nèi)核中是將2,3步合在一起的,如下:tcp_transmit_skbsk,skb_cloneskb,GFP_ATOMIC接下來就是tcp_transmit_skb函數(shù)的實(shí)現(xiàn)過程了。1通過skb_push在skb前面參加tcp協(xié)議頭信息。這包括序列號(hào),源地址,目的地址,校驗(yàn)和等。2通過tcp_opt構(gòu)造體它是在該函數(shù)的開場(chǎng)部
13、分從sock構(gòu)造體中獲得的tcp_func構(gòu)造體中的.queue_xmit虛擬功能函數(shù),在IPV4中是調(diào)用了ip_queue_xmit,這樣就進(jìn)入了下一層-網(wǎng)絡(luò)層。Layer 3網(wǎng)絡(luò)層Network Layer在ip_queue_xmit函數(shù)中需要做的事情有一下幾件:1是否需要將數(shù)據(jù)包進(jìn)展路由,假設(shè)需要的話就跳到包路由子程序段。判斷是否需要路由是由如下語句執(zhí)行的:rt=struct rtable*skb-dst;ifrt!=NULLgoto packet_routed;在skb的dst變量中指明發(fā)送目的地址。它存放了路由途徑中的下臺(tái)主機(jī)地址。假設(shè)是需要對(duì)數(shù)據(jù)包進(jìn)展路由,那么其執(zhí)行分如下步驟1.
14、1使用skb_push在skb前面插入一段ip_headsize大小的空間。1.2填寫ip協(xié)議頭,包括ttl,protocol等1.3寫入校驗(yàn)和,最后調(diào)用NF_HOOK宏,關(guān)于NF_HOOK后面介紹。調(diào)用的NF_HOOK宏語句如下:NF_HOOKPF_INET,NF_IP_LOCAL_OUT,skb,NULL,rt-u.dst.dev,dst_output;2假設(shè)沒有路由地址,內(nèi)核會(huì)嘗試從外部可選項(xiàng)中來獲取該地址,此時(shí)傳輸層發(fā)現(xiàn)沒有路由地址會(huì)不斷地發(fā)出重發(fā)機(jī)制,直到路由地址獲取到。當(dāng)獲取到路由地址之后,內(nèi)核會(huì)通過以下語句重新將地址賦給skb-dst.之后就會(huì)進(jìn)入到1所述的路由子程序段執(zhí)行。sk
15、b-dst=dst_clone&rt-u.dst;所以這樣看來正常情況下內(nèi)核都會(huì)進(jìn)入1.3所闡述的NF_HOOK宏的執(zhí)行。關(guān)于NF_HOOK宏,我也不怎么理解,但是查了下內(nèi)核后可以大體的知道,當(dāng)二維數(shù)組nf_hookspfhook其下標(biāo)分別是調(diào)用宏中的第一個(gè)和第二個(gè)參數(shù)中定義了需要的鉤子函數(shù)時(shí),就會(huì)調(diào)用nf_hook_slow函數(shù)來處理,假設(shè)沒有定義鉤子函數(shù)就直接調(diào)用NF_HOOK中的最后一個(gè)參數(shù)所指向的函數(shù),在這里是:dst_outputskb。在網(wǎng)上搜了下,發(fā)現(xiàn)一篇講解NF_HOOK的帖子,很詳細(xì),鏈接如下:上面已經(jīng)談到,當(dāng)存在鉤子函數(shù)時(shí),內(nèi)核轉(zhuǎn)向nf_hook_slow函數(shù)來處理
16、。下面闡述下這個(gè)函數(shù):1檢查hook函數(shù)是否真的已經(jīng)設(shè)置,假設(shè)沒有設(shè)置就將hook對(duì)應(yīng)位通過移位來設(shè)置;當(dāng)確認(rèn)已經(jīng)設(shè)置后就取出該鉤子函數(shù),如下:elem=&nf_hookspfhook;2執(zhí)行nf_iterate函數(shù),該函數(shù)采用list_for_each_continue_rcuHOOK鏈表中的每個(gè)nf_hook_ops鉤子構(gòu)造體,通過其內(nèi)部變量priority來判斷它的優(yōu)先級(jí)是否大于系統(tǒng)所定義的INT_MIN,假設(shè)小于就繼續(xù)搜索,否那么就執(zhí)行該構(gòu)造體單元中所指向的鉤子函數(shù)。ifhook_thresh elem-prioritycontinue;/*Optimization:we do
17、n't need to hold module reference here,since function can't sleep.-RR*/switchelem-hookhook,skb,indev,outdev,okfn。當(dāng)鉤子函數(shù)成功執(zhí)行之后,它會(huì)返回一個(gè)NF_ACCEPT標(biāo)志,3判斷nf_iterate函數(shù)的返回標(biāo)志,如下:switchverdictcase NF_ACCEPT:ret=okfnskb;break;case NF_DROP:kfree_skbskb;ret=-EPERM;break;由上面的代碼可以看到,當(dāng)標(biāo)志是NF_ACCEPT時(shí),內(nèi)核會(huì)繼續(xù)調(diào)用okf
18、nskb函數(shù),也就是傳遞給NF_HOOK的最后一個(gè)參數(shù)dst_outputskb。該函數(shù)非常簡(jiǎn)單,就是間接啟用和skb相關(guān)的output函數(shù),如下:for;err=skb-dst-outputskb;iflikelyerr=0return err;ifunlikelyerr!=NET_XMIT_BYPASSreturn err;內(nèi)核這句skb-dst-outputskb,就將skb打入到了下面的一層-數(shù)據(jù)鏈路層.Layer 2數(shù)據(jù)鏈路層Data Link Layer上層的output函數(shù)最終會(huì)觸發(fā)鏈路層中的dev_queue_xmitskb函數(shù)。在該函數(shù)中需要做的事情如下:1對(duì)傳輸過來的skb
19、包進(jìn)展檢查,主要是:1.1數(shù)據(jù)包有分散的數(shù)據(jù)片段即skb_infoskb-nr_frags 0,但是接口不能傳輸這樣的數(shù)據(jù)包片段即dev-features中沒有設(shè)置NETIF_F_FRAGLIST,這個(gè)時(shí)候內(nèi)核就會(huì)執(zhí)行數(shù)據(jù)包線性化函數(shù)_skb_linearizeskb,GFP_ATOMIC,簡(jiǎn)單來說該函數(shù)就是將skb中的數(shù)據(jù)片段存儲(chǔ)到由內(nèi)核所創(chuàng)立的一個(gè)緩沖區(qū)中,并釋放掉原來的skb數(shù)據(jù)區(qū),將skb指向新分配的數(shù)據(jù)緩沖區(qū)。1.2和上面的條件很相似,不過還添加了一個(gè)判斷條件,那就是設(shè)備是否在高內(nèi)存緩沖區(qū),并且設(shè)備又不支持DMA對(duì)數(shù)據(jù)的存取,此時(shí)也需要將數(shù)據(jù)包線性化。2假設(shè)包沒有實(shí)現(xiàn)IP校驗(yàn),就需要
20、再次對(duì)數(shù)據(jù)包檢驗(yàn)。3啟用qdisc_rundev,該函數(shù)檢查網(wǎng)卡是否可以接收數(shù)據(jù),假設(shè)不可以就重新檢查直到可以發(fā)送為止,假設(shè)可以就調(diào)用qdisc_restart來詳細(xì)實(shí)現(xiàn)。qdisc_restart的實(shí)現(xiàn)如下:3.1檢查dev中數(shù)據(jù)包隊(duì)列是否為空,假設(shè)不為空就試圖獲取驅(qū)動(dòng)程序的使用權(quán)限,當(dāng)網(wǎng)卡可以接收數(shù)據(jù)包時(shí)就調(diào)用dev-hard_start_xmitskb,dev來執(zhí)行驅(qū)動(dòng)程序的數(shù)據(jù)包發(fā)送函數(shù)。3.2假設(shè)沒有獲取到驅(qū)動(dòng)程序的使用權(quán)限,這中情況一般是在調(diào)用hard_start_xmitskb,dev時(shí)出現(xiàn)了暫時(shí)的配置錯(cuò)誤。這時(shí)可以檢查下驅(qū)動(dòng)程序在被什么使用,假設(shè)是死循環(huán)的話,將數(shù)據(jù)包丟棄!3.
21、3執(zhí)行netif_scheduledev,在該函數(shù)之后的情況我就不再多說了,有一個(gè)網(wǎng)友寫的很精彩,鏈接如下:至此,各協(xié)議層的數(shù)據(jù)包發(fā)送過程就算是全部完成了,接下來就進(jìn)入到驅(qū)動(dòng)程序的詳細(xì)介紹。網(wǎng)卡底層驅(qū)動(dòng)開發(fā)1驅(qū)動(dòng)模塊的加載module_initfn在驅(qū)動(dòng)的開發(fā)之中,大家都知道是從module_initfn開場(chǎng)的,該內(nèi)核宏允許你添加自定義的初始化函數(shù)。這里略微扯遠(yuǎn)點(diǎn),看下module_init是如何在內(nèi)核中實(shí)現(xiàn)的,展開如下:#define module_init(;x);_initcall(;x);#define _initcall&
22、;#40;fn);device_initcall(;fn);#define device_initcall(;fn);_define_initcall(;"6",fn);#define _define_initcall(;level,fn);static initcall_t _initcall_#fn _attribute_used_attribute_(;(;_section_(;".initc
23、all"level".init");););=fn雖然很長(zhǎng),其實(shí)就是做了一件事情,說明了系統(tǒng)最終調(diào)用的初始化函數(shù)為initcall_t _initcall_#fn#fn用fn代替即可,在內(nèi)核啟動(dòng)的過程中do_initcalls函數(shù)會(huì)調(diào)用該初始化函數(shù)。當(dāng)然在以上宏定義中還給出一些關(guān)于初始化函數(shù)的其它信息:_attribute_used_attribute_(;(;_section_(;".initcall"這里的_attribute_、used、_section_
24、都是GNU編譯器的保存字。_attribute_:表示屬性,也就是賦予它所修飾的變量或函數(shù)后面指定的屬性;used:表示該變量或函數(shù)代碼的執(zhí)行過程中會(huì)被用到;_section_(;".initcall":指將其所修飾的變量或函數(shù)編譯進(jìn).initcall段。那么initcall段的地址在什么地方呢?它包括在_initcall_start到_initcall_end區(qū)間里,在arch/i386/kernel/vmlinux.lds.S中找到可以找到該變量。好了,言歸正傳。接下來內(nèi)核將要調(diào)用初始化函數(shù)fn了。2初始化函數(shù)fn,在該函數(shù)中需要做的事情如下:2.1為對(duì)應(yīng)
25、的網(wǎng)絡(luò)設(shè)備例如:ether,Wlan等分配net_device構(gòu)造體alloc_netdev或是alloc_etherdev,關(guān)于這兩個(gè)函數(shù)其實(shí)很相似,后者也是直接調(diào)用了alloc_netdev最終實(shí)現(xiàn)。不同之處在于:后者使調(diào)用alloc_netdev時(shí)使用了內(nèi)核所提供的初始化函數(shù)ether_setup;前者使用的是程序員自定義的函數(shù)xxx_setupalloc_netdev的實(shí)現(xiàn)代碼如下:alloc_size=sizeof*dev+sizeof_priv+31;dev=struct net_device*kmallocalloc_size,GFP_KERNEL;ifdev=NULLprint
26、kKERN_ERR"alloc_dev:Unable to allocate device memory.n";return NULL;memsetdev,0,alloc_size;ifsizeof_privdev-priv=void*longdev+1+31&31;setupdev;strcpydev-name,mask;從代碼可以看出alloc_netdev函數(shù)間接調(diào)用了上層函數(shù)所提供的setup函數(shù)來初始化dev構(gòu)造體。到此大家都知道了初始化函數(shù)中包括的是翻開,關(guān)閉設(shè)備,傳輸函數(shù)等各個(gè)主要變量的初始化。2.2通過register_netdevdev來注冊(cè)一個(gè)已
27、經(jīng)初始化好了的net_device設(shè)備。其實(shí)注冊(cè)設(shè)備就是將dev鏈接到內(nèi)核中的netdev的鏈表之中。當(dāng)使用ifconfig來為一個(gè)網(wǎng)絡(luò)設(shè)備配置地址時(shí),內(nèi)核ioctl函數(shù)就會(huì)設(shè)置dev-flag中的IFF_UP標(biāo)志以翻開接口,當(dāng)IFF_UP設(shè)置之后,內(nèi)核就將調(diào)用open函數(shù)。3接口的翻開接口翻開函數(shù)中需要做的工作如下:3.1設(shè)置MAC地址,一般來說接口是不支持硬件地址改變的,所以就沒有必要自定義MAC地址設(shè)置函數(shù),而只需要采用默認(rèn)設(shè)置。默認(rèn)設(shè)置是在eth_setup函數(shù)中賦予的,就是將dev-set_mac_address設(shè)置為eth_mac_add,該函數(shù)首先會(huì)判斷接口是否在工作,只有不在工
28、作時(shí)才會(huì)啟用設(shè)置命令memcpy,如下所示:struct sockaddr*addr=p;ifnetif_runningdevreturn-EBUSY;memcpydev-dev_addr,addr-sa_data,dev-addr_len;3.2必要時(shí)使用端口申請(qǐng)request_region.為什么說是必要時(shí)呢?因?yàn)槎丝谏暾?qǐng)的目的就是使得進(jìn)程可以獨(dú)享IO端口訪問權(quán)限,不至于出現(xiàn)資源爭(zhēng)用。但是當(dāng)你能確定IO端口只是被單個(gè)進(jìn)程使用時(shí),就可以省去該步驟。但是為了程序的強(qiáng)健性考慮,還是加上這個(gè)函數(shù)為妙。下面簡(jiǎn)單介紹下request_region,他的調(diào)用格式如下:requset_regionstar
29、t,size,name調(diào)用該函數(shù)時(shí)時(shí)確定start-start+size地址空間是否可以使用,當(dāng)確認(rèn)可以使用之后就調(diào)用端口讀寫函數(shù)來對(duì)端口進(jìn)展訪問。一些端口讀寫函數(shù)如下:void insbunsigned port,void*addr,unsigned long count;void outsbunsigned port,void*addr,unsigned long count;讀或?qū)憦膬?nèi)存地址addr開場(chǎng)的count字節(jié).數(shù)據(jù)讀自或者寫入單個(gè)port端口.void inswunsigned port,void*addr,unsigned long count;void outswunsig
30、ned port,void*addr,unsigned long count;讀或?qū)?6-位值到一個(gè)單個(gè)16-位端口.void inslunsigned port,void*addr,unsigned long count;void outslunsigned port,void*addr,unsigned long count;讀或?qū)?2-位值到一個(gè)單個(gè)32-位端口.還補(bǔ)充一點(diǎn):start的值是在驅(qū)動(dòng)程序中賦予的,一般驅(qū)動(dòng)程序都會(huì)定義一個(gè)ion,接著通過MODULE_PARM將其輸出,這樣在用戶在通過insmod加載模塊時(shí)可以將該參數(shù)傳遞進(jìn)來。3.3中斷申請(qǐng)中斷申請(qǐng)使用的時(shí)request_irq函數(shù)。該函數(shù)的調(diào)用形式如下:int request_irqunsigned int irq,void*handlerint irq,void*dev_id,struct pt_regs*regsirq是要申請(qǐng)的硬件中斷號(hào)。在Intel平臺(tái),范圍0-15。handler是向系統(tǒng)登記的中斷處理函數(shù)。這是一個(gè)回調(diào)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- R-YNT-3708-生命科學(xué)試劑-MCE-1793
- N-Butyl-Pentedrone-hydrochloride-生命科學(xué)試劑-MCE-8255
- Homarylamine-hydrochloride-生命科學(xué)試劑-MCE-8287
- 2025年度員工股份分配與業(yè)績(jī)考核協(xié)議
- 二零二五年度離婚財(cái)產(chǎn)協(xié)議-房產(chǎn)車輛資產(chǎn)分配
- 2025年度車輛外借責(zé)任免除及事故賠償協(xié)議
- 2025年度研學(xué)旅行文化體驗(yàn)合同
- 二零二五年度炊事員餐飲業(yè)未來趨勢(shì)預(yù)測(cè)聘用合同
- 2025年度蛋糕店線上線下銷售渠道拓展合同
- 施工現(xiàn)場(chǎng)施工防生物災(zāi)害威脅制度
- 行政事業(yè)單位國(guó)有資產(chǎn)管理辦法
- 六年級(jí)口算訓(xùn)練每日100道
- 高一生物生物必修一全冊(cè)考試題帶答題紙答案
- 北師大版五年級(jí)上冊(cè)四則混合運(yùn)算100道及答案
- 人教部編版道德與法治八年級(jí)下冊(cè):6.3 《國(guó)家行政機(jī)關(guān)》說課稿1
- 2024山東能源集團(tuán)中級(jí)人才庫選拔(高頻重點(diǎn)提升專題訓(xùn)練)共500題附帶答案詳解
- 鋼鐵是怎樣煉成的讀后感作文700字
- 武漢市江夏區(qū)2022-2023學(xué)年七年級(jí)上學(xué)期期末數(shù)學(xué)試卷【帶答案】-109
- 學(xué)校物業(yè)服務(wù)合同范本專業(yè)版
- SL 288-2014 水利工程施工監(jiān)理規(guī)范
- 部編版八年級(jí)語文上冊(cè)期末考試卷
評(píng)論
0/150
提交評(píng)論