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

OSCHINA-MIRROR/rcore-os-rCore-Tutorial

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

Обработка файловых дескрипторов

Хотя это и не похоже, но в большинстве операционных систем стандартные потоки ввода-вывода stdin и stdout, хотя и называются «потоками», имеют интерфейс файла. Мы также будем реализовывать их как файлы.

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

Файлы, открытые процессом

Операционная система должна поддерживать список файлов, открытых процессом. Среди них обязательно есть stdin, stdout и stderr. Для простоты мы реализуем только stdin и stdout, их значения файлового дескриптора равны 0 и 1 соответственно.

stdout

Поток вывода очень прост: каждый раз, когда встречается системный вызов, символы из буфера напрямую выводятся через SBI-вызов.

stdin

Ввод потока более сложен: каждый раз при встрече системного вызова он получает символы через прерывание или опрос: если есть, то продолжает получать; если нет, то ждёт. Возвращается только после получения строки согласованной длины.

Внешние прерывания

Для пользовательской программы внешний ввод — это данные, которые активно считываются в любое время. На самом деле внешний ввод обычно краток и не ждёт, операционная система должна немедленно обработать его и буферизовать, а затем ждать, пока программа прочитает его. Поэтому каждая клавиша на клавиатуре является кратковременным прерыванием для операционной системы.

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

{% label %}os/src/interrupt/handler.rs{% endlabel %}

/// Инициализация обработки прерываний
///
/// Записывает `__interrupt` в `stvec`, и включает обработку прерываний
pub fn init() {
    unsafe {
        extern "C" {
            /// Входной прерывающий вызов в `interrupt.asm`
            fn __interrupt();
        }
        // Используем прямой режим, устанавливаем входное прерывание на `__interrupt`
        stvec::write(__interrupt as usize, stvec::TrapMode::Direct);

        // Включаем внешние прерывания
        sie::set_sext();

        // В OpenSBI включаем внешние прерывания
        *PhysicalAddress(0x0c00_2080).deref_kernel() = 1 << 10;
        // В OpenSBI включаем последовательный порт
        *PhysicalAddress(0x1000_0004).deref_kernel() = 0x0bu8;
        *PhysicalAddress(0x1000_0001).deref_kernel() = 0x01u8;
    }
}

Здесь нам нужно настроить в соответствии с интерфейсом OpenSBI в указанном адресе. Хорошо, что эти адреса находятся в пространстве отображения файловой системы, поэтому нам не нужно создавать отдельное отображение памяти для них. После включения обработки прерываний любое нажатие клавиши приведёт программу к области unimplemented!.

Реализация потока ввода

Потоку ввода требуется буфер, который мы можем реализовать с помощью alloc::collections::VecDeque. При возникновении прерывания клавиатуры вызывается sbi_call для получения символа и добавления его в буфер. Когда встречается системный вызов sys_read, соответствующее количество символов извлекается из буфера.

Что делать, если встречается sys_read, а в буфере нет данных для чтения? Как сделать так, чтобы поток ждал, не тратя ресурсы процессора?

Опубликовать ( 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