2013-11-08 2 views
2

Я беру курс ОС, и первым решением было добавить несколько системных вызовов в ядро ​​(Redhat, версия ядра 2.4).Добавление нового системного вызова в ядро ​​linux, похоже, не работает

Я добавил все, что, как я думал, должно быть добавлено, и оно по-прежнему не работает.

Я пытаюсь запустить тесты, и я заметил, что обертки (я добавил пример для одного ниже и код sys_call для него) не связаны с системными вызовами. Я знаю это, потому что я помещаю printk в системные вызовы, и они никогда не появляются (и сам тест не дает ожидаемого результата).

Теперь от того, что я понимаю процесс разработки для добавления системного вызова является:

  1. Создание оберток как функции примера обертки в инструкции (позволяет называть его AService ").
  2. Напишите sys_aservice в .c файле, который перейдет в один из многих файлов в папке linux-2.4.18-14. Файл, к которому он идет, зависит от типа службы, которую я хочу добавить (например, если это была служба файловой системы, которую я поставил бы в fs).
  3. Добавить запись для системного вызова в таблице на /usr/src/linuxlinux-2.4.18-14custom/arch/i386/kernel/ entry.S

Это то, что я сделал в первый, но это, кажется, не достаточно (потому что это не похоже на работу).

Я искал его онлайн (и читал: How to add a system call), и я прочитал, что мне нужно добавить/изменить следующие вещи для привязки к работе.

  1. Добавить строку в unistd.h для системного вызова. Это будет выглядеть как

    определяют __NR_aservice

  2. Добавить AService в Makefile. Так, например, если я поместил aservice.c в папку fs, я бы добавил aservice.c в makefile в fs.

  3. Создайте файл aservice.h, который перейдет в linux-2.4.18-14custom/include/linux (где все h-файлы идут, по-видимому?). Этот файл .h будет включать в себя что-то, называемое «заглушкой», которое автоматически генерируется из макроса в unistd.h (который должен содержать файл .h), чтобы программа пользователя могла использовать ваш системный вызов. декларация заглушки выглядит следующим образом: _syscallN (тип возвращаемого значения, имя функции, тип arg1, arg1 имя ...)», где„N“является числом параметров

  4. PREPEND каждой функции sys_X в aservice.c. ключевое слово «asmlinkage» (которое требует включения linkage.h). Таким образом, объявления функций выглядят так: asmlinkage int sys_aservice (...) {..} После этого добавьте файл .h в файл .c.

Все ли это правильно? Потому что даже после выполнения следующего кажется, что системный вызов не вызван.

Вот пример обертка и системный вызов реализации:

int stop_monitor(int pid){ 
     long __res; 
     __asm__ volatile (
       "movl $244, %%eax;" << 244 is the entry in the sys_call table in entry.S 
       "movl %1, %%ebx;" 
       "int $0x80;" 
       "movl %%eax, %0" 
       : "=m" (__res) 
       : "m" (pid) 
       : "%eax", "%ebx" 
     ); 
     if((unsigned long)(__res) >= (unsigned long)(-125)) { 
      errno = -(__res); 
      __res = -1; 
     } 
     return (int)(__res); 
    } 


asmlinkage int sys_stop_monitor(int pid){ 
    task_t* task = find_task_by_pid(pid); 
    if(!task) 
     return -ESRCH; 
    if(task->flagMonitor == 0) 
     return -EPERM; 
    task->flagMonitor = 0; 
    return 0; 
} 

Что мне не хватает?

+1

Вы не забыли настроить ядро ​​для его компиляции? – technosaurus

+0

я сделал. Я также добавил необходимые изменения в make-файл. – Shookie

ответ

1

Я проверил эти SYSCALL хелперы, которые я написал для моего микро LIBC:

#define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) 
#define MKFN_N(fn, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n, ...) fn##n 
#define syscall(...) MKFNS(syscall,##__VA_ARGS__) 

static inline long syscall0(long n){ 
    unsigned long r; 
    asm volatile("int $128":"=a"(r):"a"(n):"memory"); 
    return r; 
} 

#define syscall1(n,a) _syscall1(n,(long)a) 
static inline long _syscall1(long n, long a){ 
    unsigned long r; 
    asm volatile("int $128":"=a"(r):"a"(n),"b"(a):"memory"); 
    return r; 
} 

#define syscall2(n,a,b) _syscall2(n,(long)a,(long)b) 
static inline long _syscall2(long n, long a, long b){ 
    unsigned long r; 
    asm volatile("int $128":"=a"(r):"a"(n),"b"(a),"c"(b):"memory"); 
    return r; 
} 

#define syscall3(n,a,b,c) _syscall3(n,(long)a,(long)b,(long)c) 
static inline long _syscall3(long n, long a, long b, long c){ 
    unsigned long r; 
    asm volatile("int $128" : "=a"(r):"a"(n),"b"(a),"c"(b),"d"(c):"memory"); 
    return r; 
} 

#define syscall4(n,a,b,c,d) _syscall4(n,(long)a,(long)b,(long)c,(long)d) 
static inline long _syscall4(long n, long a, long b, long c, long d){ 
    unsigned long r; 
    asm volatile("int $128":"=a"(r):"a"(n),"b"(a),"c"(b),"d"(c),"S"(d):"memory"); 
    return r; 
} 

#define syscall5(n,a,b,c,d,e) _syscall5(n,(long)a,(long)b,(long)c,(long)d,(long)e) 
static inline long _syscall5(long n, long a, long b, long c, long d, long e){ 
    unsigned long __ret; 
    __asm__ __volatile__ ("int $128" : "=a"(__ret) : "a"(n), "b"(a), "c"(b), "d"(c), "S"(d), "D"(e) : "memory"); 
    return __ret; 
} 

void exit(long a){asm volatile("int $128":"=a"(a):"a"(1),"b"(a):"memory");} 
extern char **environ; 

asm(".text\n" 
".global _start\n" 
"_start:\n" 
"popl %ecx\n" 
"movl %esp,%esi\n" 
"pushl %ecx\n" 
"leal 4(%esi,%ecx,4),%eax\n" 
"pushl %eax\n" 
"pushl %esi\n" 
"pushl %ecx\n" 
"movl %eax,environ\n" 
"call main\n" 
"pushl %eax\n" 
"call exit\n" 
"hlt\n" 
".Lstart:\n" 
".size _start,.Lstart-._start\n" 
); 

#define aservice(...) syscall(__NR_aservice,__VA_ARGS__) 
#define write(...) syscall(__NR_write,__VA_ARGS__) //#define __NR_write 4 

, то вы можете запустить простую тестовую программу, чтобы убедиться, что вы можете обрабатывать системные вызовы

int main(void){write(1,"hello world!\n",13);} 

компилировать с gcc -nostdlib -fno-builtin

Это позволит вам проверить, что вы можете получить доступ к системным вызовам, чтобы вы знали, является ли это вашим syscall или вашим способом доступа к ним, что является проблемой.

Смежные вопросы