在老版本的Linux内核中,proc文件系统有一个缺陷:如果输出内容大于1个内存页,需要多次读,因此处理起来很难。另外,如果输出内容太大,速度会比较慢。在2.6内核中,由于大量使用了seq_file功能,使得内核输出大文件信息更容易。使用seq_file需要包含头文件linux/seq_file.h,并定义一个seq_operations结构:

  1. struct seq_operations {
  2. void * (*start) (struct seq_file *m, loff_t *pos);// 指定seq_file文件的读开始位置
  3. void (*stop) (struct seq_file *m, void *v);//关闭seq_file
  4. // 把seq_file文件的当前读位置移动到下一个读位置
  5. void * (*next) (struct seq_file *m, void *v, loff_t *pos);
  6. int (*show) (struct seq_file *m, void *v);//格式化输出
  7. };

seq_file的常用操作接口如下:

  1. int seq_open(struct file *, const struct seq_operations *);//打开
  2. ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);//读
  3. loff_t seq_lseek(struct file *, loff_t, int);//定位
  4. int seq_release(struct inode *, struct file *);//释放
  5. int seq_escape(struct seq_file *, const char *, const char *);//写缓冲,忽略某些字符
  6. int seq_putc(struct seq_file *m, char c);// 把一个字符输出到seq_file文件
  7. int seq_puts(struct seq_file *m, const char *s);// 把一个字符串输出到seq_file文件

下面以cpuinfo为例说明seq_file在proc中的使用。

  1. void create_seq_entry(char *name, mode_t mode, const struct file_operations *f)
  2. {
  3. struct proc_dir_entry *entry;
  4. entry = create_proc_entry(name, mode, NULL);
  5. if (entry)
  6. entry->proc_fops = f;
  7. }
  8. void __init proc_misc_init(void)
  9. {
  10. create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); //创建/proc目录
  11. }

定义proc_cpuinfo_operations:

  1. static const struct file_operations proc_cpuinfo_operations = {
  2. .open   = cpuinfo_open,
  3. .read       = seq_read,
  4. .llseek = seq_lseek,
  5. .release    = seq_release,
  6. };

接下来看cpuinfo_open:

  1. static int cpuinfo_open(struct inode *inode, struct file *file)
  2. {
  3. return seq_open(file, &cpuinfo_op);
  4. }

cpuinfo_op是与硬件平台相关的。ARM的cpuinfo_op在/arc/arm/kernel/setup.c中:

  1. struct seq_operations cpuinfo_op = {
  2. .start  = c_start,
  3. .next   = c_next,
  4. .stop   = c_stop,
  5. .show= c_show
  6. };

cpuinfo_op就是实际上对/proc/ cpuinfo进行修改的操作接口,其中最重要的是c_show:

  1. static int c_show(struct seq_file *m, void *v)
  2. {
  3. int i;
  4. seq_printf(m, "Processor\t: %s rev %d (%s)\n",
  5. cpu_name, (int)processor_id & 15, elf_platform);
  6. #if defined(CONFIG_SMP)//针对多处理器
  7. for_each_online_cpu(i) {
  8. seq_printf(m, "processor\t: %d\n", i);
  9. seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
  10. per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
  11. (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
  12. }
  13. #else /* CONFIG_SMP */
  14. seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
  15. loops_per_jiffy / (500000/HZ),
  16. (loops_per_jiffy / (5000/HZ)) % 100);
  17. #endif
  18. seq_puts(m, "Features\t: ");
  19. for (i = 0; hwcap_str[i]; i++)
  20. if (elf_hwcap & (1 << i))
  21. seq_printf(m, "%s ", hwcap_str[i]);
  22. seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
  23. seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
  24. if ((processor_id & 0x0008f000) == 0x00000000) {/* pre-ARM7 */
  25. seq_printf(m, "CPU part\t: %07x\n", processor_id >> 4);
  26. } else {
  27. if ((processor_id & 0x0008f000) == 0x00007000) {/* ARM7 */
  28. seq_printf(m, "CPU variant\t: 0x%02x\n",
  29. (processor_id >> 16) & 127);
  30. } else {/* ARM7以上的CPU */
  31. seq_printf(m, "CPU variant\t: 0x%x\n",
  32. (processor_id >> 20) & 15);
  33. }
  34. seq_printf(m, "CPU part\t: 0x%03x\n",(processor_id >> 4) & 0xfff);
  35. }
  36. seq_printf(m, "CPU revision\t: %d\n", processor_id & 15);
  37. {
  38. unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
  39. if (cache_info != processor_id) {
  40. seq_printf(m, "Cache type\t: %s\n"
  41. "Cache clean\t: %s\n"
  42. "Cache lockdown\t: %s\n"
  43. "Cache format\t: %s\n",
  44. cache_types[CACHE_TYPE(cache_info)],
  45. cache_clean[CACHE_TYPE(cache_info)],
  46. cache_lockdown[CACHE_TYPE(cache_info)],
  47. CACHE_S(cache_info) ? "Harvard" : "Unified");
  48. if (CACHE_S(cache_info)) {
  49. c_show_cache(m, "I", CACHE_ISIZE(cache_info));
  50. c_show_cache(m, "D", CACHE_DSIZE(cache_info));
  51. } else {
  52. c_show_cache(m, "Cache", CACHE_ISIZE(cache_info));
  53. }
  54. }
  55. }
  56. seq_puts(m, "\n");
  57. seq_printf(m, "Hardware\t: %s\n", machine_name);
  58. seq_printf(m, "Revision\t: %04x\n", system_rev);
  59. seq_printf(m, "Serial\t\t: %08x%08x\n",system_serial_high, system_serial_low);
  60. return 0;
  61. }

seq_file机制相关推荐

  1. linux seq_file机制学习

    linux内核驱动模块经常要将一些信息通过/proc文件树暴露给用户,以方便用户直接能从文件系统中读取到驱动程序或者内核的一些状态信息,当这些信息比较短的时候编程比较容易,一旦过长并且用户有lseek ...

  2. linux 内核 调试工具介绍

    1 内核调试以及工具总结 内核总是那么捉摸不透, 内核也会犯错, 但是调试却不能像用户空间程序那样, 为此内核开发者为我们提供了一系列的工具和系统来支持内核的调试. 内核的调试, 其本质是内核空间与用 ...

  3. Linux内核中的proc文件系统

    简介 procfs文件系统是内核中的一个特殊文件系统.它是一个虚拟文件系统: 它不是实际的存储设备中的文件,而是存在于内存中.procfs中的文件是用来允许用户空间的程序访问内核中的某些信息(比如进程 ...

  4. 设备驱动基础学习--/proc下增加节点

    在需要创建一个由一系列数据顺序组合而成的/proc虚拟文件或一个较大的/proc虚拟文件时,推荐使用seq_file接口. 数据结构struct seq_fille定义在include/linux/s ...

  5. Linux 文件系统(VFS、EXT、proc)

    主要参考了<深入linux内核>和<Linux内核深度解析>,另外简单浅析了一下相关内容 文章目录 通用文件模型及VfS文件结构 基础知识 文件系统种类 常见的文件系统 VFS ...

  6. 实验二 创建显示系统进程的信息的proc模块

    实验二 创建显示系统进程的信息的proc模块 目录 实验二 创建显示系统进程的信息的proc模块 实验环境 一.实验目的 二.实验内容 三.实验步骤 四.实验总结 实验环境 操作系统版本:ubuntu ...

  7. linux内核seq_file接口

    seq相关头文件linux/seq_file.h,seq相关函数的实现在fs/seq_file.c.seq函数最早是在2001年就引入了,但以前内核中一直用得不多,而到了2.6内核后,许多/proc的 ...

  8. linux内核与用户空间的九种通信机制

    目前Linux提供了9种机制完成内核与用户空间的数据交换,分别是内核启动参数.模块参数与 sysfs.sysctl.系统调用.netlink.procfs.seq_file.debugfs和relay ...

  9. LWN: 名为 Sequoia 的 seq_file 漏洞!

    关注了就能看到更多这么棒的文章哦- The Sequoia seq_file vulnerability By Jake Edge July 21, 2021 DeepL assisted trans ...

最新文章

  1. 分布式系统中的进程标识
  2. .net Core 生产环境 KestrelServer + Shell 实践
  3. 存储过程的版本控制(StoreProcedure,SourceSafe)
  4. *【洛谷 - P1025】数的划分(dfs 或 dp 或 母函数,第二类斯特林数Stirling)
  5. Linux centosVMware df命令、du命令、磁盘分区
  6. Python中fastapi构建的web项目配置环境变量
  7. 我的成长日记20210406(日常测试工作安排)
  8. 算法最优化(2)线性规划问题中的常见概念辨析:可行解,最优解,基,基向量,非基向量,基变量,非基变量等等
  9. 咸鱼Maya笔记—NURBS双轨成型法
  10. 基于朴素贝叶斯的新闻分类
  11. linux停止nginx服务
  12. 从 Flask-RESTful 到 Flask-RESTPlus 再到 Flask-RESTX
  13. jenkins基础与gitlab代理自动构建
  14. 求数组中间值的三种方法
  15. IT运维的相关需求分析报告(第一篇)
  16. 酒店行业如何借助无线认证提高营销能力
  17. js+css实现鼠标点击时出现小心心
  18. 玩转华为ENSP模拟器系列 | 配置OSPF的DR选择示例
  19. 【20212121】Python基础 05条件控制语句
  20. 手机号码和姓名脱敏(加密*)

热门文章

  1. boost::phoenix::val相关的测试程序
  2. boost::math::owens_t用法的测试程序
  3. boost::histogram::axis::circular用法的测试程序
  4. boost::hana::scan_left用法的测试程序
  5. boost::graph模块实现读写graphviz的测试程序
  6. Boost:bind绑定查找问题的测试程序
  7. VTK:PolyData之SelectVisiblePoints
  8. VTK:Qt之EventQtSlotConnect
  9. VTK:IO之GenericDataObjectReader
  10. OpenCV级联识别器cascade recognizer的实例(附完整代码)