В образовательных целях я хочу реализовать системный вызов в Debian Wheezy. Я хочу реализовать его в ядре, которое входит в пакет linux-image-3.2.0 - rt-amd64. Вот обзор того, что я пробовал:
Чтобы получить исходный код ядра:
apt-get source linux-image-3.2.0-4-rt-amd64
Из этого я получаю следующие файлы / каталоги, в которых я выполнил:
linux_3.2.41.orig.tar.xz
linux_3.2.41-2+deb7u2.dsc
linux_3.2.41-2+deb7u2.debian.tar.xz
а также:
linux_3.2.41
который содержит исходный код ядра.
Затем, чтобы внести необходимые изменения для добавления системного вызова, я в основном перешел на эту страницу: Как писать системные вызовы в debian / ubuntu
Ниже приводится сокращенная версия приведенных здесь инструкций, измененных для отражения внесенных мною изменений.
+ Файл 1: linux-x.x.x / vpart_syscalls / vpart_syscalls.c
#include <linux/linkage.h>
#include <linux/kernel.h>
asmlinkage long insert_partition(char*dest, const char* src)
{
printk("<--- the syscall has been called!");
return 0;
}
Файл 2: linux-x.x.x / vpart_syscalls / Makefile. Создайте Makefile в том же тестовом каталоге, который вы создали выше, и поместите в него эту строку:
obj-y := vpart_syscalls.o
Файл 3: linux-x.x.x / arch / x86 / kernel / syscall_table_32.S. Теперь вам нужно добавить свой системный вызов в таблицу системных вызовов. Добавьте в файл следующую строку:
.long insert_partition
Файл 4: linux-x.x.x / arch / x86 / include / asm / unistd_32.h
В этом файле имена всех системных вызовов будут связаны с уникальным номером. После последней пары системного вызова и номера добавьте строку
#define __NR_insert_partition 349
Затем замените значение NR_syscalls, указав общее количество системных вызовов на (существующее число увеличено на 1), т.е. в этом случае NR_syscalls должно было быть 338, а новое значение - 339.
#define NR_syscalls 350
- Файл 5: linux-x.x.x / include / linux / syscalls.h
Добавляем в файл прототип нашей функции.
asmlinkage long insert_partition(int lenTicks, int vpid);
непосредственно перед строкой #endif в файле.
- Файл 6: Makefile в корне исходного каталога.
Откройте Makefile и найдите строку, в которой определено core-y, и добавьте тест каталога в конец этой строки.
core-y += kernel/ mm/ fs/ test/ vpart_syscalls/
Затем я приступил к сборке ядра другим способом, нежели описано здесь:
make localmodconfig
make menuconfig (making no changes)
make-kpkg clean
fakeroot make-kpkg --initrd --append-to-version=+tm kernel_image kernel_headers
cd ..
dpkg -i linux-image-3.8.*
dpkg -i linux-headers-3.8.*
Установленное ядро загружается нормально. Я сделал следующую программу на c для проверки системного вызова:
#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
int main(){
printk("Calling the new syscall!\n");
int ret = 100;
ret = syscall(349, 1, 2);
printf("call return value: %i\n", ret);
return 0;
}
Когда я компилирую и запускаю эту программу, я получаю возвращаемое значение -1. Я проверяю сообщения с помощью dmesg, и нет никаких доказательств того, что мой printk был вызван ..
Если кто-нибудь знает, в чем моя проблема, я был бы очень счастлив! Я должен сказать, что у меня нет большого опыта в изменении и сборке ядра, но я многое узнал об этом. Я прочитал книгу Роберта Лавса - разработка ядра Linux и несколько руководств в Интернете.
uname -a
. Кроме того, вы можете проверить свой тест с помощьюfile -k ./test_name
(для проверки 32/64-битного режима программы) иstrace ./test_name
, чтобы увидеть, был ли вызван системный вызов, какие были аргументы и возвращаемое значение (strace должен сообщатьsyscall_349
для вашего системного вызова). - person osgx   schedule 26.05.2013