Если бы вы подписались на мой предыдущий пост в блоге, вы бы уже имели представление об операционной системе xv6. Однако, чтобы проинформировать новых читателей, xv6 - обучающая операционная система, разработанная MIT. Этот блог - вторая фаза серии хаков, о которых я собираюсь написать при использовании ОС xv6.

Что такое системный вызов?

Как вы все знаете, операционная система поддерживает два режима; режим ядра и пользовательский режим.

Когда программе в пользовательском режиме требуется доступ к ОЗУ или аппаратному ресурсу, она должна попросить ядро ​​предоставить доступ к этому конкретному ресурсу. Это делается с помощью системного вызова. Когда программа выполняет системный вызов, режим переключается из пользовательского режима в режим ядра.

В операционной системе существует множество системных вызовов, которые при вызове выполняют различные типы задач.

Добавление пользовательского системного вызова в xv6

Чтобы определить свой собственный системный вызов в xv6, вам необходимо внести изменения в 5 файлов. А именно эти файлы выглядят следующим образом.

1. syscall.h
2. syscall.c
3. sysproc.c
4. usys.S
5. user.h

Давайте напишем системный вызов, чтобы узнать год выпуска Unix версии 6.

Мы бы начали процедуру с редактирования syscall.h, в котором каждому системному вызову присваивается номер. Этот файл уже содержит 21 системный вызов. Чтобы добавить пользовательский системный вызов, в этот файл необходимо добавить следующую строку.

#define SYS_getyear 22

Далее нам нужно добавить указатель на системный вызов в файле syscall.c. Этот файл содержит массив указателей функций, в котором указанные выше числа (индексы) используются в качестве указателей на системные вызовы, определенные в другом месте. Чтобы добавить наш собственный системный вызов, добавьте в этот файл следующую строку.

[SYS_getyear] sys_getyear,

Что именно здесь происходит?

Основное значение двух вышеупомянутых изменений заключается в следующем.

  • Когда системный вызов с номером 22 вызывается пользовательской программой, указатель на функцию sys_getyear с индексом SYS_getyear или 22 вызовет функцию системного вызова.

Следовательно, нам необходимо реализовать функцию системного вызова. Однако мы не реализуем функцию системного вызова в файле syscall.c. Вместо этого мы добавляем сюда только прототип функции и определяем реализацию функции в другом файле. Прототип функции, который необходимо добавить в файл syscall.c, выглядит следующим образом.

extern int sys_getyear(void);

Далее мы реализуем функцию системного вызова. Для этого откройте файл sysproc.c, в котором определены функции системного вызова.

// return the year of which the Unix version 6 was released
int
sys_getyear(void)
{
return 1975;
}

На этом базовая реализация системного вызова завершена. Однако осталось еще 2 второстепенных шага.

Добавьте интерфейс для системного вызова

Чтобы пользовательская программа могла вызвать системный вызов, необходимо добавить интерфейс. Поэтому нам нужно отредактировать файл usys.S, где мы должны добавить следующую строку.

SYSCALL(getyear)

Далее необходимо отредактировать файл user.h.

int getyear(void);

Это будет функция, которую вызывает пользовательская программа. Эта функция будет сопоставлена ​​системному вызову с номером 22, который определен как директива препроцессора SYS_getyear.

Если вы выполнили все вышеперечисленное, вы успешно добавили новый системный вызов в xv6. Однако, чтобы проверить его функциональность, вам нужно будет добавить пользовательскую программу, которая вызывает этот системный вызов.

Программа пользователя может быть следующей.

#include “types.h”
#include “stat.h”
#include “user.h”
 
int
main(void)
{
printf(1, “Unix V6 was released in the year %d\n”, getyear());
exit();
}

Чтобы добавить эту пользовательскую программу в xv6, вам необходимо выполнить несколько шагов. Если вы не знакомы с добавлением пользовательской программы в xv6, обратитесь, пожалуйста, в этот блог.

Последним шагом будет запуск пользовательской программы в окне qemu, которое можно получить, выполнив команду make qemu на терминале.

1975 год должен отображаться на терминале, если ваш системный вызов был правильно добавлен в xv6.

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

Благодарю вас!