freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

linux系統(tǒng)內(nèi)核空間與用戶空間通信的實(shí)現(xiàn)與分析-展示頁(yè)

2025-07-04 22:00本頁(yè)面
  

【正文】 tlink 套接字在中斷過(guò)程和用戶空間通信的應(yīng)用上作詳細(xì)的說(shuō)明,使得很多用戶對(duì)此只有一個(gè)模糊的概念。這樣的通信模型并不令人滿意,因?yàn)閮?nèi)核線程是和其他用戶態(tài)進(jìn)程競(jìng)爭(zhēng)CPU接收數(shù)據(jù)的,效率很低,這樣中斷過(guò)程便不能實(shí)時(shí)地接收來(lái)自用戶空間的數(shù)據(jù)。圖【2】因?yàn)橹袛噙^(guò)程不可能無(wú)休止地等待用戶態(tài)進(jìn)程發(fā)送數(shù)據(jù),所以要通過(guò)一個(gè)內(nèi)核線程來(lái)接收用戶空間的數(shù)據(jù),再通過(guò)臨界區(qū)傳給中斷過(guò)程。但硬、軟中斷中也有一套同步機(jī)制自旋鎖(spinlock),可以通過(guò)自旋鎖來(lái)實(shí)現(xiàn)中斷環(huán)境與中斷環(huán)境,中斷環(huán)境與內(nèi)核線程的同步,而內(nèi)核線程是運(yùn)行在有進(jìn)程上下文環(huán)境中的,這樣便可以在內(nèi)核線程中使用套接字或消息隊(duì)列來(lái)取得用戶空間的數(shù)據(jù),然后再將數(shù)據(jù)通過(guò)臨界區(qū)傳遞給中斷過(guò)程。 3.2 硬、軟中斷環(huán)境比起用戶上下文環(huán)境,硬中斷和軟中斷環(huán)境與用戶態(tài)進(jìn)程無(wú)絲毫關(guān)系,而且運(yùn)行過(guò)程不能阻塞。整個(gè)示例演示了由一個(gè)用戶態(tài)進(jìn)程向用戶上下文環(huán)境發(fā)送一個(gè)字符串,內(nèi)容為a message from userspace\n。 是內(nèi)核模塊的源代碼。 ,內(nèi)核模塊注冊(cè)了一組設(shè)置套接字選項(xiàng)的函數(shù)使得用戶空間進(jìn)程可以調(diào)用此組函數(shù)對(duì)內(nèi)核態(tài)數(shù)據(jù)進(jìn)行讀寫。此類方法的工作原理路如圖【1】。但這些方法的數(shù)據(jù)傳輸效率較低,Linux 內(nèi)核提供 copy_from_user()/copy_to_user() 函數(shù)來(lái)實(shí)現(xiàn)內(nèi)核態(tài)與用戶態(tài)數(shù)據(jù)的拷貝,但這兩個(gè)函數(shù)會(huì)引發(fā)阻塞,所以不能用在硬、軟中斷中。套接字在硬、軟中斷中無(wú)法無(wú)阻塞地接收數(shù)據(jù)。信號(hào)量無(wú)法介于內(nèi)核態(tài)和用戶態(tài)使用。表【2】通信方法無(wú)法介于內(nèi)核態(tài)與用戶態(tài)的原因管道(不包括命名管道)局限于父子進(jìn)程間的通信。 Linux 傳統(tǒng)的進(jìn)程間通信有很多,如各類管道、消息隊(duì)列、內(nèi)存共享、信號(hào)量等等。硬中斷和軟中斷環(huán)境硬中斷或軟中斷過(guò)程中代碼的運(yùn)行環(huán)境,如 IP 數(shù)據(jù)報(bào)的接收代碼的運(yùn)行環(huán)境,網(wǎng)絡(luò)設(shè)備的驅(qū)動(dòng)程序等。表【1】?jī)?nèi)核態(tài)環(huán)境介紹局限性用戶上下文內(nèi)核態(tài)代碼的運(yùn)行與一用戶空間進(jìn)程相關(guān),如系統(tǒng)調(diào)用中代碼的運(yùn)行環(huán)境。但三種環(huán)境的局限性分兩種,因?yàn)檐浿袛喹h(huán)境只是硬中斷環(huán)境的延續(xù)。Linux 內(nèi)核模塊是一段可以動(dòng)態(tài)在內(nèi)核裝載和卸載的代碼,裝載進(jìn)內(nèi)核的代碼便立即在內(nèi)核中工作起來(lái)。其中除了【4】,其他狀態(tài)只可以被在其之上的狀態(tài)搶占?!?】 運(yùn)行一個(gè)用戶態(tài)進(jìn)程。【2】 在處理一個(gè)軟中斷,如 softirq、tasklet 和 bh。在 Linux 的內(nèi)核發(fā)行版本中沒有對(duì)該類通信方法的詳細(xì)介紹,也沒有其他文章對(duì)此進(jìn)行總結(jié),所以本文將列舉幾種內(nèi)核態(tài)與用戶態(tài)進(jìn)程通信的方法并詳細(xì)分析它們的實(shí)現(xiàn)和適用環(huán)境。當(dāng)我們需要做這些的時(shí)候,就需要將在內(nèi)核態(tài)采集到的數(shù)據(jù)傳送到用戶態(tài)的一個(gè)或多個(gè)進(jìn)程中進(jìn)行處理。目前有很多中低端用戶使用的網(wǎng)絡(luò)設(shè)備的操作系統(tǒng)是從標(biāo)準(zhǔn) Linux 改進(jìn)而來(lái)的,這也說(shuō)明了有越來(lái)越多的人正在加入到 Linux 內(nèi)核開發(fā)團(tuán)體中。本文總結(jié)并比較了幾種內(nèi)核態(tài)與用戶態(tài)進(jìn)程通信的實(shí)現(xiàn)方法,并推薦使用 netlink 套接字實(shí)現(xiàn)中斷環(huán)境與用戶態(tài)進(jìn)程通信。級(jí)別: 初級(jí)陳鑫 (), 自由軟件愛好者, 南京郵電學(xué)院電子工程系2004 年 7 月 01 日多數(shù)的 Linux 內(nèi)核態(tài)程序都需要和用戶空間的進(jìn)程交換數(shù)據(jù),但 Linux 內(nèi)核態(tài)無(wú)法對(duì)傳統(tǒng)的 Linux 進(jìn)程間同步和通信的方法提供足夠的支持。1 引言Linux 是一個(gè)源碼開放的操作系統(tǒng),無(wú)論是普通用戶還是企業(yè)用戶都可以編寫自己的內(nèi)核代碼,再加上對(duì)標(biāo)準(zhǔn)內(nèi)核的裁剪從而制作出適合自己的操作系統(tǒng)。一個(gè)或多個(gè)內(nèi)核模塊的實(shí)現(xiàn)并不能滿足一般 Linux 系統(tǒng)軟件的需要,因?yàn)閮?nèi)核的局限性太大,如不能在終端上打印,不能做大延時(shí)的處理等等。這樣,內(nèi)核態(tài)與用戶空間進(jìn)程通信的方法就顯得尤為重要。2 Linux 內(nèi)核模塊的運(yùn)行環(huán)境與傳統(tǒng)進(jìn)程間通信在一臺(tái)運(yùn)行 Linux 的計(jì)算機(jī)中,CPU 在任何時(shí)候只會(huì)有如下四種狀態(tài):【1】 在處理一個(gè)硬中斷?!?】 運(yùn)行于內(nèi)核態(tài),但有進(jìn)程上下文,即與一個(gè)進(jìn)程相關(guān)。其中,【1】、【2】和【3】是運(yùn)行于內(nèi)核空間的,而【4】是在用戶空間。比如,軟中斷只可以被硬中斷搶占。Linux 內(nèi)核代碼的運(yùn)行環(huán)境有三種:用戶上下文環(huán)境、硬中斷環(huán)境和軟中斷環(huán)境。比較如表【1】。不可直接將本地變量傳遞給用戶態(tài)的內(nèi)存區(qū),因?yàn)閮?nèi)核態(tài)和用戶態(tài)的內(nèi)存映射機(jī)制不同。不可直接向用戶態(tài)內(nèi)存區(qū)傳遞數(shù)據(jù); 代碼在運(yùn)行過(guò)程中不可阻塞。但它們都無(wú)法介于內(nèi)核態(tài)與用戶態(tài)使用,原因如表【2】。消息隊(duì)列在硬、軟中斷中無(wú)法無(wú)阻塞地接收數(shù)據(jù)。內(nèi)存共享需要信號(hào)量輔助,而信號(hào)量又無(wú)法使用?;仨?yè)首3 Linux內(nèi)核態(tài)與用戶態(tài)進(jìn)程通信方法的提出與實(shí)現(xiàn)3.1 用戶上下文環(huán)境運(yùn)行在用戶上下文環(huán)境中的代碼是可以阻塞的,這樣,便可以使用消息隊(duì)列和 UNIX 域套接字來(lái)實(shí)現(xiàn)內(nèi)核態(tài)與用戶態(tài)的通信。一般將這兩個(gè)特殊拷貝函數(shù)用在類似于系統(tǒng)調(diào)用一類的函數(shù)中,此類函數(shù)在使用中往往穿梭于內(nèi)核態(tài)與用戶態(tài)。圖【1】其中相關(guān)的系統(tǒng)調(diào)用是需要用戶自行編寫并載入內(nèi)核。源碼包含三個(gè)文件, 是通用頭文件,定義了用戶態(tài)和內(nèi)核態(tài)都要用到的宏。 是用戶態(tài)進(jìn)程的源代碼。然后再由用戶上下文環(huán)境向用戶態(tài)進(jìn)程發(fā)送一個(gè)字符串,內(nèi)容為a message from kernel\n。3.2.1 使用一般進(jìn)程間通信的方法 我們無(wú)法直接使用傳統(tǒng)的進(jìn)程間通信的方法實(shí)現(xiàn)?;舅悸啡鐖D【2】。中斷過(guò)程向用戶空間的數(shù)據(jù)發(fā)送必須是無(wú)阻塞的。3.2.2 netlink 套接字 在 Linux 版以后版本的內(nèi)核中,幾乎全部的中斷過(guò)程與用戶態(tài)進(jìn)程的通信都是使用 netlink 套接字實(shí)現(xiàn)的,同時(shí)還使用 netlink 實(shí)現(xiàn)了 ip queue 工具,但 ip queue 的使用有其局限性,不能自由地用于各種中斷過(guò)程。netlink 套接字的通信依據(jù)是一個(gè)對(duì)應(yīng)于進(jìn)程的標(biāo)識(shí),一般定為該進(jìn)程的 ID。當(dāng)使用 netlink 套接字進(jìn)行通信,通信的雙方都是用戶態(tài)進(jìn)程,則使用方法類似于消息隊(duì)列。netlink 套接字的最大特點(diǎn)是對(duì)中斷過(guò)程的支持,它在內(nèi)核空間接收用戶空間數(shù)據(jù)時(shí)不再需要用戶自行啟動(dòng)一個(gè)內(nèi)核線程,而是通過(guò)另一個(gè)軟中斷調(diào)用用戶事先指定的接收函數(shù)。圖【3】很明顯,這里使用了軟中斷而不是內(nèi)核線程來(lái)接收數(shù)據(jù),這樣就可以保證數(shù)據(jù)接收的實(shí)時(shí)性。圖【4】是 netlink 套接字實(shí)現(xiàn)此類通信時(shí)創(chuàng)建的過(guò)程。示例實(shí)現(xiàn)了從 netfilter 的 NF_IP_PRE_ROUTING 點(diǎn)截獲的 ICMP 數(shù)據(jù)報(bào),在將數(shù)據(jù)報(bào)的相關(guān)信息傳遞到一個(gè)用戶態(tài)進(jìn)程,由用戶態(tài)進(jìn)程將信息打印在終端上。內(nèi)核模塊代碼(分段詳解): (一)模塊初始化與卸載static struct sock *nlfd。 rwlock_t lock。/*掛接在 netfilter 框架的 NF_IP_PRE_ROUTING 點(diǎn)上的函數(shù)為 get_icmp()*/static struct nf_hook_ops imp2_ops ={ .hook = get_icmp, /*netfilter 鉤子函數(shù)*/ .pf = PF_INET, .hooknum = NF_IP_PRE_ROUTING, .priority = NF_IP_PRI_FILTER 1,}。)。 if(!nlfd) { printk(can not create a netlink socket\n)。 } /*向 netfilter 的 NF_IP_PRE_ROUTING 點(diǎn)掛接函數(shù)*/ return nf_register_hook(amp。}static void __exit fini(void){ if(nlfd) { sock_release(nlfdsocket)。imp2_ops)。module_exit(fini)。卸載時(shí)釋放套接字所占的資源并注銷之前在 netfilter 上掛接的函數(shù)。01: static void kernel_receive(struct sock *sk, int len)02: {03: do04: {05: struct sk_buff *skb。receive_sem))07: return。skreceive_queue)) != NULL)10: {11: {12: struct nlmsghdr *nlh = NULL。16: if((nlhnlmsg_len = sizeof(struct nlmsghdr))17: amp。 (skblen = nlhnlmsg_len))18: {19: if(nlhnlmsg_type == IMP2_U_PID)20: {21: write_lock_bh(amp。22: = nlhnlmsg_pid。)。)。29: write_unlock_bh(amp。30: }31: }32: }33: }34: kfree_skb(skb)。receive_sem)。amp。38: }如果讀者看過(guò) 或 (二)中的 03~18 和 31~38 是 netlink socket 在內(nèi)核空間接收數(shù)據(jù)的框架。在這里筆者使用了自己定義的消息類型:IMP2_U_PID(消息為用戶空間進(jìn)程的ID),IMP2_CLOSE(用戶空間進(jìn)程關(guān)閉)。kernel_receive() 函數(shù)的運(yùn)行在軟中斷環(huán)境。 struct packet_info info。)。)。 /*記錄源地址*/ = iphdaddr。info)。)。}(四)發(fā)送數(shù)據(jù)static int send_to_user(struct packet_info *info){ int ret。 unsigned char *old_tail。 struct nlmsghdr *nlh。 size = NLMSG_SPACE(sizeof(*info))。 old_tail = skbtail。 packet = NLMSG_DATA(nlh)。 /*傳輸?shù)接脩艨臻g的數(shù)據(jù)*/ packetsrc = infosrc。 /*計(jì)算經(jīng)過(guò)字節(jié)對(duì)其后的數(shù)據(jù)實(shí)際長(zhǎng)度*/ nlhnlmsg_len = skbtail old_tail。 read_lock_bh(amp。 ret = netlink_unicast(nlfd, skb, , MSG_DONTWAIT)。)。 nlmsg_failure: /*若發(fā)送失敗,則撤銷套接字緩存*/ if(skb) kfree_skb(skb)。}片斷(四)中所使用的宏參考如下:/*字節(jié)對(duì)齊*/define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO1) amp。 \ __nlmsg_put(skb, pid, seq, type, len)。 int size = NLMSG_LENGTH(len)。 nlhnlmsg_type = type。 nlhnlmsg_flags = 0。 nlhnlmsg_seq = seq。}/*跳過(guò)報(bào)頭取實(shí)際數(shù)據(jù)*/define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))/*取 netlink 控制字段*/define NETLINK_CB(skb) (*(struct netlink_skb_parms*)amp。再運(yùn)行編譯好的 imp2_u 命令,此時(shí)就會(huì)顯示出本機(jī)當(dāng)前接收的 ICMP 數(shù)據(jù)報(bào)的源地址和目的地址?;仨?yè)首4 總結(jié)本文從內(nèi)核態(tài)代碼的不同運(yùn)行環(huán)境來(lái)實(shí)現(xiàn)不同方法的內(nèi)核空間與用戶空間的通信,并分析了它們的實(shí)際效果。參考資料 ; 本文是該系列文章的第一篇,它介紹了內(nèi)核啟動(dòng)參數(shù)、模塊參數(shù)與sysfs、sysctl、系統(tǒng)調(diào)用和netlink,并結(jié)合給出的例子程序詳細(xì)地說(shuō)明了它們?nèi)绾问褂?。回?yè)首二、內(nèi)核啟動(dòng)參數(shù)Linux 提供了一種通過(guò) bootloader 向其傳輸啟動(dòng)參數(shù)的功能,內(nèi)核開發(fā)者可以通過(guò)這種方式來(lái)向內(nèi)核傳輸數(shù)據(jù),從而控制內(nèi)核啟動(dòng)行為。內(nèi)核為整數(shù)參數(shù)值的分析提供了函數(shù) get_option 和 get_options,前者用于分析參數(shù)值為一個(gè)整數(shù)的情況,而后者用于分析參數(shù)值為逗號(hào)分割的一系列整數(shù)的情況,對(duì)于參數(shù)值為字符串的情況,需要開發(fā)者自定義相應(yīng)的分析函數(shù)。該程序列舉了參數(shù)為一個(gè)整數(shù)、逗號(hào)分割的整數(shù)串以及字符串三種情況,讀者要想測(cè)試該程序,需要把該程序拷貝到要使用的內(nèi)核的源碼目錄樹的一個(gè)目錄下,為了避免與內(nèi)核其他部分混淆,作者建議在內(nèi)核源碼樹的根目錄下創(chuàng)建一個(gè)新目錄,如 examples,然后把該程序拷貝到 examples 目錄下并重新命名為 ,并且為該目錄創(chuàng)建一個(gè) Makefile 文件:objy = Makefile
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評(píng)公示相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1