Библиотека сайта rus-linux.net
| Цилюрик О.И. Модули ядра Linux | ||
| Назад | Отладка в ядре | Вперед |
Комплементарный отладочный модуль
Весьма часто техника создания интерфейсов в пространство /proc или /sys, как это описано выше, является совершенно приемлемой, но после завершения работ было бы нежелательно оставлять конечному пользователю доступ к диагностическим и управляющим переменным, хотя бы из тех соображений, что таким образом сохраняется возможность очень просто разрушить нормальную работу изделия. Но переписывать код модуля перед его сдачей — это тоже мало приемлемый вариант, так как такой редактурой можно внести существенные ошибки в код модуля. В этом случае для проектируемого модуля на период отладки может быть создан парный ему (комплементарный) модуль:
- проектируемый модуль теперь не выносит критические переменные в качестве органов диагностики в файловые системы, а только объявляет их экспортируемыми:
- комплементарный отладочный модуль динамически устанавливает связь с этими переменными (импортирует) при своей загрузке...
- и создаёт для них интерфейсы в свя:диагностическим и управляющим переменным;
- после завершения отладки отладочный модуль просто изымается из проекта.
Чтобы увидеть в деталях о чём речь, трансформируем в эту схему пример, описанный в предыдущем разделе... Причём сделаем это без всяких изменений и улучшений, полный эквивалент, чтобы мы могли сравнить исходники по принципу: что было и что стало?
Файл общих определений:
mdsys2.h :
#include <linux/module.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/version.h> extern unsigned int irq_counter; int __init init( void ); void __exit cleanup( void ); module_init( init ); module_exit( cleanup ); MODULE_AUTHOR( "Oleg Tsiliuric <olej@front.ru>" ); MODULE_DESCRIPTION( "module in debug" ); MODULE_LICENSE( "GPL v2" );
Собственно проектируемый (отлаживаемый) модуль:
mdsys2.с :
#include "mdsys2.h"
#define SHARED_IRQ 16 // my eth0 interrupt
static int irq = SHARED_IRQ;
module_param( irq, int, S_IRUGO ); // may be change
unsigned int irq_counter = 0;
EXPORT_SYMBOL( irq_counter );
static irqreturn_t mdsys_interrupt( int irq, void *dev_id ) {
irq_counter++;
return IRQ_NONE;
}
static int my_dev_id;
int __init init( void ) {
if( request_irq( irq, mdsys_interrupt, IRQF_SHARED, "my_interrupt", &my_dev_id ) )
return -1;
else
return 0;
}
void cleanup( void ) {
synchronize_irq( irq );
free_irq( irq, &my_dev_id );
return;
}
И модуль, создающий для него отладочный интерфейс:
mdsysс.h :
#include "mdsys2.h"
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
static ssize_t show( struct class *class, struct class_attribute *attr, char *buf ) {
#else
static ssize_t show( struct class *class, char *buf ) {
#endif
sprintf( buf, "%d\n", irq_counter );
return strlen( buf );
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
static ssize_t store( struct class *class, struct class_attribute *attr, const char *buf, size_t c
#else
static ssize_t store( struct class *class, const char *buf, size_t count ) {
#endif
int i, res = 0;
const char dig[] = "0123456789";
for( i = 0; i < count; i++ ) {
char *p = strchr( dig, (int)buf[ i ] );
if( NULL == p ) break;
res = res * 10 + ( p - dig );
}
irq_counter = res;
return count;
}
CLASS_ATTR( mds, 0666, &show, &store ); // => struct class_attribute class_attr_mds
static struct class *mds_class;
int __init init( void ) {
int res = 0;
mds_class = class_create( THIS_MODULE, "mds-class" );
if( IS_ERR( mds_class ) ) printk( KERN_ERR "bad class create\n" );
res = class_create_file( mds_class, &class_attr_mds );
if( res != 0 ) printk( KERN_ERR "bad class create file\n" );
return res;
}
void cleanup( void ) {
class_remove_file( mds_class, &class_attr_mds );
class_destroy( mds_class );
return;
}
Теперь отладочный модуль не знает ничего ни о прерываниях, ни о структуре отлаживаемого модуля — он знает только ограниченный набор экспортируемых переменных (или, как вариант, экспортируемых точек входа), по именам и по типам. Опробуем то, что у нас получилось, и сравним с примером предыдущего раздела:
$ sudo insmod mdsys2.ko
$ sudo insmod mdsysc.ko
$ lsmod | head -n3
Module Size Used by mdsysc 934 0 mdsys2 844 1 mdsysc
$ cat /sys/class/mds-class/mds
784
$ cat /sys/class/mds-class/mds
825
$ echo 0 > /sys/class/mds-class/mds
$ cat /sys/class/mds-class/mds
21
Теперь мы удалим отладочный модуль:
$ sudo rmmod mdsysc
Отлаживаемый модуль замечательно продолжает работать, но отладочные интерфейсы к нему исчезли:
$ lsmod | head -n3
Module Size Used by mdsys2 844 0 lp 6794 0
$ cat /sys/class/mds-class/mds
cat: /sys/class/mds-class/mds: Нет такого файла или каталога
$ sudo rmmod mdsys2
| Предыдущий раздел: | Оглавление | Следующий раздел: |
| Интерфейсы пространства пользователя к модулю | Некоторые мелкие советы в завершение |
