Как работает ошибка сегментации (ядро/оборудование)? - программирование

Как работает ошибка сегментации (ядро/оборудование)?

В общем, мне интересно, как ядро ​​(или ЦП) знает, что процесс попытался получить доступ к ячейке памяти, для которой ему не хватает разрешения, и как таинственная часть аппаратного обеспечения, называемая MMU, помогает в этом.

В частности: мне кажется, что MMU агностически относится к модели управления памятью ядра ОС (подкачки, зоны памяти, пространства адресов процессов...) (я бы предположил, что страницы Linux и Windows не совсем например, исправьте меня, если я ошибаюсь). Но тогда, как мой процессор узнает, может ли текущий код получить доступ к местоположению x? И как это сигнализирует об этом ядру?

4b9b3361

Ответ 1

Это, вероятно, слишком большая тема, чтобы полностью удовлетворительно ответить на этот вопрос; вам лучше искать какие-либо документы/статьи/книги, в которых обсуждаются аппаратные средства реализации виртуальной памяти (возможно, начиная с конкретной архитектуры, поскольку существуют значительные различия между, например, x86, x86_64, sparc и т.д.).

Короткий ответ заключается в том, что аппаратное обеспечение обрабатывает это через таблицы страниц. Каждый доступ к памяти, к которому обращается MMU, проверяется через структуры таблицы страниц. Если запись в таблице страниц, описывающая страницу, содержащую запрашиваемый адрес, не помечена, чтобы разрешить запрашиваемый тип доступа (чтение/запись/выполнение/...), аппаратное обеспечение создает ловушку, которую Linux в конечном итоге вызывает "ошибку сегментации", Другие ОС называют их по-разному (например, общая ошибка защиты,...). Затем ядро ​​ОС должно выяснить причину ошибки и можно ли что-либо сделать с ней (многие ловушки обрабатываются ядром для обмена новыми страницами с диска, отображения новой пустой страницы и т.д., Но некоторые, например, null-pointer dereferences, лучшее, что может сделать ядро, это бросить его в приложение, чтобы сказать "вы сделали что-то плохое" ).

Ответ 2

MMU сконфигурирован (путем разработки его логических и/или опционных бит, установленных ядром), как аппаратная часть реализации модели поискового вызова.

MMU должен обычно переводить логические адреса на отображаемые физические адреса; когда он не может этого сделать, потому что не существует соответствующего физического адреса для запрошенного логического адреса, он генерирует ошибку (часто как тип прерывания), которая запускает код обработчика в ядре.

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

Однако, если это запрос для чего-то, чего не существует, он не может быть удовлетворен и должен быть обработан как ошибка программы.

Запрос на запись в то, где запись не разрешена, будет обрабатываться аналогичным образом.

Сверху моей головы я не уверен, что попытки выполнить неисполняемую информацию обнаруживаются в MMU или больше в самом CPU; как кэш команд, если он присутствует, может также усложнить ситуацию. Тем не менее, конечный результат был бы аналогичным - условие отказа для ядра, что была предпринята попытка незаконного выполнения, которую ядро ​​обычно рассматривало бы как ошибку программы.

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