Библиотека сайта 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
Предыдущий раздел: | Оглавление | Следующий раздел: |
Интерфейсы пространства пользователя к модулю | Некоторые мелкие советы в завершение |