proc 文件系统是由软件创建,被内核用来向外界报告信息的一个文件系统。/proc 下面的每一个文件都和一个内核函数相关联,当文件的被读取时,与之对应的内核函数用于产生文件的内容。我们已经见到了很多这样的文件,例如,/proc/modules 总是返回当前内核中加载的模块。
下面是一些重要 的文件:
/proc/cpuinfo - CPU 的信息 (型号, 家族, 缓存大小等)
/proc/meminfo - 物理内存、交换空间等的信息
/proc/mounts - 已加载的文件系统的列表
/proc/devices - 可用设备的列表
/proc/filesystems - 被支持的文件系统
/proc/modules - 已加载的模块
/proc/version - 内核版本
/proc/cmdline - 系统启动时输入的内核命令行参数
proc文件系统可用于查看硬件的寄存器状态,并可以对其进行写操作。以下实例用于模拟利用proc文件系统对寄存器进行读写操作
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <asm/access.h>
#define MAX_BUFFER_SIZE 256
#define AXP192_PROC_FILE "driver/axp192"
static struct proc_dir_entry *axp192_proc_file;
static int index;
static u8 buff[MAX_BUFFER_SIZE];
static void axp192_write(int index, u8 reg_val)
{
buff[index] = reg_val;
}
static void axp192_read(int index, u8 *reg_val)
{
*reg_val = buff[index];
}
static ssize_t axp192_proc_read(struct file *filp,
char *buffer, size_t length,loff_t *offset)
{
u8 reg_val;
if ((index < 0) || (index >MAX_BUFFER_SIZE))
return 0;
axp192_read(index, ®_val);
printk(KERN_ALERT "register0x%x: 0x%x\n", index, reg_val);
return 0;
}
static ssize_taxp192_proc_write(struct file *filp,
const char*buff, size_t len, loff_t *off)
{
u8 reg_val;
char messages[256], vol[256];
if (len > 256)
len = 256;
if (copy_from_user(messages, buff,len))
return -EFAULT;
if ('-' == messages[0]) {
/* set the register index */
memcpy(vol,messages+1, len-1);
index = (u8) simple_strtoul(vol, NULL, 16);
} else {
/* set theregister value */
reg_val =(u8)simple_strtoul(messages, NULL, 16);
axp192_write(index,reg_val & 0xFF);
}
return len;
}
static struct file_operationsaxp192_proc_ops = {
.read = axp192_proc_read,
.write = axp192_proc_write,
};
static voidcreate_axp192_proc_file(void)
{
printk("setup proc controlinterface\n");
axp192_proc_file = create_proc_entry(AXP192_PROC_FILE,0644, NULL);
if (axp192_proc_file) {
axp192_proc_file->proc_fops =&axp192_proc_ops;
} else
printk(KERN_INFO "proc filecreate failed!\n");
}
static voidremove_axp192_proc_file(void)
{
remove_proc_entry(AXP192_PROC_FILE,NULL);
}
static int __init axp192_init(void)
{
printk(KERN_ALERT”---AXP192_init\n”);
create_axp192_proc_file();
return 0;
}
static void __exitaxp192_exit(void)
{
remove_axp192_proc_file();
}
module_init(axp192_init);
module_exit(axp192_exit);
MODULE_DESCRIPTION("Axp192Driver");
MODULE_LICENSE("GPL");生成apx192.ko后,在虚拟机中insmod,成功后在/proc/driver下将会生成名为axp192的文件,改变其属性对其操作。操作过程和结果如图(ubuntu的文字界面模式下):
第一次echo “-0x21”>axp192 ,指定寄存器,由于没有设置值,故默认值为0 所以:register 0x21: 0x0
第二次echo “0x78”>axp192是改变寄存器0x21的值,设为0x78。设置后,观察:register 0x21: 0x78
这就是在Ubuntu虚拟机下一个最简单的模块编写过程。