LINUX.ORG.RU
ФорумTalks

Драйвер для биореактора под Linux 2.6


0

0

Работает отлично. Суёшь в него какие-нибудь буквы, а он возвращает чистейший
метан. Статистика работы биореактора находится в /proc/bioreactor. Там указано
количество произведённого метана и количество метана, находящегося в
резервуаре.

Makefile:
_______________________________________
obj-m += bioreactor.o

all:
        make -C /lib/modules/`uname -r`/build M=${PWD} modules

clean:
        make -C /lib/modules/`uname -r`/build M=${PWD} clean
_______________________________________



bioreactor.c:
_______________________________________
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>


static int major;
static int opened;
static int ch4, total_ch4;

struct proc_dir_entry *proc_bioreactor;

static int bioreactor_open(struct inode *inode, struct file *file);
static int bioreactor_close(struct inode *inode, struct file *file);
static ssize_t bioreactor_read(struct file *, char *, size_t, loff_t *);
static ssize_t bioreactor_write(struct file *, char *, size_t, loff_t *);
int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data);

static struct file_operations fops = {
        .read = bioreactor_read,
        .write = bioreactor_write,
        .open = bioreactor_open,
        .release = bioreactor_close
};

static int bioreactor_open(struct inode *inode, struct file *file)
{
        if (opened) return -EBUSY;
        opened++;
        printk(KERN_INFO "Door opened. Give me some shit!\n");
return 0;
}

static int bioreactor_close(struct inode *inode, struct file *file)
{
        opened--;
        printk(KERN_INFO "Door closed.\n");
return 0;
}

static ssize_t bioreactor_read(struct file *f, char *buffer, size_t length, loff_t *offset)
{
        int l, i;
        char metan = 'm';
        if (length > ch4)
        {
                l = ch4;
                ch4 = 0;
        } else
        {
                l = length;
                ch4 -= length;
        }
        for(i = 0; i < l; i++) put_user('m', buffer++);
return l;
}

static ssize_t bioreactor_write(struct file *f, char *buffer, size_t length, loff_t *offset)
{
        ch4 += length;
        total_ch4 += length;
return length;
}

int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data)
{
return sprintf(buffer, "Total CH4:       %10d Kg\nCH4 in the tank: %10d Kg\n", total_ch4, ch4);
}

static int __init bioreactor_init(void)
{
        printk(KERN_INFO "Turning bioreactor on...\n");
        major = register_chrdev(0, "bioreactor", &fops);
        if (major < 0)
        {
                printk(KERN_ALERT "Failed to register device\n");
                return major;
        }
        printk(KERN_INFO "Registered device %d\n", major);
        proc_bioreactor = create_proc_entry("bioreactor", 644, NULL);
        proc_bioreactor->read_proc = proc_bioreactor_read;
        proc_bioreactor->owner = THIS_MODULE;
        proc_bioreactor->mode = S_IFREG | S_IRUGO;
        proc_bioreactor->uid = 0;
        proc_bioreactor->gid = 0;
        proc_bioreactor->size = 20;
        printk(KERN_INFO "/proc/bioreactor has been created\n");
return 0;
}

static void __exit bioreactor_exit(void)
{
        int r = unregister_chrdev(major, "bioreactor");
        if (r < 0) printk(KERN_ALERT "Error in unregister_chrdev %d\n", r);
        remove_proc_entry("bioreactor", &proc_root);
        printk(KERN_INFO "Turning bioreactor off...\n");
}

MODULE_AUTHOR("unnamed");
MODULE_DESCRIPTION("Bioreactor");

module_init(bioreactor_init);
module_exit(bioreactor_exit);
_______________________________________

ЛОЛ :)

Надо добавить возможность вывода метана через USB привод.

shuthdar ★★★
()

Да, кое-кто хорошо покурил ;))

anonymous
()

Лицензию еще только нужно прописать :)

alexru ★★★★
()
Ответ на: комментарий от JB

Получилось! ;)

Я подредактировал исходник, убрал warnings.

Значит, так. Надо создать каталог /usr/src/linux/bioreactor, туда поместить Makefile
и bioreactor.c. Потом в /usr/src/linux/Makefile строку "drivers-y       := drivers/ sound/"
переделать в "drivers-y       := drivers/ sound/ bioreactor/". Ну, а потом make && make
install.

Makefile для статики:
_________________________________
obj-y += bioreactor.o

all:
        make -C /lib/modules/`uname -r`/build M=${PWD}

clean:
        make -C /lib/modules/`uname -r`/build M=${PWD} clean
_________________________________

Новый bioreactor.c:
_________________________________
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>


static int major;
static int opened;
static int ch4, total_ch4;

struct proc_dir_entry *proc_bioreactor;

static int bioreactor_open(struct inode *inode, struct file *file);
static int bioreactor_close(struct inode *inode, struct file *file);
static ssize_t bioreactor_read(struct file *, char *, size_t, loff_t *);
static ssize_t bioreactor_write(struct file *, const char *, size_t, loff_t *);
int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data);

static struct file_operations fops = {
	.read = bioreactor_read,
	.write = bioreactor_write,
	.open = bioreactor_open,
	.release = bioreactor_close
};


static int bioreactor_open(struct inode *inode, struct file *file)
{
	if (opened) return -EBUSY;
	opened++;
	printk(KERN_INFO "Door opened. Give me some shit!\n");
return 0;
}

static int bioreactor_close(struct inode *inode, struct file *file)
{
	opened--;
	printk(KERN_INFO "Door closed.\n");
return 0;
}

static ssize_t bioreactor_read(struct file *f, char *buffer, size_t length, loff_t *offset)
{
	int l, i;
	if (length > ch4)
	{
		l = ch4;
		ch4 = 0;
	} else
	{
		l = length;
		ch4 -= length;
	}
	for(i = 0; i < l; i++) put_user('m', buffer++);
return l;
}

static ssize_t bioreactor_write(struct file *f, const char *buffer, size_t length, loff_t *offset)
{
	ch4 += length;
	total_ch4 += length;
return length;
}

int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data)
{
return sprintf(buffer, "Total CH4:       %10d Kg\nCH4 in the tank: %10d Kg\n", total_ch4, ch4);
}

static int __init bioreactor_init(void)
{
	printk(KERN_INFO "Turning bioreactor on...\n");
	major = register_chrdev(0, "bioreactor", &fops);
	if (major < 0)
	{
		printk(KERN_ALERT "Failed to register device\n");
		return major;
	}
	printk(KERN_INFO "Registered device %d\n", major);
	proc_bioreactor = create_proc_entry("bioreactor", 644, NULL);
	proc_bioreactor->read_proc = proc_bioreactor_read;
	proc_bioreactor->owner = THIS_MODULE;
	proc_bioreactor->mode = S_IFREG | S_IRUGO;
	proc_bioreactor->uid = 0;
	proc_bioreactor->gid = 0;
	proc_bioreactor->size = 20;
	printk(KERN_INFO "/proc/bioreactor has been created\n");
return 0;
}

static void __exit bioreactor_exit(void)
{
	int r = unregister_chrdev(major, "bioreactor");
	if (r < 0) printk(KERN_ALERT "Error in unregister_chrdev %d\n", r);
	remove_proc_entry("bioreactor", &proc_root);
	printk(KERN_INFO "Turning bioreactor off...\n");
}

MODULE_AUTHOR("unnamed");
MODULE_DESCRIPTION("Bioreactor");

module_init(bioreactor_init);
module_exit(bioreactor_exit);
_________________________________

unnamed
() автор топика
Ответ на: комментарий от CrazyPit

cat /proc/devices

254 bioreactor

идём в /dev и sudo mknod -m 666 bioreactor u 254 254

работает =)

cat /dev/random > /dev/bioreactor ...

cat /proc/bioreactor

Total CH4: 2120 Kg CH4 in the tank: 2120 Kg

WerNA ★★★★★
()

Дык! Драйвер для биореактора надо писАть на ЛИСПЕ. Недоязычок С не канает ни разу.

профессор В.С.Луговский.

anonymous
()
Ответ на: комментарий от anonymous

На 2.4 попробуй вот так откомпилить:
gcc -O2 -DMODULE -D__KERNEL__ -isystem /lib/modules/`uname -r`/build/include -c bioreactor.c

unnamed
() автор топика

Исправлена уязвимость, позволяющая злоумышленнику получить
отрицательные значения CH4. А ещё появилась возможность открывать файл
по нескольку раз.


bioreactor.patch:
__________________
diff --context a/bioreactor.c b/bioreactor.c
*** a/bioreactor.c	Tue Jul 26 23:28:15 2005
--- b/bioreactor.c	Wed Jul 27 11:52:03 2005
***************
*** 7,14 ****
  
  
  static int major;
! static int opened;
! static int ch4, total_ch4;
  
  struct proc_dir_entry *proc_bioreactor;
  
--- 7,13 ----
  
  
  static int major;
! static unsigned int ch4, total_ch4;
  
  struct proc_dir_entry *proc_bioreactor;
  
***************
*** 28,42 ****
  
  static int bioreactor_open(struct inode *inode, struct file *file)
  {
- 	if (opened) return -EBUSY;
- 	opened++;
  	printk(KERN_INFO "Door opened. Give me some shit!\n");
  return 0;
  }
  
  static int bioreactor_close(struct inode *inode, struct file *file)
  {
- 	opened--;
  	printk(KERN_INFO "Door closed.\n");
  return 0;
  }
--- 27,38 ----
***************
*** 66,72 ****
  
  int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data)
  {
! return sprintf(buffer, "Total CH4:       %10d Kg\nCH4 in the tank: %10d Kg\n", total_ch4, ch4);
  }
  
  static int __init bioreactor_init(void)
--- 62,68 ----
  
  int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data)
  {
! return sprintf(buffer, "Total CH4:       %10u Kg\nCH4 in the tank: %10u Kg\n", total_ch4, ch4);
  }
  
  static int __init bioreactor_init(void)
***************
*** 103,105 ****
--- 99,102 ----
  
  module_init(bioreactor_init);
  module_exit(bioreactor_exit);
+ 

__________________

unnamed
() автор топика
Ответ на: комментарий от unnamed

/*
 *
 * Бранч драйвера бироеактора, поддерживающий udev
 * но незапатченый :-)
 *
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/device.h>


static int major;
static int opened;
static int ch4, total_ch4;

struct proc_dir_entry *proc_bioreactor;

static int bioreactor_open(struct inode *inode, struct file *file);
static int bioreactor_close(struct inode *inode, struct file *file);
static ssize_t bioreactor_read(struct file *, char *, size_t, loff_t *);
static ssize_t bioreactor_write(struct file *, const char *, size_t, loff_t *);
int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int
 buffer_length, int *eof, void *data);

static struct file_operations fops = {
        .read = bioreactor_read,
        .write = bioreactor_write,
        .open = bioreactor_open,
        .release = bioreactor_close
};


static int bioreactor_open(struct inode *inode, struct file *file)
{
        if (opened) return -EBUSY;
        opened++;
        printk(KERN_INFO "Door opened. Give me some shit!\n");
return 0;
}

static int bioreactor_close(struct inode *inode, struct file *file)
{
        opened--;
        printk(KERN_INFO "Door closed.\n");
return 0;
}

static ssize_t bioreactor_read(struct file *f, char *buffer, size_t length, loff
_t *offset)
{
        int l, i;
        if (length > ch4)
        {
                l = ch4;
                ch4 = 0;
        } else
        {
                l = length;
                ch4 -= length;
        }
        for(i = 0; i < l; i++) put_user('m', buffer++);
return l;
}

static ssize_t bioreactor_write(struct file *f, const char *buffer, size_t lengt
h, loff_t *offset)
{
        ch4 += length;
        total_ch4 += length;
return length;
}

int proc_bioreactor_read(char *buffer, char **buffer_location, off_t offset, int
 buffer_length, int *eof, void *data)
{
return sprintf(buffer, "Total CH4:       %10d Kg\nCH4 in the tank: %10d Kg\n", t
otal_ch4, ch4);
}

static struct class_simple * bioclass;

static int __init bioreactor_init(void)
{
        printk(KERN_INFO "Turning bioreactor on...\n");
        major = register_chrdev(0, "bioreactor", &fops);
        if (major < 0)
        {
                printk(KERN_ALERT "Failed to register device\n");
                return major;
        }
        bioclass = class_simple_create( THIS_MODULE, "bioreactor" );
        class_simple_device_add( bioclass, MKDEV(major,1), NULL, "bioreactor");
        devfs_mk_cdev(MKDEV(major,1),S_IFCHR|S_IRUSR|S_IWUSR,"bioreactor");
        printk(KERN_INFO "Registered device %d\n", major);
        proc_bioreactor = create_proc_entry("bioreactor", 644, NULL);
        proc_bioreactor->read_proc = proc_bioreactor_read;
        proc_bioreactor->owner = THIS_MODULE;
        proc_bioreactor->mode = S_IFREG | S_IRUGO;
        proc_bioreactor->uid = 0;
        proc_bioreactor->gid = 0;
        proc_bioreactor->size = 20;
        printk(KERN_INFO "/proc/bioreactor has been created\n");
return 0;
}

static void __exit bioreactor_exit(void)
{
        int r = unregister_chrdev(major, "bioreactor");
        devfs_remove("bioreactor");
        class_simple_device_remove(MKDEV(major,1));
        class_simple_destroy(bioclass);
        if (r < 0) printk(KERN_ALERT "Error in unregister_chrdev %d\n", r);
        remove_proc_entry("bioreactor", &proc_root);
        printk(KERN_INFO "Turning bioreactor off...\n");
}

MODULE_AUTHOR("unnamed");
MODULE_DESCRIPTION("Bioreactor");

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

:)
А патч, собственно, убирает все строки с переменной opened, заменяет тип ch4 и total_ch4 на unsigned и заменяет %d на %u в printf().

unnamed
() автор топика

Makefile для корректной установки модуля биореактора:

----------------------

obj-m += bioreactor.o

all:
        make -C /lib/modules/`uname -r`/build M=${PWD} modules

install:
        make -C /lib/modules/`uname -r`/build M=${PWD} modules_install
        depmod -a
        $(shell [ ! -f /dev/bioreactor ] && mknod -m 666 /dev/bioreactor u 254 254)
        @ls -l /dev/bioreactor

clean:
        make -C /lib/modules/`uname -r`/build M=${PWD} clean

----------------------------------------------------

При установке создаётся нужный девайс, если его не было.
Загружать модуль теперь можно так:

(as root)
modprobe bioreactor

RomanU
()
Ответ на: комментарий от RomanU

> При установке создаётся нужный девайс, если его не было.

Плохое решение. Мажор драйверу выдается динамически, и поэтому существует риск, что mknod /dev/bioreactor c 254 1 будет "мимо кассы", и угодит на другое устройство. Так что это уже скорее не патч, а dirty hack для тех, у кого нет udev :-)

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

Ну у меня нету udev, поэтому я даже об этом не подумал.

А если реактор перезапишет какое-другое устройство - так представляете сколько метана будет? ;))

RomanU
()

А когда плагин для фаерфокса будет, ЛОР посещать?

bugmaker ★★★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.