Вот код. При открытии устройства драйвер получает список процессов. При чтении с устройства в пользовательский буфер копируется часть данных, но я ещё не уверен, использовал *pos для указания откуда начать копировать данные, если их будет очень много, но наверное можно было бы и обойтись и без них.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/string.h>
MODULE_LICENSE("Dual BSD/GPL");
dev_t dev;
int lock;
unsigned baseminor = 0;
unsigned count = 1;
unsigned scull_major = 0;
char *name = "scull";
struct scull_dev {
int quantum;
int qset;
unsigned long size;
unsigned int access_key;
struct semaphore sem;
struct cdev cdev;
};
struct scull_dev *sdev;
char *data;
loff_t scull_llseek ( struct file *file, loff_t pos, int n )
{
}
ssize_t scull_read ( struct file *file, char __user *buf, size_t count, loff_t *pos)
{
char *p;
p = data;
p += *pos;
int len = strlen ( p );
len = len > 4096 ? count : len;
memset ( buf, 0, sizeof buf );
copy_to_user ( buf, p, len );
*pos += len;
return len;
}
ssize_t scull_write ( struct file *file, const char __user *buf, size_t n, loff_t *lt )
{
}
int scull_open ( struct inode *inode, struct file *filp )
{
if ( lock ) while ( lock ){};
lock = 1;
struct scull_dev *scdev;
struct task_struct *task;
scdev = container_of ( inode->i_cdev, struct scull_dev, cdev );
filp->private_data = scdev;
data = kmalloc ( 16386, GFP_USER );
char *p, *h;
p = data;
int len = 0;
for_each_process(task)
{
h = &task->comm[0];
for ( ; *h != 0 && len < 16384; p++, h++, len++ ) *p = *h;
*p = 32;
p++;
len++;
if ( len > 16384 ) break;
printk ( "%s\n", task->comm );
}
*p = 0;
return 0;
}
int scull_release ( struct inode *inode, struct file *file )
{
kfree ( data );
lock = 0;
return 0;
}
struct file_operations scull = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.open = scull_open,
.release = scull_release
};
static int hello_init ( void )
{
sdev = kmalloc ( sizeof ( struct scull_dev ), GFP_KERNEL );
int err;
int result = alloc_chrdev_region ( &dev, baseminor, count, name );
scull_major = MAJOR(dev);
cdev_init ( &sdev->cdev, &scull );
sdev->cdev.owner = THIS_MODULE;
sdev->cdev.ops = &scull;
err = cdev_add ( &sdev->cdev, dev, 1 );
if ( err )
printk (KERN_NOTICE "Error %d adding scull%d", err, 0 );
}
static void hello_exit ( void )
{
cdev_del ( &sdev->cdev );
kfree ( sdev );
unregister_chrdev_region ( dev, count );
}
module_init ( hello_init );
module_exit ( hello_exit );