Доброе время суток! У меня вопрос - какая модель луче: сегментная или Flat, пожалуйста, обширной ответ! Еще вопрос - как делать gdt и ldt при выбранной модели? За любой ответ или инфу - буду очень благодарен! Заранее всём спасибо!
я так понял, что flat модель луче использовать (помню кто-то такое говорил, но точно не уверен, поэтому и решил спросить) - если может доки по этой модели?
использование сегментной модели оправдано разве что для реализации механизма защиты данных от интерпретации их как кода на системах, где нет поддержки Execute Disable Bit еще из плюсов - возможность аппаратной защиты от переполнения стека (#SS и все такое) flat модель более проста в использовании и хорошо ложится на 2-ух уровневую модель построения ОС (использование 2-ух уровней привелегий) кроме того, в 64-х разрядных системах сегментация очень сильно ограничена аппаратно
rei3er Не просто ограничена, а вообще фактически упразднена: нету там больше сегментов как таковых. AntiB Плоская модель намного проще и "естественнее", и никаких "доков" там не нужно. Создаётся она элементарно: в GDT формируются два дескриптора (один для доступа на чтение-выполнение, другой -- на чтение-запись), у которых установлен базовый адрес 0 и предел -- все единицы, т.е. длина сегмента -- 4 Гб. После этого селекторы этих сегментов загружаются в сегментные регистры (в CS -- тот, который чтение-выполнение, а в остальные -- тот, что чтение-запись) -- и всё. Про сегментные регистры с этого момента можно забыть, доступ к памяти осуществляется с помощью одного лишь 32-разрядного смещения. rei3er упомнянул, что Тут могу добавить, что в общем-то он прав, однако сама надобность в такой защите возникает из-за кривизны и прикладных программ, и осей -- спасибо Си с его дурацкими библиотечными функциями, допускающими возможность переполнения буфера. Эту ошибку использует множество всевозможных злобных вирусов и прочих червяков, чтобы внедриться на компутеры несчастных юзверей Если же преполнение буфера исключено алгоритмически (объём вводимых данных жёстко ограничен размерами буфера и контролируется соответствующими подпрограммами ввода-вывода на уровне системы и библиотек языков программирования), тогда этой проблемы попросту практически нет. Остаётся только возможность случайной передачи управления в сегмент данных, что, естественно, приведёт к ошибке, но не менее вероятен ошибочный переход прямо в сегменте кода -- вызов не той подпрограммы, например.
Сегментная модель памяти плоха тем, что приходится использовать FAR pointers, а это - перезагрузка селекторов, достаточно длительный процесс.
я имел в виду GS.base и FS.base вообще говоря сегменты никуда не делись они как были так и есть, просто при вычислении линейного адреса база интерпретируется как 0, а лимит не используется
Всём большое спасибо! Особенно SII и небольшой проверочной вопрос - если флат, то тогда в GDT создается тока два дескриптора и их используют всё программы или для каждой создается по два?
AntiB Дескрипторов можно создавать сколько угодно, но если уровня привелегий используется два, то понадобится 4 дескриптора: 1. Код кольца 0. 2. Данные кольца 0. 3. Код кольца 3. 4. Данные кольца 3. В принципе, и можно использовать один и тот же дескриптор данных что для кольца 0, что для кольца 3 (с DPL = 3, естественно). Помимо этого надо иметь хотя бы один TSS для переключения между уровнями привилегий.
AntiB И про IDT не забыть. Кстати, TSS надо инициализировать ДО установки указателя стека защищённого режима, иначе происходит вылет (убедился на собственном опыте). Реально в TSS необходимо устанавливать лишь поля, хранящие SS:ESP для используемых уровней привилегий.
SII С IDT мне уже помогли разобраться а вот с TSS еще даже не начинал - так, что всё еще впереди, кстати - спасибо за подсказку
небольшой вопрос, например, есть код: Код (Text): mov eax, cr0 or al, 1 mov cr0, eax ???? pm_entry: что мне надо сделать вместо ???? чтобы сделать перезагрузку регистра, например у меня есть дескриптор 0x08 с базой 0 и лимитом в 4 ГБ, я так понимаю, нужна сделать jmp на физический адрес pm_entr ??
Mika0x65 Вот в том-то и дело, что в явном виде я на это дело в мануалах тоже не натыкался. Ну, сделал себе переключение в защищённый режим, установил DS и ES (на плоскую модель, есно) и для проверки решил вывести сообщение прямо в видеопамять. Всё сработало. Ну а потом решил сделать то же самое через собственную подпрограмму -- и получил вылет компа на перезагрузку... Стал копаться в приведённом в мануале примере по переключению в защищённый режим и обратил внимание, что после переключения в защищённый режим (строка 177 листинга в мануале) и до загрузки регистра задачи (строка 277) SS не загружается, он загружается лишь в строке 285. После этого я у себя вставил инициализацию TSS и загрузку его адреса в регистр задачи -- и всё заработало. AntiB Надо длинный JMP сделать (ну или нечто аналогичное). Конкретный синтаксис зависит от используемого транслятора ассемблера. n0name Стек -- это данные, а значит, доступен через тот же селектор, что и сегмент данных.
SII Интересно, я у себя в переключении в PM не наблюдал. SS инициализирую сразу же. А можно исходник того переключения?
Mika0x65 Он уже переправленный, копию не сохранил... А твой можно, где ты SS инициализируешь до загрузки регистра задачи?
я бы еще фиктивный LDT дескриптор в GDT поместил и указал бы его селектор в поле LDT TSS'а просто сам сталкивался с проблемой которая таким способом решилась конечно если Expand Down не используется
rei3er Это вполне можно сделать, но, строго говоря, можно обойтись и без этого, почему я и не упомянул в списке обязательных действий. Можно моделировать с помощью страниц. Собственно, Винда добавляет страницы стеку по мере надобности.