1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/rcore-os-rCore-Tutorial

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
part-4.md 6.5 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 21:14 7f8a4fd

Реализация системного вызова

В настоящее время мы реализуем три простых системных вызова: sys_read, sys_write и sys_exit. Изучив их реализацию, становится понятно, что реализация других системных вызовов не представляет особой сложности.

Вызов системного вызова в пользовательской программе

Реализовать системный вызов в пользовательской программе довольно просто, подобно тому, как мы использовали sbi_call в операционной системе, нужно только передать параметры в соответствии с правилами. Более того, на этот раз нам даже не нужно ссылаться на какой-либо стандарт, каждый может реализовать свой собственный стандарт для своей операционной системы.

Например, в руководстве по эксперименту номер системного вызова использует кодировку и формат параметров из musl. Однако на самом деле при реализации операционной системы можно свободно настраивать кодировку и форматы параметров, главное, чтобы они соответствовали вызовам в пользовательских программах и интерпретации в операционной системе.

{% label %}Пример кода{% endlabel %}

// musl 中的 sys_read 调用 формата
llvm_asm!("ecall" :
    "={x10}" (/* 返回读取长度 */) :
    "{x10}" (/* 文件描述符 */),
    "{x11}" (/* 读取缓冲区 */),
    "{x12}" (/* 缓冲区长度 */),
    "{x17}" (/* sys_read 编号 63 */) ::
);
// Возможный формат вызова sys_read
llvm_asm!("ecall" :
    "={x10}" (/* текущее время */),
    "={x11}" (/* погода сегодня */),
    "={x12}" (/* прочитать один символ */) :
    "{x20}" (/* sys_read 编号 0x595_7ead */) ::
);

Руководство по эксперименту предоставляет первый скучный формат системного вызова.

Избегание состояния ожидания занятости

В распространённых операционных системах некоторые операции с большими задержками, такие как чтение и запись файлов или сетевое взаимодействие, могут использовать асинхронные интерфейсы. Однако для простоты реализации наши операции чтения и записи являются блокирующими. В sys_read используется loop, чтобы гарантировать возврат только после успешного чтения символа.

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

Реализация системного вызова в операционной системе

Реализация системного вызова в операционной системе похожа на обработку прерываний, у них одинаковый вход, а для разных параметров устанавливаются разные процессы обработки. Чтобы упростить процесс, мы можем разделить результаты обработки системных вызовов на три категории:

  • Возврат числового значения, продолжение выполнения программы;
  • Программа переходит в состояние ожидания;
  • Завершение программы.

Процесс обработки системного вызова

  • Сначала извлекается код вызова и параметры из соответствующих регистров;
  • В зависимости от кода вызова выполняется различный процесс обработки, получая результат обработки;
    • Возвращается числовое значение и продолжается выполнение:
      • Значение возврата сохраняется в регистре x10, sepc += 4, и продолжает выполнение текущего context;
    • Программа переходит в состояние ожидания:
      • Также необходимо обновить x10 и sepc, но текущий поток должен быть помечен как ожидающий, и другой поток должен быть запущен для выполнения;
    • Завершение программы:
      • Не нужно учитывать возврат системного вызова, просто удалите поток.

Конкретная реализация вызова

Как именно реализовать чтение / запись системных вызовов? Здесь мы будем использовать унифицированный интерфейс файлов INode и его интерфейсы read_at() и write_at(), которые могут быть использованы. В следующем разделе будет объяснено, как обрабатывать дескрипторы файлов.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/rcore-os-rCore-Tutorial.git
git@api.gitlife.ru:oschina-mirror/rcore-os-rCore-Tutorial.git
oschina-mirror
rcore-os-rCore-Tutorial
rcore-os-rCore-Tutorial
master