生活随笔
收集整理的這篇文章主要介紹了
seq_file机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在老版本的Linux內核中,proc文件系統有一個缺陷:如果輸出內容大于1個內存頁,需要多次讀,因此處理起來很難。另外,如果輸出內容太大,速度會比較慢。在2.6內核中,由于大量使用了seq_file功能,使得內核輸出大文件信息更容易。使用seq_file需要包含頭文件linux/seq_file.h,并定義一個seq_operations結構:
struct?seq_operations?{ ?????????void?*?(*start)?(struct?seq_file?*m,?loff_t?*pos);//?指定seq_file文件的讀開始位置 ?????????void?(*stop)?(struct?seq_file?*m,?void?*v);//關閉seq_file ?????????//?把seq_file文件的當前讀位置移動到下一個讀位置 ?????????void?*?(*next)?(struct?seq_file?*m,?void?*v,?loff_t?*pos); ?????????int?(*show)?(struct?seq_file?*m,?void?*v);//格式化輸出 ?}; ?
seq_file的常用操作接口如下:
int?seq_open(struct?file?*,?const?struct?seq_operations?*);//打開 ?ssize_t?seq_read(struct?file?*,?char?__user?*,?size_t,?loff_t?*);//讀 ?loff_t?seq_lseek(struct?file?*,?loff_t,?int);//定位 ?int?seq_release(struct?inode?*,?struct?file?*);//釋放 ?int?seq_escape(struct?seq_file?*,?const?char?*,?const?char?*);//寫緩沖,忽略某些字符 ?int?seq_putc(struct?seq_file?*m,?char?c);//?把一個字符輸出到seq_file文件 ?int?seq_puts(struct?seq_file?*m,?const?char?*s);//?把一個字符串輸出到seq_file文件 ?
下面以cpuinfo為例說明seq_file在proc中的使用。
void?create_seq_entry(char?*name,?mode_t?mode,?const?struct?file_operations?*f) ?{ ?????struct?proc_dir_entry?*entry; ?????entry?=?create_proc_entry(name,?mode,?NULL); ?????if?(entry) ?????????entry->proc_fops?=?f; ?} ?void?__init?proc_misc_init(void) ?{ ?????… ?????create_seq_entry("cpuinfo",?0,?&proc_cpuinfo_operations);?//創建/proc目錄 ?} ?
定義proc_cpuinfo_operations:
static?const?struct?file_operations?proc_cpuinfo_operations?=?{ ?????.open???=?cpuinfo_open, ?????.read???????=?seq_read, ?????.llseek?=?seq_lseek, ?????.release????=?seq_release, ?}; ?
接下來看cpuinfo_open:
static?int?cpuinfo_open(struct?inode?*inode,?struct?file?*file) ?{ ?????return?seq_open(file,?&cpuinfo_op); ?} ?
cpuinfo_op是與硬件平臺相關的。ARM的cpuinfo_op在/arc/arm/kernel/setup.c中:
struct?seq_operations?cpuinfo_op?=?{ ?????.start??=?c_start, ?????.next???=?c_next, ?????.stop???=?c_stop, ?????.show=?c_show?}; ?
cpuinfo_op就是實際上對/proc/ cpuinfo進行修改的操作接口,其中最重要的是c_show:
static?int?c_show(struct?seq_file?*m,?void?*v) ?{ ?????int?i; ?????seq_printf(m,?"Processor\t:?%s?rev?%d?(%s)\n", ????????????cpu_name,?(int)processor_id?&?15,?elf_platform); ?#if?defined(CONFIG_SMP)//針對多處理器 ?????for_each_online_cpu(i)?{ ?????????seq_printf(m,?"processor\t:?%d\n",?i); ?????????seq_printf(m,?"BogoMIPS\t:?%lu.%02lu\n\n", ????????????????per_cpu(cpu_data,?i).loops_per_jiffy?/?(500000UL/HZ), ????????????????(per_cpu(cpu_data,?i).loops_per_jiffy?/?(5000UL/HZ))?%?100); ?????} ?#else?/*?CONFIG_SMP?*/ ?????seq_printf(m,?"BogoMIPS\t:?%lu.%02lu\n", ????????????loops_per_jiffy?/?(500000/HZ), ????????????(loops_per_jiffy?/?(5000/HZ))?%?100); ?#endif ?????seq_puts(m,?"Features\t:?"); ?????for?(i?=?0;?hwcap_str[i];?i++) ?????????if?(elf_hwcap?&?(1?<<?i)) ?????????????seq_printf(m,?"%s?",?hwcap_str[i]); ?????seq_printf(m,?"\nCPU?implementer\t:?0x%02x\n",?processor_id?>>?24); ?????seq_printf(m,?"CPU?architecture:?%s\n",?proc_arch[cpu_architecture()]); ?????if?((processor_id?&?0x0008f000)?==?0x00000000)?{/*?pre-ARM7?*/ ?????????seq_printf(m,?"CPU?part\t:?%07x\n",?processor_id?>>?4); ?????}?else?{ ?????????if?((processor_id?&?0x0008f000)?==?0x00007000)?{/*?ARM7?*/ ?????????????seq_printf(m,?"CPU?variant\t:?0x%02x\n", ????????????????????(processor_id?>>?16)?&?127); ?????????}?else?{/*?ARM7以上的CPU?*/ ?????????????seq_printf(m,?"CPU?variant\t:?0x%x\n", ????????????????????(processor_id?>>?20)?&?15); ?????????} ?????????seq_printf(m,?"CPU?part\t:?0x%03x\n",(processor_id?>>?4)?&?0xfff); ?????} ?????seq_printf(m,?"CPU?revision\t:?%d\n",?processor_id?&?15); ?????{ ?????????unsigned?int?cache_info?=?read_cpuid(CPUID_CACHETYPE); ?????????if?(cache_info?!=?processor_id)?{ ?????????????seq_printf(m,?"Cache?type\t:?%s\n" ???????????????????????"Cache?clean\t:?%s\n" ???????????????????????"Cache?lockdown\t:?%s\n" ???????????????????????"Cache?format\t:?%s\n", ????????????????????cache_types[CACHE_TYPE(cache_info)], ????????????????????cache_clean[CACHE_TYPE(cache_info)], ????????????????????cache_lockdown[CACHE_TYPE(cache_info)], ????????????????????CACHE_S(cache_info)???"Harvard"?:?"Unified"); ?????????????if?(CACHE_S(cache_info))?{ ?????????????????c_show_cache(m,?"I",?CACHE_ISIZE(cache_info)); ?????????????????c_show_cache(m,?"D",?CACHE_DSIZE(cache_info)); ?????????????}?else?{ ?????????????????c_show_cache(m,?"Cache",?CACHE_ISIZE(cache_info)); ?????????????} ?????????} ?????} ?????seq_puts(m,?"\n"); ?????seq_printf(m,?"Hardware\t:?%s\n",?machine_name); ?????seq_printf(m,?"Revision\t:?%04x\n",?system_rev); ?????seq_printf(m,?"Serial\t\t:?%08x%08x\n",system_serial_high,?system_serial_low); ?????return?0; ?} ?
總結
以上是生活随笔為你收集整理的seq_file机制的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。