Как сделать системный вызов с INT из кольца 0 (поток ядра)? - PullRequest
0 голосов
/ 24 октября 2019

Основной вопрос: Как сохранить кадр потока ядра при вызове функции ядра, как это делается в системных вызовах из пространства пользователя? Я хочу время от времени планировать kthread и хочу, чтобы он продолжал выполнение с того места, где он ушел.

Дольше: я реализовал 64-битное ядро, которое может выполнять многопоточность на основе JOS-фреймворка. Я хочу добавить потоки ядра для выполнения операций подкачки в фоновом режиме. Чтобы запланировать поток ядра как другие задачи, я хочу сохранить кадр kthread при вызовах функций ядра. Моим первоначальным решением было использовать INT, как это было сделано из пространства пользователя. Как я могу сделать прерывание системного вызова от 0 до 0 (с INT / IRETQ), сохранив фрейм и изменив его на использование стека ядра?

Поток ядра работает в кольце 0. При использовании существующего системного вызовакод (показан ниже) с инструкцией INT, я могу сделать системный вызов, но операция выполняется на стеке вызывающего kthread, потому что значение% RSP является тем же. По сути, поток вызывает INT 0x80, он переходит к соответствующей функции в пространстве ядра (он уже был в пространстве ядра), но все эти операции выполняются в стеке потока ядра.

.global do_ksyscall
do_ksyscall:
    pushq %rbp
    movq 0x10(%rsp), %rbp
    int $INT_SYSCALL
    popq %rbp
    retq

Вариант использования этогопоказано ниже:

void kthread_swap() {
  page = get_page();
  disk_write(page);
  // Yielding now
  // With current implementation of do_ksyscall
  // this will go to correct function
  // but the RSP will be the same of this thread
  // instead it should change to kernel stack somehow
  sched_yield(); // Don't block while waiting
  // Should continue from here
  int res = disk_poll();
  if res ok kill(0);
  else throw err;
}

Если это не ясно, пожалуйста, укажите. Спасибо!

...