Виртуальная, Линейная, Физическа память: давайте разберемся

Тема в разделе "WASM.BEGINNERS", создана пользователем CuriosDroid, 19 ноя 2011.

  1. CuriosDroid

    CuriosDroid New Member

    Публикаций:
    0
    Регистрация:
    19 ноя 2011
    Сообщения:
    5
    Прочитал статью про витуальную память IA-32: http://www.wasm.ru/article.php?article=pipm10. Стало немного понятнее.
    Но к сожалению пазл в голове собрался не до конца, есть некие сомнения которые корёжат мозг, а смутило меня упоминание PAE, всякие GDT, LDT и страничная организация памяти. Помогите пожалуйста, ниже я сформулирую утрверждения, прокоментируйте их пожалуйста:

    - Виртуальное пространство - оно одно и равно оно 64 ТБ. Все инструкции процессора работают именно с ним (давайте не будет рассматривать разные схемы адресации ибо в коннечно итоге это всеравно SEG:смещение)

    - Линейное пространство - их много, каждое по отдельности 4 ГБ, всего их может быть теоритически до 214, практически ограниченно размерами GDT/LDTs.

    - Линейных пространств в процессорах IA-32 много только тогда, когда включена страничная организация памяти.

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

    - Если страничная организация памяти не включена, то больше 4ГБ никак не адресуешь. Ну либо нужно в дискрипторы добавлять разряды базовому адресу.
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    CuriosDroid
    Всё неверно. И в статье по ссылке соответственно тоже. Виртуальное адресное пространство (множество виртуальных адресов) — понятие, определяемое ОС, применяемое к процессам (т.е. по сути полное название — виртуальное АП процесса). Например, в 32-битной Windows виртуальный адрес всегда имеет размер 32 бита, поэтому размер виртуального АП для любого процесса (для каждого процесса своё) — 4 ГБ.
    С точки зрения ОС (Windows) инструкции работают с 32-битными виртуальными адресами. С точки зрения процессора с 48-битными логическими.
    Во-первых, не SEG:смещение, а селектор:смещение, а во-вторых, это не виртуальный, а логический адрес — понятие, определяемое Intel, а не ОС.
    Если я правильно понял утверждение, под количеством линейных АП подразумевается количество дескрипторов в защищённом режиме (но линейное АП существует точно так же и в реальном режиме). В противном случае непонятно, насколько различными считать перекрывающиеся линейные АП. Так вот количество различных дескрипторов даже практически не ограничено размерами GDT и LDT, т.к. не обязательно хранить все дескрипторы в этих таблицах, а можно подгружать в нужную таблицу при необходимости. Соответственно даже практически их может быть более 214.
    Линейный адрес и линейное АП не имеют никакого отношения к страничной организации (пэйджинг). Включение пэйджинга вносит понятие виртуальной памяти и, обычно с точки зрения ОС, виртуального адреса и виртуального АП.
    Здесь перепутано понятие линейного и виртуального АП. Процессы имеют свои виртуальные АП, а не линейные. Но это уже относится к ОС, а не к процессору. Через cr3 транслируется, конечно, линейный адрес, всегда численно равный виртуальному адресу ОС (Windows).
    Опять таки, нет такого понятия "линейный адрес в процессе", т.к. процесс — понятие, относящееся к ОС, а линейный адрес — понятие, относящееся к IA-32. Если речь о виртуальных адресах, то они не просто могут совпадать, они всегда совпадают (все 2^32 различных виртуальных адреса есть в каждом процессе). Что может совпадать, а может и не совпадать — это физические адреса, на которые транслируются виртуальные адреса различных процессов.
    Через таблицы страниц совпадающие линейные адреса транслируются на различные физические адреса независимо от разрядности шины.
     
  4. CuriosDroid

    CuriosDroid New Member

    Публикаций:
    0
    Регистрация:
    19 ноя 2011
    Сообщения:
    5
    to Y_Mur

    да действительно грандиозное обсуждение, проблема в том, что 90% времени тратиться на выяснения "понятий". И просвета этому нет. А хотелось бы все таки продвинуться дальше в обсуждении и перейти к обсуждению свойств этих "понятий".

    Сами же понятия мне кажется очень хорошо ввел Broken Sword в свой статье.

    to l_inc

    Так сказать "ну понеслось...". Хорошо, давайте обсуждать понятия. Щас полезу в интеловскую документацию, раз все так запутанно... по результатам отпишусь.
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    CuriosDroid
    Тем не менее изначально вопрос сформулирован именно про "понятия" :))

    Если же интересуют всё таки практически значимые свойства - то сегментами ты можешь адресовать в пределах 4Гб, размещать эти сегменты можешь в этих пределах как угодно, но если "хвост" сегмента вылезет за пределы этих 4Гб то он переотобразиться на младшие адреса. Адресовать с помощью механизма сегментов свыше 4Гб нельзя ни при каких условиях.

    Страничный механизм собственно ставит соответствие между адресом сформированным с помощью сегментной моделью и реальной физической памятью. Т.е. "сегментный" адрес может указывать "в никуда", а может на реальную память. Можно по одному и тому же адресу (сегментному) поочерёдно подставлять разные страницы памяти. Это используется для:
    - разделения адресных пространств разных программ,
    - адресации памяти если её физически больше 4Гб (но не более 64Гб)
    - "виртуального" увеличения объёма памяти за счёт использования диска или других носителей информации - это увеличение теоретически безгранично т.е. ограничивается только размерами диска или особенностями программного менеджера памяти.
     
  6. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    CuriosDroid, многие из утверждений некорректны. Чтобы получить правильные ответы на большинство из этих утверждений, нужно четко представлять порядок трансляции логического адреса:

    1) логический адрес;
    2) линейный адрес (он же виртуальный при включенном пэйджинге) - 32-разрядный, 48-разрядный (в расширенном режиме);
    3) физический адрес - 32-разрядный, 36-разрядный (PSE-36) или 36+ (PAE) - строго 36, если нельзя получить размерность физического адреса.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Лучше говорить "численно равный виртуальному", т.к. понятие виртуального адреса в отличие от понятия виртуальной памяти вводится ОС, а не Intel (в интеловской документации Вы про виртуальные адреса не найдёте, только про линейные).
     
  8. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Это всего лишь слова. Эти понятия не обще приняты. Но достаточно широко распространены в определённых кругах.
    Надо сказать что в одной области они могут означать одно, а в другой другое. Также иногда используется определение в широком смысле, а иногда в узком. Дополнительную путаницу вносит, то что частные области тесно связаны. Поэтому в текстах с одной тематикой могут использоваться разные определения.


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

    Теперь про частные области(в узком смысле). Виртуальный адрес имеет определённое понятие в ОС Windows, это понятие определено для процесса.

    Также виртуальный адрес определен при описание формата файлов, таких как PE-EXE.

    Более того встречается ещё десяток определений, которые так или иначе встречаются.


    Чтобы не запутаться надо использовать больше слов.
    l_inc
    Слова "численно", "адрес", "пространство" и "память", не позволяют однозначно отделить одно определение от другого. Определения надо оговаривать в статье, сообщение, теме сразу пояснив какое именно определение будет использоваться в данной статье, сообщение, теме.
     
  9. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Читаем Том 1. Глава 3.
    Линейное пространство имеет размер от 0 до 2^32-1 в 32-разрядом режиме. В 64 не определено, но понятно что от 0 до 2^64-1.
    GDT/LDT не ограничивают количество линейных пространств. Определение даётся через определение программы.
    Достаточно не зависимое определение. Оно не ограничивает нас в реализации.
    Сколько задач столько и линейных пространств.

    Если заглянуть в том 3. Глава 3 (память) то мы видим другое определение линейного пространства, через определение процессора.
    Там оно уже имеет фиксированный размер 4ГБ для 32-битного режима, и более того оно одно для процессора.
    Если в первом определение линейное пространство никак не связано с сегментами. То во второй показана его связь.
     
  10. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
    CuriosDroid
    имхо прочтите маны интела а уж потом читайте остальное
     
  11. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Это в теории 64-разрядное, а по факту пока 48-разрядное.

    Кстати, я выше сказал, что линейный адрес в расширенном режиме 48-разрядный, а ведь может в режиме совместимости он "сворачивается" до 32-разрядного. Кто-нибудь точно знает, как это работает? К примеру будет ли доступно в режиме совместимости все пространство сегмента максимального размера (4 гига), имеющего ненулевую базу?

    Лучше говорить, что виртуальных пространств много, а линейное пространство одно.
     
  12. CuriosDroid

    CuriosDroid New Member

    Публикаций:
    0
    Регистрация:
    19 ноя 2011
    Сообщения:
    5
    Короче понял свои ошибки и действительно полез читать маны Intel, что отрадно, действительно все доходчиво объястняют в отличии от книг на русском и статей. Нарисовал небольшой конспектик, представляю его ниже на суд общественности:

    Итак, давайте немного обрежем область обсуждений:

    Есть некая прикладная программа выполняющаяся на компьютере (IA-32) без операционной системы. Программа выполняет инструкции в защищенном режиме, которые обращаются к памяти . Есть физическая память размером <= 4 ГБ. Нужно понять данный механизм работы.

    У меня получилась вот такая картинка, описание ниже:
    [​IMG]

    -----
    Все prooflink (параграф и том) в скобочках даны по Intel® 64 and IA-32 Architectures Software Developer’s Manual (http://www.intel.com/content/dam/doc/manual/64-ia-32-architectures-software-developer-manual-325462.pdf)
    -----

    1. Любая инструкция в архитектуре IA-32, когда обращается к памяти, всегда адресует ее с помощью селектор: смещение. Это делается либо явно либо неявно. (3.7.3 Vol 1)

    2. Во время написании программы программист должен выбрать модель памяти с которой он будет работать, и в соответствии с которой он будет писать программу: Flat Model, Segmented Model.

    Если выбрана модель Flat, то программисту доступно 4ГБ Logical Address space.
    Note:В это модели - память линейна! (по идеи данное пространство тоже можно назвать линейным)

    Если выбрана модель Segmented, то программисту достуно 64ТБ! Logical Address space.
    Note1: В это модели - память двумерна и очень большая!
    Note2: Это устаревшая модель которой никто реально не пользуется (Win, Linux - flat), также поддержка данной модели отключена в IA-64 (3.3.4 Vol1).

    3. После начала исполнения логический адрес подвергается воздействию “черной коробочки” под названием Segmentation process на картинке. Результатом является линейный адрес в Linear Address Space процессора. Размер Linear Address Space - 4 ГБ.

    Note1: Данный предел линейного адресного пространства перепругныть для конкретной задачи нельзя. Даже если задача будет оперировать 64ТБ!, логическое пространство будет “обрезано” до 4ГБ. (3.3.6 Vol 1)
    Note2: “Черную коробочку” - сегментацию - отключить нельзя (3.1 Vol 3)

    4. После получения линейного адреса у нас возникают следующие вопросы:
    Сколько у нас физической памяти?
    Принадлежит ли нам линейное пространство полностью и нераздельно?

    Если физической памяти дофига т.е ровно 4 ГБ и у нас 1 задача (что по условию) то нам дальше можно и не париться и ставить в прямое соответствие адреса линейного пространства с адресами физического. Т.е пойти по стрелочке 2 на картинке

    Если же памяти мало например 256 МБ, то надо изголяться, и мы можем использовать свойство того, что задаче реально столько памяти все равно не нужно и из своего логического, а соответственно и линейного прост-ва оно будет использовать часть. Следовательно подвергнем линейный адрес воздействию “черного ящика” под названием Paging process, который “урежет” линейное прост-во до 256 МБ физического прост-ва, а если не получиться то еще и диск использует (3.1 Vol 3)

    Дальше осталось аккуратненько расписать и наполнить деталями
    - Процесс трансляции в случае нескольких задач
    - Процесс трансляции при наличии физической памяти больше чем 4 ГБ

    Но что такое Логическое (виртуальное по старому), линейное и физическое пространство становиться понятно.
     
  13. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    CuriosDroid
    Картинка мне не нравится.

    Кому должен программист?
    Он волен выбирать любую из двух моделей. Более того они могут работать одновременно, поясню эту фразу позже.

    Это не корректно. Сегмент модель говорит что для организации защиты используются сегменты, более того подразумевается что они не перекрываются. Поэтому доступны будут не 64ГБайт (4ГБ умножить на 6 сегментных регистров), а меньше.
    В интеловской сегментной модели говориться о пользовательском приложение, т.е таком приложение которое не меняет сегментные регистры. Если бы программа меняла сегментные регистры то ей бы было доступно более 64ГБайт, но это уже другая модель.

    Не правильно вы попутали модель, и механизм.
    Модель как-раз таки в win и linux используется сегментная, но механизм реализации через страницы.
    В IA64 это другая архитектура. Вы наверно имели ввиду x64. Да в ней механизм сегментов упрощён до той степени, что не позволяет сделать защиту в виде сегментной модели.
    Но сделано это потому что сегментная модель реализуется через страничный механизм.


    Было бы желание, а способ найдётся. Делаем некорректный(или помечаем сегмент как отсутствующий) описатель сегмента при обращение к которому ловим исключение. Во время исключения загружаем нужные данные в память. При этом дескрипторы на которые ссылаются сегментные регистры помечаем как некорректные кроме того с которого пришло исключение. Таким образом приложение способно получить свои 64ГБ.

     
  14. CuriosDroid

    CuriosDroid New Member

    Публикаций:
    0
    Регистрация:
    19 ноя 2011
    Сообщения:
    5
    Pavia
    к сожаления не могу с вами согласиться по некоторым пунктам:


    1) "Кому должен программист?" - Ну не воспринимайте буквально, понятно никому он ничего не должен. Но с точки зрения модели здесь либо флет модель, либо сегментная, другого не дано. Во флет модели вы используете near pointer, в segment - far pointers, и не важно сколько у вас сегментов 214 либо 2. Чтобы обращаться между сегментами вам нужно будет far pointer.

    Давайте назовет так flat model = 1 segment model, segment model = multi-segment model

    Кстати опять же см 3.3.1 IA-32 Memory Models


    2) "Это не корректно. Сегмент модель говорит что для..."
    1. я говорил про 64 ТерраБайт а не ГБ. 2. я говорил что сегментов может быть 214 по 232 см пруфлинк (3.3.1 Vol1).

    Programs running on an IA-32 processor can address up to 16,383 segments of different sizes and types, and each segment
    can be as large as 232 bytes

    А вот что с этим потом делать, это задача программиста. Как следить за пересечениями и трансляцией нескольких адресов в 1 линейный.

    Собственно этим и занимаются всякие ОС

    3) "модель, и механизм..." модель памяти она и есть модель, см пруфлинк интеловской документациию (например Figure 3-2. Flat Model), то что есть абстракции код, стек и дата в понимании программиста это уже другой разговор, но живет это все в 1м сегменте и 1м адресном пространстве.



    4) "Было бы желание, а способ найдётся...."
    Да здесь согласен, выразился не корректно, нада подумать как свою мысль выразить поточнее. Вообще моя мысль была навеяна вот этим

    Beginning with P6 family processors, the IA-32 architecture supports addressing of
    up to 64 GBytes (236 bytes) of physical memory. A program or task could not
    address locations in this address space directly. Instead, it addresses individual linear
    address spaces of up to 4 GBytes that mapped to 64-GByte physical address space
    through a virtual memory management mechanism.
     
  15. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Что за бред. Откуда взялись 64 тб, 6*4 гб? Линейное пространство не резиновое, т.е. его размер не зависит от числа используемых непересекающихся сегментов.
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    CuriosDroid
    Представьте, что Вы решили некоторую алгоритмическую задачу. После этого к Вам подходит некоторый абстрактный отучившийся в вузе умник и говорит: "Для решения этой задачи Вы выбрали метод динамического программирования". Но по факту Вы ничего не выбирали, Вы просто решили задачу, а как оно получилось, так получилось. С моделями памяти примерно так же. Хотя, конечно, директивы старых 16-битных компиляторов иногда заставляли задумываться о модели памяти явным образом. Но обычно Вы всё таки скорее выбираете, куда положить какой код, куда какие данные, и в результате получается какая-то часто смешанная модель.
    И те, и другие указатели по различным причинам вполне могут использоваться во всех моделях. Даже если условно используется плоская модель памяти, ничто не мешает явно указывать селектор сегмента для простого прыжка, а в той же Windows, которая, как известно, использует плоскую модель, обращение к TEB вообще стандартизовано происходит через fs, содержащий селектор сегмента с ненулевой базой.
    Я не уверен, правильно ли говорить, что это всё неверно. Но это точно не имеет смысла. 64ТБ — бессмысленное практически не имеющее применения число. И уж точно не имеет смысла говоить о том, сколько логического адресного пространства доступно программисту.
    Адресное пространство (любое) — это всего лишь множество всех возможных значений адресов. Логический адрес состоит из двух компонентов: 16 бит и 32 бита. Изменение любого из 48 бит чисто синтаксически меняет адрес на другой, причём не имеет значения, какой именно бит (будь то Offset, TI или RPL) изменён. Соответственно число различных логических адресов — 2^48, что и определяет размер (как понятие практически не используемого, в том числе и в интеловской документации) логического адресного пространства независимо от модели памяти.
    Линейное АП никак не урезается пэйджингом. Оно всегда 32-битно и содержит 2^32 адреса независимо от того, на каких адресах будет возникать page fault. Мало того, даже на 4 КБ физической памяти можно спроецировать все линейные адреса на физические в пределах этой страницы, чтобы избежать page fault'ы; и это точно так же не изменит размер линейного АП.
    Кроме того, здесь перепутаны физическое АП (которое не бывает размером в 256МБ, а определяется разрядностью шины) и физическая память (в данном примере 256МБ).
    Логическое и виртуальное АП — абсолютно разные вещи без всяких "по-старому". Конкретно к IA-32 относятся только понятия логического, линейного и физического адреса (и соответственно АП). Виртуальный адрес — адрес из адресного пространства процесса, работающего в пределах ОС.
     
  17. CuriosDroid

    CuriosDroid New Member

    Публикаций:
    0
    Регистрация:
    19 ноя 2011
    Сообщения:
    5
    l_inc


    Абсолютно с вами согласен, именно так все в жизни и происходит. Но чтобы каждый раз не рассусоливать о том, что я решал эту проблему так " взял такую забубенину, принес другую хрень, вставил забубенину в хрень на рассвете, под углом 15 град к солнцу..." + еще 2 часа описание метода. Люди придумали способ, а именно кристаллизовать знание в учебнике и называть определенный метод неким именем, легко узнаваемым специалистом в данной области.

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


    Кстати в закиданной гнилыми помидорами статье Broken Sword (http://www.wasm.ru/article.php?article=pipm10) Именно данный случай и описывается, только там он говорит, что у винды 4 ГБ сегмент кода, 4ГБ на сегмент данных (по отдетльному селектору конечно же) и стека + 4 КБ на FS.

    Но здесь не так все ясно, а даже мутно, надо отдельно разбираться. Но к сожалению в статьях, книгах и на этом форуме понятия даются отрывочно без общей картины. Прилетает некий факт, а как он с остальным дружит, понять сложно.

    А вот разобраться в этом я, в принципе, здесь и предлагаю

    Согласен, описал не верно.

    Хорошо давайте так считать.
     
  18. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    CuriosDroid
    Я привёл пример, исходя из некоторых соображений, которые я сейчас уже не буду приводить, т.к. они покажутся слабой аргументацией. Важно то, что я нигде не говорил, что бессмысленно вводить сами понятия, определяющие различные модели памяти.
    Так об этом же и речь:
    Условно можно сказать, что в Windows плоская модель памяти (и в основном везде именно так и написано), т.к. в одном и том же адресном пространстве находятся и код, и стек, и прочие данные, и программа может к чему угодно обратиться одними и теми же инструкциями. Но программисты не выбрали какую-то идеализированную модель, чтобы потом строго её придерживаться, а использовали доступные средства для эффективной реализации продукта (конечно, даже в отношении TEB нельзя говорить о какой-то строгой сегментированности, т.к. к нему совсем не обязательно обращаться через сегмент, селектор которого загружен в fs; а сам сегмент используется всего лишь, как некоторый стабильный локальный для потока указатель). В результате и получается вроде всё нормально, но остаётся какая-то кака, "прилетающая неким фактом, который с остальными не дружит".