Системы с базовой виртуальной адресацией
Часто ОС, работающие на таких архитектурах, умеют сбрасывать на диск образы тех процессов, которые долго не получают управления. Это самая простая из форм своппинга (swapping – обмен) (русскоязычный термин "страничный обмен" довольно широко распространен, но в данном случае его использование было бы неверным, потому что обмену подвергаются не страницы, а целиком задачи).
Решив перечисленные выше проблемы, мы создаем другие, довольно неожиданные. Мы оговорили, что базовый регистр недоступен прикладным задачам. Но какой-то задаче он должен быть доступен! Каким же образом процессор узнает, исполняет ли он системную или прикладную задачу, и не сможет ли злонамеренная прикладная программа его убедить в том, что является системной?
Другая проблема состоит в том, что, если мы хотим предоставить прикладным программам возможность вызывать систему и передавать ей параметры, мы должны обеспечить процессы (как системные, так и прикладные) теми или иными механизмами доступа к адресным пространствам друг друга.
На самом деле, эти две проблемы тесно взаимосвязаны – например, если мы предоставим прикладной программе свободный доступ к системному адресному пространству, нам придется распрощаться с любыми надеждами на защиту от злонамеренных действий пользователей. Раз проблемы взаимосвязаны, то и решать их следует в комплексе.
Стандартное решение этого комплекса проблем состоит в следующем. Мы снабжаем процессор флагом, который указывает, исполняется системный или пользовательский процесс. Код пользовательского процесса не может манипулировать этим флагом, однако ему доступна специальная команда. В различных архитектурах эти специальные команды имеют разные мнемонические обозначения, далее мы будем называть эту команду SYSCALL. SYSCALL одновременно переключает флаг в положение "системный" и передает управление на определенный адрес в системном адресном пространстве. Процедура, находящаяся по этому адресу, называется диспетчером системных вызовов (рис. 4.20).
Возврат из системного вызова осуществляется другой специальной командой, назовем ее SYSRET. Эта команда передает управление на указанный адрес в указанном адресном пространстве и одновременно переводит флаг в состояние "пользователь". Необходимость выполнять эти две операции одной командой очевидна: если мы сначала сбросим флаг, мы потеряем возможность переключать адресные пространства, а если мы сначала передадим управление, никто не может нам гарантировать, что пользовательский код добровольно выйдет из системного режима.
Рис. 4.20. Диспетчер системных вызовов
Протокол общения прикладной программы с системой состоит в следующем: программа помещает параметры вызова в оговоренное место – обычно в регистры общего назначения или в стек – и исполняет SYSCALL. Одним из параметров передается и код системного вызова. Диспетчер вызовов анализирует допустимость параметров и передает управление соответствующей процедуре ядра, которая и выполняет требуемую операцию (или не выполняет, если у пользователя не хватает полномочий). Затем процедура помещает в оговоренное место (чаще всего опять-таки в регистры или в пользовательский стек) возвращаемые значения и передает управление диспетчеру, или вызывает SYSRET самостоятельно.