XV6 - передать параметры системному вызову и получить возвращаемое значение - PullRequest
0 голосов
/ 19 июня 2020

Мне нужно написать системный вызов в XV6, который получает несколько целых чисел и несколько целочисленных указателей в качестве аргументов, и я не понимаю, как это сделать.
Я читал про argint и argptr, но я не понимаю, как их использовать. Например, я не понимаю, используются ли они как для передачи аргументов (в пользовательском пространстве) системному вызову, так и для их получения в sys_name (имя функции в sysproc.c.

Кроме того, мне нужна функция, чтобы возвращать значение, и я не знаю, как вернуться к значению обратно в пространство пользователя, где функция была вызвана.

1 Ответ

1 голос
/ 20 июня 2020

tldr:

Если вы вызвали свой системный вызов следующим образом some_syscall(42), все, что вам нужно сделать для доступа к 42, - это позвонить: argint(0, &local_var). Это сохраняет 0-й параметр int, 42, в local_var.

С argptr вам нужно указать ему адрес указателя и количество байтов памяти, которые вы хотите извлечь. Однако, поскольку указатель в 32-битной архитектуре составляет 4 байта, argint также выполнит эту работу.

Вот общее понимание того, как это работает:

argint обращается к параметры с некоторой математикой указателя. Он обращается к структуре trapframe процесса, содержащей регистры пользовательского пространства системного вызова. Trapframe сохраняет параметры функции, начиная с регистра esp. Он добавляет 4, чтобы пропустить пустое слово в стеке из некоторого преобразования, которое, как я считаю, является спецификацией xv6 c. 4*n означает, что вы можете получить доступ к n-му 4-байтовому параметру после начального адреса.

fetchint выполняет некоторую проверку ошибок и фактически сохраняет адрес по адресу, указанному этим *ip указателем.

// Fetch the nth 32-bit system call argument.
int
argint(int n, int *ip)
{
  return fetchint((myproc()->tf->esp) + 4 + 4*n, ip);
}

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

      curproc->tf->eax = syscalls[num]();

Этот github иногда очень полезен для понимания xv6: https://github.com/YehudaShapira/xv6-explained/blob/master/Explanations.md#getting -arguments-in-system-calls

...