Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну тут я могу еще кое-что добавить. BCD операции, например. Но тогда они казались нужными, да и, видимо, совместимость с 8080 требовалась.
Нет, ну для периода примерно до Pentium они ещё имели какой-то смысл. Потом уже оказалось, что делать то же самое на бинарке крупными порциями (хотя бы по 2-3 цифры) уже выгоднее.
N>>- Почему в page table entry один бит на права на страницу, а не два согласно режимам? Они этим самым с ходу убили rings 1 & 2 даже для тех, кто хотел и мог их осмысленно использовать. PD>Потому что механизмы от 286 оказались ненужными. Фактически весь механизм защиты и адресации от 286 в 386 аннигилирован. Он остается, как же иначе, но по сути роли не играет, его программируют так, чтобы не мешал. А реально защита идет на страничном механизме. PD>Вспомни, зачем сделали 4 кольца. 0-е для ядра ОС, 1- для драйверов, так что их падение не приведет к падению ОС. 2- например, для DB engine. Ну и 3. И никто не стал в 286 процессоре это использовать. Равно как никто не стал использовать задачи процессора и переключение LDT. Идея оказалась невостребованной.
В 286 — по другой причине, что он сам был какой-то убогий и переходной — попытка фактически реанимировать iAPX432 поверх 8086.
А посмотри на VAX. Там 4 кольца используются на полную. Или сейчас на ARM, то же самое (с поправкой, что одно из них это гипервизор) и плюс по другой оси ещё "реалмы". Или на RISC-V, там три кольца плюс резерв для гипервизора (но они в итоге сделали иначе и PL2 просто не нужен).
А сами Intel сделали SMM, который по их нумерации получается номер -1.
Ну так стоило ли так грубо и тупо вырезать? Что, одного бита в свободной области было жалко? Там до сих пор есть резерв.
N>>- Почему для ring 0 форсирован маппинг? Ему это нафиг не надо, у него и так права на доступ ко всему физическому адресному пространству. PD>Это не понял. Что за форсирование маппинга ?
Всё просто. Если ты посмотришь на такую пачку архитектур, как MIPS, POWER, и даже SystemZ, то там можно (а в некоторых (было) обязательно), что в режиме супервизора маппинг (трансляция) виртуальных адресов в физические просто идемпотентна! То есть этот уровень работает в физических адресах. Ну просто нафиг ему не сдалось заниматься ещё и тем, что самому себе обеспечивать страничные каталоги, искать где их размещать и как правильно управлять, чтобы самому себе не вышибить почву из-под ног...
Если то, что называется Software-Managed Address Translation (гуглится, куча работ), то в этом случае все эти страничные каталоги и подкаталоги просто не существуют — это случай MIPS. Там супервизор командует напрямую кэшом трансляций (translation lookaside buffer (TLB) у большинства включая Intel). Но (у SystemZ) иерархия страничных каталогов в памяти, но супервизору трансляцию обычно отключают.
А у x86 эта трансляция если включена, то принудительно на всех. В результате получается куча костылей. Ты видел, как инициализируются современные ОС?
В одном из вариантов (очень долго был основным) сначала надо в нижнем мегабайте создать хотя бы один корневой каталог и один подкаталог 0 (первые 4MB в 32 битах). Именно там — потому, что до верхней памяти не добраться.
И они создаются с идемпотентной трансляцией.
Далее когда уже включили — можно сменить на другой каталог (а их надо делать для каждого процесса свой, если процесс не чисто ядерный).
Если надо перейти в реальный режим — тоже два этапа: сначала ужаться каталогами (а также GDT) в первый мегабайт, идемпотентно, и тогда отключать.
Сейчас больше используют unreal mode на 4GB и это не нужно в таком виде, больше свободы. Но чтобы переключиться потом в 64 бита, всё равно нужен ещё один прыжок режима.
И это я только про то, что видно процессору. А ещё надо структуры для самой ОС, где расписано, где она держит эти каталоги. И эти структуры тоже надо где-то держать. Если фиксированного места на них не хватает, задача становится ой нетривиальной — надо сделать так, чтобы собственные же структуры не затереть, не сдвинуть, если нельзя...
Пока писал, вспомнил ещё один момент. В Intel его тоже могли знать, потому что уже был VAX в полную силу доступен. Корневой каталог страниц свой на каждый процесс. Но если меняется маппинг для ядерной половины, его надо менять у всех процессов, на это есть особый контроль при переключении процесса. Что мешало сделать раздельные корневые каталоги хотя бы на две половины адресного пространства, и верхнюю не менять лишний раз? В VAX таких каталогов 4. В ARM сделали два каталога и управляемую границу между ними. Зачем x86 создал трудности на ровном месте?
PD>Все, в общем, верно. Но в основном совместимость. Ну что прикажешь делать с теми же CLI/STI ? В 86 один код, а в 386 другой ?
Нет. В 16-битном режиме (неважно, 8086, 386, Corei14...) один. В 32-битном (начиная с 386) другой. В 64-битном, возможно, третий.
Между ними и так существенная разница, и сделать различие в кодогенераторе и в декодере — только добавить к уже существующему.
PD> А SGDT вроде как еще от 286 пришла, и там был какой-то резон ее сделать непривилегированной. А может, и не было. Не подумали.
Я 101% уверен, что просто не подумали.
PD>А в целом — типичное "развивающее" решение. Это когда не делают как следует с нуля, а делают с оглядкой на предыдущие решения. Конечно, многое можно было сделать лучше. Но сама архитектура отнюдь не плоха, а это все же мелочи.
Ну _в общем и целом_, да, она не худшая. У неё достаточно гибкости, чтобы ещё конкурировать. Но при этом количество костылей, подпорок, ненужных и заброшенных частей ужасает.
PD>С другой стороны, когда Intel попробовала сделать с нуля "как следует" — получился Itanium.
Там другая история. Я уверен, что кому-то из топов хотелось, опять же, выстебнуться и зайти в историю. Иначе не объяснить, как заведомо нерабочая изначально концепция могла пойти в железо. А почему кто-то мог подумать, что она рабочая — потому что история с Rambus, которые пообещали избавление от основных причин, почему вообще нужен out-of-order.