Здравствуйте, Pavel Dvorkin, Вы писали:
m2l>>Нет. Таблицы трансляции работают через таблицы GDT/LDT — они часть общего механизма.
PD>Я с этим и не спорю, это верно. Вот только фактически все элементы LDT/GDT и в Windows, и в Linux настроены так, что база у низ 0, а лимит 4 Г. В принципе LDT и GDT могли бы иметь сегменты любого размера <4Гб и с базой от 0 до 4Г. В плоской же модели (flat) используется лишь вариант с 0 и 4 Г соответственно. Это и есть то, что я назвал обнулением. Конечно, LDT/GDT и сегментные регистры (Cs, DS...) никуда не делись, но поскольку каждый сегментный регистр показывает на элемент LDT/GDT с нулевой базой, то
Можно, я не буду запускать отладчик и делать дамп gdt/ldt, а просто спрошу — откуда ты это взял?
PD>CS16:OFF32 -> LDT/GDT -> OFS32
PD>то есть фактически линейный адрес (после преобразования по сегментному механизму) численно равен смещению с сегментированном адресе.
Ага. Как это мешает управлению адресным пространством через ldt? Что бы не быть голословным:
https://github.com/torvalds/linux/blob/master/arch/x86/kernel/ldt.c
GDT — указывает на PTE общие для всех процессов, LDT — указывает на таблицы PTE адресующие виртуальное адресатное пространство самого процесса.
m2l>>* Бит в PTE определяет кому страница принадлежит — программе или операционной системе, это немного другой механизм. Разделения на 4-ре кольца (в современных, учитывая SMM можно считать что и больше) так и осталось.
m2l>>* Байка о двух режимах идет от Windows NT, которая изначально разрабатывалась ещё под процессоры DEC и Alpha — а в одном из них защищенный режим (его не Intel придумал, а сделал аналог уже существовавших решений) был ограничен как-раз двумя уровнями. Отсюда и взялась эта унификация, когда всю систему уложили в 0 и 3 кольца. И то, спроектировано ядро так, что те-же драйверы устройств, изначально можно было вынести в ring 1 или ring 2. Эти элементы микроядра небыли использованы по большей мере из-за падения производительности.
PD>Это, скажем так, не вполне верно. Кольца остались, конечно, вот только 4 кольца механизма LDT/GDT проецируются на 2 режима механизма User/Supervisor. А именно, 3 кольцо есть User, все остальное — Supervisor. Но поскольку реально кольца 1 и 2 не использовались никогда, это никого не беспокоило тоже никогда, и все считают, что 0 — это Supervisor, 3- это User, а про 1 и 2 никто и не вспоминает.
Ты путаешь два совершенно разных механизма. Двухбитный DPL дошел до наших с четырьмя уровнями защиты. И он задаётся дескрипторами GDT/LDT. Тот бит в PTE о котором устанавливает флаг, доступности страницы только для супервизора DPL=0. И он дополняет механику четырех колец защиты тем что запрещает "обратное чтение". Т.е. без этого бита процесс с DPL=2 может прочесть/записать память с DPL=2 или DPL=3, но не может с DPL=1 или DPL=0. А с ним можно создавать страницы с DPL=3 и в адресатном пространстве процесса, которые доступны только из ring-0 — для хранения паролей, или криптографических ключей и т.д. По сути это самый первый прообраз защищенных анклавов. И то, что ты проецируешь его на механику DPL — это ошибка.
m2l>>* Сама идея одной GDT и многих LDT вполне себе живёт по сей день и в Windows и в Linux. Где ядро и драйверы работают в общем для всей остальной системы адресатном пространстве, а прикладные приложения в другой его части.
PD>Бог с тобой. Тут ты просто не разбираешься. Все в одном АП. Старшая часть (от 0x80000000 стандартно) отводится ядру, младшая — пользовательской части
PD>https://royallib.com/read/russinovich_mark/1vnutrennee_ustroystvo_Windows_gl_1_4.html#0
PD>см. рис 1.4
Я про это и говорю. Системная часть — адресуется через GDT, пользовательское адресатное пространство через LDT.
PD>А LDT вообще одна, я уже объяснил, как она используется.
Ага, особенно на многоядерных машинах LDT одна. Адресующая одни и те же таблицы PTE для всех адресатных пространств одновременно работающих процессов разом по твоему?
LDT не используется для управления многозадачностью через процессор в том смысле, что на каждый процесс не создается по дескриптору LDT в GDT — это дорого. Но при этом планировщик, при переключении процессов перезаписывает поля LDT, сохраняя старые значения как часть служебной информации о процессе и восстанавливая при обратном переключении. Выше я тебе дал ссылку на исходный код Linux занимающийся этим.
>>Для 32-разрядных систем тема с пределом в 2-гигабайта на процесс (3-и при соответствующей настройке) — много LDT именно из-за того, что оставшиеся 2-а (1-н) — общее для всей системы адресатное пространство ядра (GDT).
PD>Это уже чистая фантазия.
Исходный код выше. Любой отладчик ядра для Windows, благо в наше время с этим всё просто.
m2l>>PS. ИМХО ты не совсем понимаешь всю гибкость защищенного режима. Разнесение адресации на GDT/LDT/PTE позволяет допустим отправлять в своп куски памяти с неиспользуемыми сейчас фрагментами PTE/LDT. Разнесение GDT/LDT позволяет делать общее для всех программ адресатное пространство, без дополнительных действий для его поддержания (для Windows и Linux в нём находится ядро, драйверы, DMA и всё что относится к ядру). Применение раздельных LDT позволяет делать для двух процессов общую область памяти, которая у каждого отображена в свои адреса. И таких фишек — очень много. AMD когда делала x64-86 не просто так сохранила большую часть аспектов этой работы для long mode — им просто сложно найти адекватную замену.
PD>Все верно. Позволяет. Более того, он позволяет адресовать до 2^48 в 32-битном процессоре, разумеется, при отказе от flat-модели. Просто потому что SEG16:OFFS32 — это 48 бит.
PD>Вот только пока речи не идет о виртуальных машинах, все эти возможности не используются. Ни несколько LDT (все дескрипторы в одной LDT и все настроены на flat), ни переключение задач в смысле 80286 (это вообще, кажется, нигде не использовалось, а переключение проессов идет через CR3 страничного механизма.
Слушай, ведь лютейший же бред пишешь....
Ты же сам блин ссылаешься, у тебя под рисунком про AWE написано !?! Обычный прикладной интерфейс, к примеру SQL Server умеет им пользоваться. — Ну твоя же ссылка, вот прямо твой рисунок, ну прочитай один абзац текста.
Та же 48-битная адресация — берешь 32-битную Windows и запускаешь в ней отдельные процессы жрущие память. Каждый по отдельности — не более 2 Гб (3 при настройке параметров загрузки). А все вмести — начнут свопится только когда физическая память закончится. Windows с помощью этой адресации 2 ГБ памяти каждого процесса раскидает и на 4 и на 24 и на 48 гигабайт физической памяти. Нет тут никаких отказов ни от каких моделей — это совершенно штатные вещи.