文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>How to access the kernel variables from user space

How to access the kernel variables from user space

时间:2009-08-14  来源:superfluous

In linux operating system there are many methods to access the kernel variables from user space. You can access the kernel variables through psuedo-device drivers, procfs, etc. In this article the procfs method is discussed.
Procfs is a pseudo filesystem which no disk storage is required. It resides in RAM. It just provide an interface. The variables of kernel is not required additional space to store. They are just kernel variables which are allocated memory space when system intialized(not considering module inserting). In short procfs provides a view of kernel's state which is described by kernel's variables. So obviously many kernel variables are only readable but writable through profs interface.

[lsq@localhost proc]$ ls -al
...
-r--r--r--   1 root      root              0 2009-08-14 11:18 partitions
-r--r--r--   1 root      root              0 2009-08-14 11:18 schedstat
dr-xr-xr-x   4 root      root              0 2009-08-14 11:18 scsi
lrwxrwxrwx   1 root      root             64 2009-08-14 07:52 self -> 10872
-rw-r--r--   1 root      root              0 2009-08-14 11:18 slabinfo
-r--r--r--   1 root      root              0 2009-08-14 11:18 stat
-r--r--r--   1 root      root              0 2009-08-14 11:18 swaps
dr-xr-xr-x   1 root      root              0 2009-08-14 07:52 sys
--w-------   1 root      root              0 2009-08-14 11:18 sysrq-trigger
dr-xr-xr-x   2 root      root              0 2009-08-14 11:18 sysvipc
-rw-r--r--   1 root      root              0 2009-08-14 11:18 timer_list
-rw-r--r--   1 root      root              0 2009-08-14 11:18 timer_stats
dr-xr-xr-x   4 root      root              0 2009-08-14 11:18 tty
-r--r--r--   1 root      root              0 2009-08-14 11:18 uptime
-r--r--r--   1 root      root              0 2009-08-14 11:18 version
-r--------   1 root      root              0 2009-08-14 11:18 vmcore
-r--r--r--   1 root      root              0 2009-08-14 11:18 vmmemctl
-r--r--r--   1 root      root              0 2009-08-14 11:18 vmstat
-r--r--r--   1 root      root              0 2009-08-14 11:18 zoneinfo

Now let's look at codes in include/linux/proc-fs.h.
struct proc_dir_entry is a main structure of procfs. It represents a procfs entry which defines mode, authorities of user, and operations etc. In this structure there are several fields which we should take into account.
struct proc_dir_entry {
  ...
  mode_t  mode;
  ...
  read_proc_t  *read_proc;
  write_proc_t  *write_proc;
  ...
};

And then how to create a proc_dir_entry? The Linux kernel provides the corresponding function:
  struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
          struct proc_dir_entry *parent);
When the entry is removed. The function
  void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
if you want to create an entry named "myentry" in /proc with mode 0644, you can do as follows:
  ...
  struct proc_dir_entry  *entry;
  ...

  entry = create_proc_entry("myprocentry", 0644, NULL);
  ...

when system runs again, you can see the following entry in /proc

[lsq@localhost proc]$ ls -al | grep myprocentry
-rw-r--r--   1 root      root              0 2009-08-14 11:18 myprocentry

Now lets add the operations to the entry.
  ...
  entry->read_proc = proc_myprocentry_read;
  entry->write_proc = proc_myprocentry_write;
  ...

  static int
  proc_myprocentry_read(char *page, char **start, off_t off, int count, int *eof,
        void *data)
  {
      ...
  }

  static int
  proc_myprocentry_write(struct file *file, const char __user *buffer,
        unsigned long count, void *data)
  {
      ...
  }
And then you can read myprocentry with following commands:
[lsq@localhost proc]$ cat /proc/myprocentry
...
[lsq@localhost proc]$ od -x /proc/myprocentry

If you want to change the kernel variable, you can use:
[lsq@localhost proc]$ echo value > /proc/myprocentry

The following codes gives details of above procedure. Assume that kernel variable
"kernel_var" is an unsigned integer. It is declared as:
   unsigned int kernel_var;
----------------------------------------------------------------------------------
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>

static int
proc_myprocentry_read(char *page, char **start, off_t off, int count, int *eof,
   void *data)
{
   int  len = 0;

   len += snprintf(page + len, PAGE_SIZE - len, "%ud\n", kernel_var);

   *eof = 0;
   return  len;
}

static int
proc_myprocentry_write(struct file *file, const char __user *buffer, unsigned long count,
   void *data)
{
   /* if using 'echo val > /proc/myprocentry', it should change string to int */
   if (unlikely(count == sizeof(unsigned int))) {
      copy_from_user((char *)&kernel_var, buffer, sizeof(unsigned int));
   }

   return  count;
}

int
myprocentry_init(void)
{
   struct proc_dir_entry  *entry;

   entry = create_proc_entry("myprocentry", 0644, NULL);
   if (entry == NULL)
       return  -1;

   entry->read_proc = proc_myprocentry_read;
   entry->write_proc = proc_myprocentry_write;

   return  0;
}

void
myprocentry_exit(void)
{
   remove_proc_entry("myprocentry", NULL);
}

module_init(myprocentry_init);
module_exit(myprocentry_exit);
MODULE_LICENSE("GPL");
相关阅读 更多 +
排行榜 更多 +
超级摩托车特技3D

超级摩托车特技3D

赛车竞速 下载
超级汽车大乱斗

超级汽车大乱斗

赛车竞速 下载
沙漠越野车

沙漠越野车

赛车竞速 下载