亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        /proc文件系統(tǒng)在實(shí)時(shí)系統(tǒng)RTAI中的應(yīng)用

        2007-01-01 00:00:00李東亮
        計(jì)算機(jī)時(shí)代 2007年5期

        摘要:/proc文件系統(tǒng)是一個(gè)特殊的、由軟件創(chuàng)建的文件系統(tǒng),內(nèi)核使用此文件系統(tǒng)可以向外部輸出信息。在進(jìn)行Linux和實(shí)時(shí)應(yīng)用程序開發(fā)時(shí),用戶經(jīng)常會(huì)使用內(nèi)核變量,獲取內(nèi)核信息。文章分析了利用/proe文件系統(tǒng)獲取內(nèi)核信息的方法以及/proc文件系統(tǒng)在實(shí)時(shí)系統(tǒng)RTAI中的應(yīng)用。

        關(guān)鍵詞:/proc文件系統(tǒng);Linux;內(nèi)核信息;RTAI

        0 引言

        /proc文件系統(tǒng)是Linux向用戶提供系統(tǒng)內(nèi)部參數(shù)的一個(gè)偽文件系統(tǒng),它包含許多文件,可用于監(jiān)視、調(diào)試或更改運(yùn)行中內(nèi)核的參數(shù)。對(duì)于內(nèi)核信息的獲取,一般僅使用其中的一部分文件。對(duì)這些文件執(zhí)行的讀操作,會(huì)被,proc文件系統(tǒng)定位到一個(gè)內(nèi)核函數(shù)。本文通過對(duì)Linux系統(tǒng)內(nèi)核現(xiàn)有通信機(jī)制的研究,介紹利用/proc文件系統(tǒng)輸出內(nèi)核信息的方法以及在實(shí)時(shí)系統(tǒng)RTAI中利用/proc文件系統(tǒng)控制實(shí)時(shí)任務(wù)的方法。

        1/proc文件系統(tǒng)概述

        Linux系統(tǒng)中的/proc文件系統(tǒng)是進(jìn)程文件系統(tǒng)和內(nèi)核文件系統(tǒng)組成的復(fù)合體,它將內(nèi)核數(shù)據(jù)對(duì)象化為文件形式進(jìn)行存取,通過文件系統(tǒng)接口實(shí)現(xiàn),用于輸出系統(tǒng)運(yùn)行狀態(tài);以文件系統(tǒng)的形式為操作系統(tǒng)和應(yīng)用進(jìn)程之間的通信提供了一個(gè)界面,使應(yīng)用程序能夠安全、方便地獲得系統(tǒng)當(dāng)前的運(yùn)行狀態(tài)和內(nèi)核的數(shù)據(jù)信息,并且可以修改某些系統(tǒng)的配置信息。

        /proc文件系統(tǒng)主要分成兩個(gè)部分:一部分是和進(jìn)程相關(guān)的目錄部分,在實(shí)現(xiàn)時(shí)將這部分稱為base部分;另一部分是把/proc根下面的其他目錄和文件,又分為兩部分,一是/proc下的子目錄,另一是/proc下的文件,如cpuinfo等。這三部分是通過不同的初始化函數(shù)完成初始化的。/proe目錄下的每一個(gè)文件都與內(nèi)核函數(shù)緊密相連,當(dāng)文件被讀取時(shí)內(nèi)核函數(shù)生成文件的“內(nèi)容”。/proe文件系統(tǒng)是動(dòng)態(tài)的,可以在其中創(chuàng)建自己的/proc文件,獲取所需內(nèi)核信息。

        Linux系統(tǒng)啟動(dòng)后,創(chuàng)建了由proc_dir_entry{}結(jié)構(gòu)形成的文件系統(tǒng)樹。在/proc文件系統(tǒng)中,代表各個(gè)文件節(jié)點(diǎn)的結(jié)構(gòu)是proc_dir_entry{}結(jié)構(gòu),它描述一個(gè)/proc文件系統(tǒng)中目錄結(jié)構(gòu)節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)在整個(gè)目錄結(jié)構(gòu)中或是一個(gè)文件,或是一個(gè)目錄,通過指針將大量的proc_dir_entry{}節(jié)點(diǎn)組成樹狀結(jié)構(gòu)。和一般文件系統(tǒng)不同的是,它修改的并不是硬盤上的文件,而是在系統(tǒng)啟動(dòng)之后內(nèi)存中由內(nèi)核動(dòng)態(tài)創(chuàng)建的文件。因此在系統(tǒng)關(guān)閉之后,/proc文件系統(tǒng)中的文件就不存在了。proc_dir_entry{}結(jié)構(gòu)提供了對(duì)文件內(nèi)容的讀寫所需要的函數(shù)指針,即管理著從操作系統(tǒng)的用戶空間到核心空間對(duì)文件讀寫的驅(qū)動(dòng)。每當(dāng)從用戶空間讀取,proc目錄下的文件時(shí),內(nèi)核根據(jù)讀取的文件映射到對(duì)應(yīng)的驅(qū)動(dòng)函數(shù),動(dòng)態(tài)地獲取內(nèi)核數(shù)據(jù)。除了提供讀的功能,/proe文件系統(tǒng)的部分文件還提供寫的功能,在Linux2.4系統(tǒng)中主要是針對(duì)/proc/sys目錄而做的。對(duì)/proc文件系統(tǒng)的寫操作并不是寫硬盤等硬件設(shè)備,而是動(dòng)態(tài)更改內(nèi)核中的數(shù)據(jù),達(dá)到監(jiān)視內(nèi)核運(yùn)行狀態(tài)的目的。

        2 /proc目錄下文件節(jié)點(diǎn)的讀寫操作流程(以讀為例)

        讀/proc文件系統(tǒng)中的文件,是通過層層調(diào)用,最終操作內(nèi)核變量的讀函數(shù),將內(nèi)核信息收集到字符型指針?biāo)赶虻木彌_區(qū)中。也就是說,用戶進(jìn)程通過系統(tǒng)調(diào)用read(讀文件)進(jìn)入系統(tǒng)態(tài),執(zhí)行sys_read內(nèi)核函數(shù);

        asmtinkage ssize_t sys_read(unsigned int fd,char*buf,

        size_t count)

        {…

        ssize_t ret;

        struct file*file;

        file=get(fd);

        ret=file->read(file,buf,count,file->f_pos);

        }

        可見,文件讀操作進(jìn)入到核心態(tài)后,執(zhí)行的是file結(jié)構(gòu)中函數(shù)跳轉(zhuǎn)表f_op中的read指針?biāo)傅暮瘮?shù)。

        file->f_op函數(shù)跳轉(zhuǎn)表值來源于inode結(jié)構(gòu)中的i_fop;

        在訪問文件的過程中,dentry_open函數(shù)將文件索引節(jié)點(diǎn)中函數(shù)跳轉(zhuǎn)表i_fop值賦給file結(jié)構(gòu)中的f_op。

        struct file *dentry_open(struct dentry*dentry,

        struct vfsmount *mnt,int flags)

        {struct file *f;

        struct inode *inode;

        inode=dentry->d_inode;

        f->f_op=fops_get(jnode->ffop);

        return f;

        }

        inode結(jié)構(gòu)中的i_fop值來源于proc_dir_entry中的proc_fops;

        在創(chuàng)建/proc文件系統(tǒng)中文件的inode節(jié)點(diǎn)時(shí),函數(shù)proc_get_inode將文件對(duì)應(yīng)的proc_dir_entry中的proc_fops值賦給inode結(jié)構(gòu)中的i_fop。

        struct inode *proc_get_inode(struct super_block *sb,int ino,

        struct proc_dir_entry*de)

        {struct inode *inode;

        inode=iget(sb,ino):

        inode->u.generic_ip=(void*)de;

        if(de->proc_fops)

        inode->i fop=de->proc_fops;

        return inode;

        }

        proc_dir_entry結(jié)構(gòu)中的proc_fops是proc_file_operations;

        在文件./linux/fs/proc/generic.c,proc_file_operations賦值為:

        struct file_operations proc_file_operations=

        {Ilseek:proc_file_lseek,

        read::proc_file_read,

        write:proc file write,

        };

        在創(chuàng)建文件的proc_dir_entry結(jié)構(gòu)時(shí),函數(shù)proc_register將proc_file_operations值賦給proc_dir_entry結(jié)構(gòu)中的proc_fops。

        static int proc_register(struct proc_dir_entry*dir,

        struct proc_dir_entry*dp)

        {…

        if(dp->proc_fops==NULL)

        dp->proc_fops=proc__file_operations;

        }

        proc_file_read函數(shù)執(zhí)行的是proc_dir_entry結(jié)構(gòu)中函數(shù)指針?biāo)傅暮瘮?shù)。

        static ssize_t proc_file_read(struct file*file,

        const char*buffer,size_t count,Ioff_t *ppos)

        {struct inode *inode=file->f_dentry->d_inode;

        struct proc dir entry *dp;

        dp=(struct proc_dir_entry*)->inode->u.generic_ip;

        if(!dp->write_proc)

        return EIO;

        return dp->read_proc(file,buffer,count,dp->data);

        }

        proc_dir_entry結(jié)構(gòu)中proc_read函數(shù)指針賦值是在創(chuàng)建文件的proc_dir_entry結(jié)構(gòu)時(shí)進(jìn)行的。

        文件./include/linux/proc_fs.h

        static inline struct proc_dir_entry *create_proc_read_entry(const

        char*name,mode_t mode,struct proc_dir_entry*base,

        read_proc_t*read_proc,void*data)

        {struct proc_dir_entry*res=create_proc_entry(name,mode,base);

        if(res)

        {res->read_proc=read_proc;

        res->data=data;

        }

        return res;

        }

        函數(shù)create_proc_read_entry參數(shù)表中的參數(shù)read_proc是對(duì)應(yīng)內(nèi)核變量的讀函數(shù)。

        3 使用/proc文件系統(tǒng)獲取內(nèi)核信息的方法

        3.1修改/proc文件系統(tǒng)中原有的文件

        /proc文件系統(tǒng)中,用戶進(jìn)程是直接打開/proc文件來實(shí)現(xiàn)自動(dòng)調(diào)用相應(yīng)內(nèi)核函數(shù)的。當(dāng)查看/proc目錄下的文件時(shí),這些文件會(huì)顯示出Linux系統(tǒng)內(nèi)部的一些信息。其實(shí)對(duì)它們進(jìn)行讀操作是調(diào)用了操作系統(tǒng)內(nèi)核中的一些對(duì)應(yīng)的函數(shù),這些函數(shù)及時(shí)將所取的信息反饋給用戶或應(yīng)用程序。因此在內(nèi)核中改造讀文件函數(shù),在讀/proc目錄下的對(duì)應(yīng)文件時(shí),可以得到所需的數(shù)據(jù)。

        例如對(duì)于/proc/loadavg文件來說,讀文件指針指向loadavg_read_proc()函數(shù)。該函數(shù)的作用就是當(dāng)用戶讀/proc/loadavg文件時(shí),將數(shù)組avenrum[]中積累的,即在過去1分鐘、5分鐘以及15分鐘的系統(tǒng)平均CPU負(fù)荷等統(tǒng)計(jì)信息通過spfintf()“打印”到緩沖區(qū)頁面中。我們可以把代碼加到諸如此類的文件中,由這些文件幫我們把所需的數(shù)據(jù)輸出來。修改完代碼后,重新編譯內(nèi)核即可。在這里,內(nèi)核到用戶的信息通過/proc文件系統(tǒng)來傳遞,但沒有在/proc目錄下創(chuàng)建新文件,而是借用Linux內(nèi)核代碼,從而得到所需的數(shù)據(jù)。這樣做的好處是減少對(duì)內(nèi)核的修改量,缺點(diǎn)是需重新編譯內(nèi)核。

        3.2在/proc目錄下新建文件

        3.2.1創(chuàng)建新/proc文件,利用read_proc操作

        新創(chuàng)建的/proc文件要想被訪問到,首先要在,proc文件系統(tǒng)中創(chuàng)建一個(gè)入口,這可以通過函數(shù)creat_proc_read_entry()來實(shí)現(xiàn)。

        從上面分析可以看出,/proc目錄下的文件只提供了讀寫操作,即只實(shí)現(xiàn)了proc dir entry{}結(jié)構(gòu)中對(duì)應(yīng)的read_proc操作,而沒有提供該結(jié)構(gòu)中的文件操作函數(shù)集,此時(shí)使用的是缺省的文件操作函數(shù)集。文件操作函數(shù)集struct file_operationsproc_file_operations中read對(duì)應(yīng)函數(shù)proc_file_read(),該函數(shù)的實(shí)現(xiàn)依賴于proc_dir_entry{}結(jié)構(gòu)中的read_proc函數(shù)。因此若注冊自己的/proc文件,在沒有設(shè)置proc_fops文件操作函數(shù)集時(shí),需實(shí)現(xiàn)read_proc(),否則缺省的proc file read()函數(shù)將做不了任何工作。所以,當(dāng)創(chuàng)建只讀的/proc文件時(shí),程序中必須實(shí)現(xiàn)proc_dir_entry{}結(jié)構(gòu)中的read_proc()函數(shù)。

        read_proc()函數(shù)的特點(diǎn)是:/proc文件系統(tǒng)首先通過sprintf()函數(shù)將要獲取的參數(shù)轉(zhuǎn)換成字符串寫入內(nèi)核中臨時(shí)分配的一個(gè)空頁,然后再將該頁用copy_to_user()送到用戶空間,最后釋放該頁。實(shí)際上,大部分內(nèi)核參數(shù)都是整型或長整型的。/proc文件系統(tǒng)將內(nèi)核數(shù)據(jù)轉(zhuǎn)換成字符串是為了方便用戶閱讀。

        3.2.2創(chuàng)建新/proc文件,使用文件操作函數(shù)集

        創(chuàng)建/proc文件的方法與創(chuàng)建字符設(shè)備文件的方法非常相似。首先創(chuàng)建一個(gè)proc_dir_entry{}結(jié)構(gòu),該結(jié)構(gòu)包含了/proc文件需要的所有信息。然后通過create_proc_entry()函數(shù)向內(nèi)核注冊這個(gè)結(jié)構(gòu),而remove_proc_entry()函數(shù)將取消它的注冊。proc_dir_entry{)結(jié)構(gòu)中描述了/proc文件的全部信息。這里最重要的是該結(jié)構(gòu)中的proc_fops項(xiàng),這是一個(gè)指向file_operations結(jié)構(gòu)的指針,可以把對(duì)/proc文件的讀寫等操作放在這個(gè)結(jié)構(gòu)中,用以實(shí)現(xiàn)對(duì)/proc文件的讀寫等功能。代碼如下:

        int ssize_t procread(struct file*file,char*buf,aize_t len,loff_t*offset); static ssize_t procwrite(struct file*file,char*buf,aize_t Ien,

        loff_t *offset);

        static struct file_operations procfop=

        {read:procread,

        write:procwrite,

        };

        static int init_routine(void)

        {struct proc_dir_entry *entry;

        entry=create_proc_entry(\"test\",S_IRUSRIS_IwUSR,NULL);

        entry->proc_fops=procfop;

        rutern;

        }

        4 /proc文件系統(tǒng)在RTAI中的應(yīng)用

        RTAI是實(shí)時(shí)應(yīng)用接口Real-Time Application Interface的縮寫,提供了一個(gè)基于Linux的實(shí)時(shí)方案。RTAI利用Linux提供的可加載內(nèi)核模塊機(jī)制來提供服務(wù),完成實(shí)時(shí)功能。模塊經(jīng)過加載,成為內(nèi)核的一部分,但是并沒有被編譯到內(nèi)核里面去。它們被分別編譯并連接成一組目標(biāo)文件,這些文件能被插入到正在運(yùn)行的內(nèi)核,或從正在運(yùn)行的內(nèi)核中移走。RTAI提供的主要模塊有RTAI主模塊、RTAI調(diào)度器模塊、RTAI命名管道fifo模塊及RTAI共享內(nèi)存模塊等。

        4.1利用/proc文件系統(tǒng)用戶獲取實(shí)時(shí)內(nèi)核的信息

        RTAI主模塊是RTAI的核心模塊,它是其他模塊的基礎(chǔ)。要加載其他模塊,首先必須加載這個(gè)模塊,沒有它,任何實(shí)時(shí)任務(wù)都不能完成。當(dāng)這個(gè)模塊被加載后,在/proc目錄下會(huì)自動(dòng)生成一個(gè)rtai子目錄,在其他模塊如rtai_sched、rtai_fifos等模塊加載后,rtai子目錄下又有rtai、scheduler、fifos等文件??梢酝ㄟ^命令cat讀取實(shí)時(shí)系統(tǒng)RTAI的有關(guān)信息,主要由…/rtai-x.x.x/arch/i386/rtai.c文件中的函數(shù)實(shí)現(xiàn)其功能:

        struct proc dir entry *rtai_proc_root=NULL;

        static int rtai_proc_register(void)

        {…

        rtai_proc_root=create_proc_entry(“rtai”,S_IFDIR,0);

        ent=create_proc_entry(“rtai”,S_IFREGIS_IRUGOIS_IwUSR,

        rtai_proc_root);

        ent->read proc=rtai_read_rtai;

        }

        4.2 利用/proc文件系統(tǒng)控制實(shí)時(shí)任務(wù)

        利用/proc文件系統(tǒng)write_proc函數(shù)可以修改內(nèi)核數(shù)據(jù),控制實(shí)時(shí)任務(wù)。首先使用create_proc_entry函數(shù)在/proc文件系統(tǒng)中創(chuàng)建一個(gè)虛擬文件,這個(gè)函數(shù)可以接收一個(gè)文件名、一組權(quán)限和這個(gè)文件在,proc文件系統(tǒng)中出現(xiàn)的位置。create_proc_entry的返回值是一個(gè)proc_dir_entry指針(或者為NULL,說明在create時(shí)發(fā)生了錯(cuò)誤)。然后就可以使用這個(gè)返回的指針來配置這個(gè)虛擬文件的其他參數(shù),例如在對(duì)該虛擬文件執(zhí)行寫操作時(shí)應(yīng)該調(diào)用的write_proc函數(shù)。通過/proc文件的write_proc函數(shù),修改內(nèi)核中可以控制實(shí)時(shí)任務(wù)執(zhí)行的變量,從而達(dá)到控制實(shí)時(shí)任務(wù)的目的。

        5 結(jié)束語

        Linux、RTAI都是開放源代碼的,我們可以采取任何能想到的方法對(duì)它進(jìn)行分析和改進(jìn),這是開放源代碼提供給我們研究和學(xué)習(xí)的便利。但也應(yīng)注意避免向內(nèi)核中帶入一些難以發(fā)現(xiàn)的錯(cuò)誤。本文所提出的利用/proc文件實(shí)現(xiàn)實(shí)時(shí)系統(tǒng)監(jiān)控和實(shí)時(shí)任務(wù)控制的方法,簡單易行,用于開發(fā)應(yīng)用程序非常方便。

        注:本文中所涉及到的圖表、注解、公式等內(nèi)容請以PDF格式閱讀原文。

        无套内射无矿码免费看黄| 国产精品中文字幕日韩精品| 亚洲熟女少妇一区二区三区青久久| 国产在热线精品视频| 免费a级毛片无码无遮挡| 青草网在线观看| 国产在线观看免费不卡视频| 亚洲天堂丰满人妻av| 激情综合色综合啪啪五月丁香| 亚洲国产婷婷六月丁香| 极品美女aⅴ在线观看| 久久精品免费无码区| 亚洲天堂一二三四区在线| 亚洲av无码国产精品色午夜软件 | 国产午夜毛片v一区二区三区| 国产露脸精品产三级国产av| 亚洲综合无码| 老汉tv永久视频福利在线观看| 无码熟妇人妻AV不卡| 国产三级国产精品国产专播| 亚洲人成影院在线无码按摩店| 少妇无码av无码一区| 精品国产高清一区二区广区| 国产精品丝袜美腿诱惑| 日本高清在线一区二区三区 | 久久精品人人做人人爱爱| 久久人妻少妇嫩草av蜜桃| 精品的一区二区三区| 国产美腿丝袜一区二区| 国模无码一区二区三区| 国产午夜精品一区二区三区不卡| 日本香蕉久久一区二区视频| 久久人妻少妇嫩草av蜜桃| 97久久精品人妻人人搡人人玩| 狠狠久久久久综合网| 探花国产精品三级在线播放| 少妇被粗大猛进进出出男女片| 中文天堂国产最新| 97视频在线观看免费| 午夜宅男成人影院香蕉狠狠爱| 中文人妻av久久人妻水蜜桃|