Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Соединил твои ответы, чтобы дать один свой
PD>Страничный и сегментный механизмы связаны, и вот как
PD>Адрес-то формально 48 битный, то есть 16:32. Другое дело, что реально 0:32, то есть flat model. Ну а если все же кто-то решил бы делать адресацию на 16:32 ? Не запретишь.
Да
нету там адресации 16:32.
Было 2^14 (два бита ушли на RPL) сегментов умножить на 2^32 адресов, и тут же из них сделали один 32-битный "линейный", в котором вся информация о том, какой сегмент использовался, тупо выброшена. Всё, её нету. И уже из этих 32 бит линейного делают 32 бита физического независимо от того, какой сегмент это был.
Или даже если делается 36 бит физического (PSE36), то всё равно из 32 логических.
Или если page fault, то информация о сегментации потеряна, обработчик page fault тоже ничего не знает, из какого сегмента это пришло. Даже если бы он восстановил это разбирая команду, на которой фолт, то в TLB он не сможет ничего занести.
Поищи видео по словам "lost in mirror maze". Вот этот самый лабиринт зеркал — это максимум, что у тебя получится. До 2^14 отражений кусков одного и того же пространства.
Поэтому это просто красивый пшик...
Опять же, сравни с SystemZ — где сделано без потери данных. Есть address space number (ASN) — параметр: для юзерского приложения равен 1 — primary (для 99% обычных приложений только оно используется), 2 — secondary, >=3 — прочие. Есть методы (хоть местами странные) систематически ходить через другой ASN. У каждого ASN своё дерево страничных каталогов. И когда лукап отработан железом, то ASN выбирает, какой физический адрес страницы. А если ушло в обработчик (страницы нет, писать нельзя, и т.п.), обработчик получает напрямую, какой ASN был, и может в зависимости от этого подключить что ему угодно и как ему угодно, и в TLB эта информация сохраняется. Вот это уже действительно честное виртуальное 47-битное пространство (16:31) в S/370...S/390, и 80-битное (16:64) в z/Architecture (расширенная до 64).
(Почему 31, а не 32, позволялось для адреса — я не нашёл с ходу, потом надоело искать. По сути неважно.)
PD>CS1 base = 0, limit = 1 MB, ring 0
PD>CS2 base = 1MB limit = 1 MB, ring 3
PD>CS3 base = 2MB limit = 1 MB, ring 0
PD>CS4 base = 3MB limit = 1 MB, ring 3
[...]
PD>Так что зафиксировать деление 32-битного на 2 части просто нельзя.
Не просто можно, а это постоянно и делали. Если у тебя все страницы со старшим битом линейного адреса равным 0 (если вообще существуют) имеют права доступа пользователя, а 1 — супервизора. Сейчас в 64 битах повторяется то же самое с поправкой на используемую длину виртуального (линейного) адреса (48 или 57 бит).
А то, что ты показал считалочку с сегментами — "перемножается" на это: имеют значение в итоге минимальные права из двух источников. Если тебе дали сегмент с правом доступа юзера (ring 3) но на адрес, через страничный механизм доступный только супервизору (считаем, ring 0) — всё, доступа нет.
Да, эта сегментная хрень по факту легаси и уже не использовалась никем в здравом уме и твёрдой памяти — именно поэтому AMD в long mode просто вырубило нафиг это, ничего не потеряв. Да, у дескриптора остаётся DPL, которое задаёт, с какими правами вообще это исполнять (kernel vs. user), и L (исполнять в 32 или 64 битах). Остальные бесполезны.
И при наличии прав доступа через страницы такие же механизмы для не-кодовых сегментов вообще теряют смысл — поэтому в реальных ОС в long mode в DS/ES/SS грузится одно и то же значение — "всем всё можно". (Базовый адрес и длину там и так процессор игнорирует.)
PD> Когда нет этого сегментного механизма — тогда мы изначально имеем дело с 32-битным пространством, в нем правило деления на части можно определить, а тут, увы...
См. выше. При правах доступа по страницах, доступных в принципе (i386 и далее) или единственно оставшихся (amd64) — это уже бесполезно или недоступно. Ну а то, что сегментация показывает внутрь того же адресного пространства, и делает её бесполезной.
PD>>>Другое дело, что вообще-то можно было совсем отказаться от сегментных регистров в 32 битном режиме. Кстати, где-то я читал, что при переходе к 64-битному от них хотели отказаться, но возникли какие-то проблемы с виртуальными машинами. Пруф не дам.
PD>Увы, где-то прочитал, где- не помню, так что ссылку дать не могу.
Меня в этом удивило именно то, что "с виртуальными машинами".
В этой архитектуре битность режима выполнения определяется тем, что загружено согласно селектору в CS — в соответствующем месте в памяти в слове было указание, 16 или 32. Ломать этот механизм совсем было бессмысленно. Поэтому на него же нагрузили включение 64-битного режима, и это выглядит достаточно оптимальным — в пределах уже сделанного извращения
А вот с виртуальными машинами важнее, думаю, только то, что раз в них исполняются системы любой древности (хоть PC-DOS 1.0), то должно было работать всё, что поддерживали предыдущие процессоры. Но это и так примерно очевидно.