Start of topic | Skip to actions
Использование Debugfs для отладки модулей ядра linuxВведениеВ функциях модулей ядра, время выполнения которых критично, использование отладочного вывода с помощью printk зачастую невозможно. Однако наблюдать за происходящими событиями в этой функции можно. Для этого предназначена файловая система debugfs. Перед вызовом функции нужно только создать необходимое количество файлов и у нас появляется возможность наблюдать за работой функции прямо из user space. А если требуется, то можно прямо на ходу управлять функцией. Давайте посмотрим на то, как просто это делается. Внимание! Приведенные примеры актуальны для ядра linux версии 2.6.17. В более новых версиях ядра могут быть модификации.Что такое debugfs?Debugfs - это виртуальная файловая ситема, похожая на /sysfs и /procfs, но с минимальным набором функций. Debugfs позволяет очень просто смотреть/менять значение любой переменной прямо во время работы модуля, в котором эта переменная присутствует. Для этого в debugfs создается файл, содержимое которого и есть значение заданной переменной. Таким образом, чтобы иметь возможность управлять какой-либо переменной нам нужно сделать всего несколько шагов:
Конфигурация ядраДля работы с debugfs необходимо, чтобы ядро было собрано с опциями:CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_FS=yЧтобы проверить, включена ли debugfs в ядре, можно сделать так: $ cat /proc/filesystems nodev sysfs nodev rootfs nodev bdev nodev proc nodev debugfs nodev sockfs nodev pipefs nodev futexfs nodev tmpfs nodev eventpollfs nodev devpts nodev ramfs nodev jffs2Если видим в списке debugfs - все хорошо. Далее необходимо подмонтировать debufs: $ mount -t debugfs none_debugfs /proc/sys/debug Пример использования debugfsРассмотрим пример простого модуля с использованием debugfs:
...
#include <linux/debugfs.h>
...
static struct dentry* dbg_dir = NULL;
static struct dentry* dbg_entry = NULL;
u32 tst_val = 0;
// инициализация модуля
static int init(void)
{
// Создаем директорию в debugfs
dbg_dir = debugfs_create_dir("dir", NULL);
if (!dbg_dir) {
return -EFAULT;
}
// Создаем файл tst в директории dir. При создании передаем
// адрес переменной tst_val, которую мы хотим изменять из userspace
dbg_entry = debugfs_create_u32("tst", S_IRUGO, dbg_dir, &tst_val);
if (!dbg_entry) {
debugfs_remove(dbg_dir);
return -EFAULT;
}
return 0;
}
// деинициализация модуля
static void cleanup(void)
{
// перед выходом выведем значение тестовой переменной,
// чтобы убедиться, что она действительно изменилась
printk("val: %u\n", tst_val);
// Перед выходом нужно удалить сначала файл,
// а затем и его директорию-parent`a
debugfs_remove(dbg_dir);
debugfs_remove(dbg_entry);
}
Загрузим наш модуль и посмотрим, что получилось:
# загружаем модуль $ insmod b4_debug.ko # в каталоге dir появился файл tst $ ls /proc/sys/debug/dir/ tst # считываем значение переменной tst_val $ cat /proc/sys/debug/dir/tst 0 # записываем новое значение $ echo 4 > /proc/sys/debug/dir/tst # проверяем $ cat /proc/sys/debug/b4/tst 4Таким образом можно менять/смотреть любую переменную модуля ядра без особых усилий СсылкиЮрий Людкевич, НТЦ Метротек. | |