Я вижу здесь две вещи не так.Сначала вы объявляете l
внутри цикла for.Второй mzone
- указатель, поэтому вам нужно использовать ->
вместо .
для доступа к vm_stat
.Кроме того, вместо long l
следует использовать atomic_long_t l
, для которого необходимо asm-generic/atomic-long.h
.Тем не менее, вот модуль ядра , который работает с вашим примером:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mmzone.h>
#include <asm-generic/atomic-long.h>
int __init init_module(void){
struct zone *mzone;
atomic_long_t l
for_each_zone(mzone)
l = mzone->vm_stat[NR_FREE_PAGES];
return 0;
}
void __exit clean_module(void){
}
Теперь о том, как работает макрос for_each_zone
.Он определен в linux/mmzone.h
как (ядро 3.1.5):
#define for_each_zone(zone) \
for (zone = (first_online_pgdat())->node_zones; \
zone; \
zone = next_zone(zone))
Как вы можете видеть, он работает, получая указатель на struct zone
и затем расширяется в цикл for, который будетцикл через каждую зону.Следовательно, вы можете думать об этом как о простом цикле for.
Теперь, как я понял ваш вопрос, вам нужно вызвать my_service
из исходных кодов ядра.В ядре есть несколько папок, в которые вы можете поместить свои исходники (fs
, ipc
и т. Д.).Самый быстрый способ сделать это - выбрать одну из этих папок и поместить туда файл .c
.Затем вам нужно изменить Makefile
из этой папки, чтобы он также компилировал ваш .c
.После этого вы, вероятно, захотите написать файл .h
, чтобы предоставить свои функции другим.Я бы порекомендовал положить его внутрь include/linux
.Наконец, вам нужно перекомпилировать ядро.Не забывайте, что если вы хотите, чтобы модули использовали любую из ваших функций / переменных, вы всегда можете использовать макрос EXPORT_SYMBOL
, чтобы сделать их доступными.
Надеюсь, это поможет