Основной вопрос: Как сохранить кадр потока ядра при вызове функции ядра, как это делается в системных вызовах из пространства пользователя? Я хочу время от времени планировать 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;
}
Если это не ясно, пожалуйста, укажите. Спасибо!