LINUX.ORG.RU

Страничная адресация. Формат дескриптора страницы.

 


0

1

Всем привет! Вот тут: https://ru.bmstu.wiki/%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C_(%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5_%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B) в разделе «Механизм работы» описан способ организации памяти просто одна таблица страниц (без каталога страниц). Это то что мне нужно. Обратите внимание на картинку в разделе «Механизм работы». Главное что из себя представляет «дескриптор страницы», не нашел в интернете нормального объяснения (в т.ч. не указывают атрибуты в статьях). Я так понял, что не используются ни какие регистры, то есть не процессор преобразует номер страницы в физический адрес, хотя в защищенном режиме я читал что именно процессор должен преобразовывать адреса в физические. В общем объясните как это работает. Полезное дело сделаете, так как у нас хорошей ОС нет сейчас в мире, а у меня точно есть отличное видение какой должна быть хорошая ОС (естественно без шпионажа как в виндовс). Не хочется тратить столько времени на плохо описанные технические нюансы ОС, Ваша помощь будет кстати. С остальным мне пока все понятно.


а у меня точно есть отличное видение какой должна быть хорошая ОС

Какой?

object
()

Надо не Википедию читать, а официальный талмуд от Интела. Там все эти диаграммы и форматы данных описаны.

wandrien ★★
()
Ответ на: комментарий от wadic2

Еще поясню то как я это вижу. Есть процесс, который говорит менеджеру памяти, дай мне страницу памяти. Менеджер видит что у него первая логическая (а следовательно физическая, у меня для простоты они совпадают, точнее соответствуют друг другу) страница чиста. Далее менеджер памяти по идее должен говорить процессору, дай мне физический адрес №1 страницы. Где то читал что передается именно номер, номер, который ты сам назначаешь, то есть страницы просто пронумерованы от 1 до 1000 к примеру. Процессор идет в таблицу страничных дискрипторов и получает физический адрес, и по идее должен писать этот адрес в какой то регистр. Вот и вопрос, что за регистр, а также №1 (цифру, а также в каком виде эту цифру) в какой регистр писать? По поводу талмуда от Интела. Есть еще amd. Вообще долго разбираться можно, особенно учитывая отвратное качество документации. Но все же скиньте ссылку на талмуд от Интела. Только ссылку на конкретную тему, уже что то искал у них, там черт ногу сломит.

wadic2
() автор топика

что из себя представляет «дескриптор страницы»

По твоей же ссылке и написано, что это Page Directory и Page Table. По ссылке cobold’a именно об этом.

атрибуты

Возможно, вопрос терминологии. Обычно они называются флаги (flags).

как это работает

Если я верно понял, wandrien советовал Intel Architectures Developer’s Manual. Можешь сразу начинать 4 главу. Там сразу по твоей теме.

PhysShell ★★
()

TLB буффер используется вроде. Чтобы не было частых запросов в таблицу страниц.

xmikex ★★★★
()
Ответ на: комментарий от X512

Да, по флагам, cobold’a дал верно. PhysShell, спасибо за ссылку.

Пока это второй прототип ОС, какой я пишу, он x86 (32 разряда), позже возможно будет x86_64.

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

wadic2
() автор топика
Ответ на: комментарий от wadic2

Пока это второй прототип ОС, какой я пишу, он x86 (32 разряда)

В x86 двухуровневая таблица трансляции из виртуальных адресов в физические. Корневой уровень называется «page directory», за ним идёт «page table». Они имеют схожий формат и состоят из 1024-ёх 32-ух битных записей с флагами и физическим адресом на следующий уровень (для последнего уровня физический адрес страницы на которую собственно происходит трансляция). Структура записей и флагов есть в статье на OsDev или в документации Intel, ссылки приведены выше. Физический адрес на корневую таблицу (page directory) хранится в регистре CR3, трансляция включается через бит 31 в регистре CR0.

Нашёл картинку для x86.

TLB - эту железо, я не думаю что мне нужно

TLB надо обновлять после переключения или изменения таблицы страниц.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 4)

у нас хорошей ОС нет сейчас в мире, а у меня точно есть отличное видение какой должна быть хорошая ОС

такое наркоманство только на лоре увидишь: чел не знает, как пэйджинг на х86 работает, но это и неважно, зато он знает какой должна быть ОС.

С остальным мне пока все понятно

а я уж грешным делом подумал…

s-o
()
Ответ на: комментарий от wadic2

Раз с английским плохо, попробуй переводить. Если не доверяешь некоторым местам перевода, для сверки смотри оригинал, особенно, когда речь идёт о терминологии. По-хорошему, технический английский необходим, ибо читая первоисточник ты не наступишь на грабли кривого перевода.

Вспомнил книжку ‘Operating systems design and implementation’ Таненбаума, она переведена на русский. Глава про управление памятью там есть, специально посмотрел. Если решишь читать в переводе, совет в 2-ом предложении актуален.

PhysShell ★★
()
Ответ на: комментарий от X512

Таблица может быть и 3-х уровневая, но мне не надо пока. Вопрос как процессор понимает сколько уровней. Суть в том, что мы не от того отталкиваемся, есть программа, которую процесс ставит на выполнение, вот он ее загружает, нужно понять как. Суть в программе. Я скорее всего не буду делать exe или другой формат, буду делать свой. Но пока работаю с программой nasm (программа представляет из себя iso, то есть это ОС), сама программа находиться внутри программы nasm во втором секторе (512 байт), это просто код (как бы подпрограмма, которую условно будем считать программой), вот мне нужно прочесть ее в оперативку, при этом обработав логические адреса, превратив их в «номер таблицы» + «номер виртуальной страницы» + «логический адрес». В литературе путаница что есть логический адрес. В моем понимании для 32 бит это адрес 0000 или 00, без номера таблицы и номера виртуальной страницы. Последние занимают 20 бит, остается 12 бит на логический адрес или 1,5 байта. Тут тоже вопрос, как 1,5 байта выглядят как логический адрес? Я привык к чему то такому: 0000.

wadic2
() автор топика
Ответ на: комментарий от X512

Еще вопрос. Логический адрес (смещение) в программе nasm представляет собой 32-х битный адрес. По идее как бы физический, и в прямой адресации он будет физическим. Компилятор не знает где будет выполняться программа (прямая адресация, сегментная, страничная), в заголовках программы не сказано какая адресация. По этому мы по сути имеем логический адрес = физический адрес. Если так, то даже если «номер виртуальной страницы» + «логический адрес», то это будет больше 32-х бит. Процессор не сможет работать с таким адресом.

wadic2
() автор топика
Ответ на: комментарий от wadic2

Если так, то даже если «номер виртуальной страницы» + «логический адрес», то это будет больше 32-х бит.

Это вы про PAE? Без использования MMU больше чем первые 4ГБ памяти на 32 битном процессоре доступно не будет.

X512 ★★★★★
()
Ответ на: комментарий от X512

Без использования MMU больше чем первые 4ГБ памяти на 32 битном процессоре доступно не будет. - это понятно. PAE пока не использую. Когда я говорю «номер виртуальной страницы» + «логический адрес», речь о:

mov eax, «номер виртуальной страницы» + «логический адрес»

Это то как в памяти в конечном счете должно выглядеть, но не влазит в 32 бита эта часть: «номер виртуальной страницы» + «логический адрес»

А в программе (даже откомпилированной) мы имеем:

mov eax, «логический адрес»

Все это преобразование адреса в страничной адресации, в сегментной адресации думаю тоже самое. Это главное, от чего нужно отталкиваться, от того как ОС транслирует программу в память и как меняет ее физический адрес (сегмент). Я 3 дня назад задал этот вопрос, но ответа нет. По сути сам все объяснил. Вот одна вещь только не укладывается.

wadic2
() автор топика
Ответ на: комментарий от wadic2

я ни знаю английский

Вот я и выучил, пока читал. Делай так же. :P

wandrien ★★
()
Ответ на: комментарий от wadic2

Ничерта непонятно, что ты спрашиваешь.

Прикладная программа работает в виртуальных адресах.

Трансляция в физический выполняется по тем самым N-уровневым таблицам прозрачно для программы (в железе).

Количество уровней в таблице зависит от конкретной архитектуры проца и режима работы.

wandrien ★★
()
Ответ на: комментарий от wandrien

<<Прикладная программа работает в виртуальных адресах.

Трансляция в физический выполняется по тем самым N-уровневым таблицам прозрачно для программы (в железе).

Количество уровней в таблице зависит от конкретной архитектуры проца и режима работы.>> - это все я знаю, это все так. Но. Вот Вы напишите пошагово как происходит трансляция логического адреса (тот что в mov указываем) в физический адрес, тогда будет доказательно отвечено на мой вопрос. А пока я написал то как это работает, на основе моих знаний. С уважением, wandrien.

wadic2
() автор топика
Последнее исправление: wadic2 (всего исправлений: 1)
Ответ на: комментарий от wadic2

mov eax, «номер виртуальной страницы» + «логический адрес»

Откуда взялась эта формула? Может быть «номер виртуальной страницы»*4096 + «смещение»? Тогда всё влезает в 32 бита, номер страницы 20 битный.

физический адрес (сегмент)

Сегментация – это другой и параллельный MMU механизм, считающийся сейчас устаревшим. Сегменты обычно настраивают так, чтобы они покрывали всю память.

X512 ★★★★★
()
Ответ на: комментарий от wadic2

Вот Вы напишите пошагово как происходит трансляция логического адреса (тот что в mov указываем) в физический адрес, тогда будет доказательно отвечено на мой вопрос.

В два этапа:

  1. Сегментный -> линейный

Проц берет сегментный адрес и идёт смотреть, что там настроено в соответствующем сегментном регистре.

Если тип доступа не соответствует разрешенному, программа получает отлуп в виде исключения.

Если адрес превышает заданный лимит, программа получает отлуп в виде исключения.

Если всё ок, вычисляется линейный адрес:

линейный адрес = сегментный адрес + опорный адрес сегмента
  1. Линейный -> физический

Проц разбивает линейный адрес на три группы бит: 10 старших бит, 10 средних бит и 12 младших бит.

Проц идёт в регистр CR3 и берет оттуда физический адрес начала Page Directory. Вычисляет адрес PDE:

PDE = CR3 + (10 старших бит адреса) * 4

Смотрит в PDE по этому адресу, проверяет флаги и всякие режимы. Если что-то ему не нравится, программа получает отлуп в виде исключения.

Если всё ок, берет из PDE физический адрес Page Table. Вычисляет адрес PTE:

PTE = (адрес PT, взятый из PDE) + (10 средних бит адреса) * 4

Смотрит в PTE по этому адресу, проверяет флаги и всякие режимы. Если что-то ему не нравится, программа получает отлуп в виде исключения.

Если всё ок, берет из PTE физический адрес страницы. Вычисляет адрес итоговый адрес:

итоговый физический адрес = (адрес страницы, взятый из PDE) + (12 младших бит)

Это и есть физический адрес обращения прикладной программы.

wandrien ★★
()
Ответ на: комментарий от X512

Сегментацию вообще не трогаем. «номер виртуальной страницы»*4096 + «смещение» - приблизительно верно, просто смещение в OllyDbg и в дизассеблере выглядит так: 0000 0000, то есть 32 бита.

wadic2
() автор топика
Ответ на: комментарий от wadic2

просто смещение в OllyDbg и в дизассеблере выглядит так: 0000 0000, то есть 32 бита.

Форматы исполняемых файлов могут вводить свою адресацию, например VA, RVA в исполняемых файлах PE. При загрузке может требоваться релокация если внутренняя адресация исполняемого файла и адреса, по которым он был по факту загружен, не совпадают.

то есть 32 бита

А что должно быть? Процессор 32 битный вот и получается 32 бита.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от wandrien

Пока не вдавался в подробности, но вижу что правильно написали. Только зачем преобразование Сегментный -> линейный? У нас не сегментная адресация, а страничная, это две разные вещи. Смешанный режим не будем брать. Вот я и говорю о «Проц разбивает линейный адрес на три группы бит: 10 старших бит, 10 средних бит и 12 младших бит.» Линейный адрес в OllyDbg и в дизассемблер выглядит так: 0000 0000, то есть 32 бита. А должен быть 12 бит. Плюс, а если я захочу программу nasm в реальном режиме запустить (а такая возможность есть, сам запускал)? Тогда вместо 12 бит, там должно быть 32 бита. Вот я и спрашиваю, как эти две нестыковки состыкуются? Смотрел устройство com, exe, elf, не нашел там в заголовках ответа, не дает ответ и внешний вид 0000 0000 (смещение или физический адрес), который показывают OllyDbg и в дизассемблер.

wadic2
() автор топика
Ответ на: комментарий от wadic2

Только зачем преобразование Сегментный -> линейный? У нас не сегментная адресация, а страничная, это две разные вещи.

IA-32 всегда работает с сегментами, они не отключаются ни в каком режиме. То, что ОС настраивает их так, будто их нет, не влияет на то, что проц всё равно их обрабатывает.

wandrien ★★
()
Ответ на: комментарий от wadic2

Линейный адрес в OllyDbg и в дизассемблер выглядит так: 0000 0000, то есть 32 бита. А должен быть 12 бит.

Кому должен?

Плюс, а если я захочу программу nasm в реальном режиме запустить (а такая возможность есть, сам запускал)? Тогда вместо 12 бит, там должно быть 32 бита.

В реальном режиме нет виртуальной памяти и соответственно нет трансляции страниц. Это 16-битный режим, эмулирующий архитектуру древнего проца i8086.

wandrien ★★
()
Ответ на: комментарий от wadic2

Линейный адрес в OllyDbg и в дизассемблер выглядит так: 0000 0000, то есть 32 бита. А должен быть 12 бит.

Блин, чувак.

Вот представь. Я тебе говорю: «Вот адрес назначения: г. Новосибирск, ул. Ленина, д. 8, кв. 45».

А потом говорю: «В этом адресе реальные данные — только номер квартиры. А чтобы узнать настоящий адрес, тебе надо взять эти город, улицу и дом и в специальном справочнике найти, какой реальный адрес я ими зашифровал.»

Вот «справочник», который превращает «ненастоящие» адреса в «настоящие» — это алгоритм трансляции страниц в проце.

А сам адрес как был длинным, так и есть.

wandrien ★★
()
Ответ на: комментарий от X512

Мне понадобятся 2 вещи - свой формат и пользоваться форматом nasm. Если nasm имеет такой адрес 0000 0000, то как к нему приклеивается «номер виртуальной страницы»*4096», чтобы в итоге было: «номер виртуальной страницы»*4096» + смещение.

wadic2
() автор топика
Ответ на: комментарий от wadic2

Если nasm имеет такой адрес 0000 0000, то как к нему приклеивается «номер виртуальной страницы»*4096»

Он там и так есть:

«номер виртуальной страницы» = «адрес» / 4096
«смещение» = «адрес» % 4096

% – остаток от деления.

X512 ★★★★★
()
Ответ на: комментарий от X512

Где есть? В иструкции наподобии mov не пишут такое, так как в ней указывается только смещение и оно почему то выглядит так: 0000 0000. А должно 01 0000 0000 или 0001 0000 0000. может я ошибаюсь, и 0000 0000 имеет номер виртуальной страницы 00, то есть нулевую. Ну так 0000 0000 это должно быть смещение, а номер виртуальной страницы ОС вставляет в 0000 0000, в итоге 01 0000 0000. Или я ошибаюсь все же? В принципе наверно довольно безопасно компилятору проставить номер виртуальной страницы, это ведь не номер физической страницы. Я прав во всем этом? Получается компилятор формирует «номер виртуальной страницы»*4096» + смещение?

wadic2
() автор топика
Ответ на: комментарий от wadic2

В иструкции наподобии mov не пишут такое

А почему должны? Ы:

Трансляция в физический выполняется по тем самым N-уровневым таблицам прозрачно для программы (в железе).

- это все я знаю

Да видимо, не знаешь. Какая же она к черту была бы ПРОЗРАЧНАЯ трансляция, если бы её нужно было специально указывать?

В том и суть, что она невидимая.

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 2)
Ответ на: комментарий от wadic2

Попустим есть 32 битный адрес 0x12345678. В нём 0x12345 – номер страницы (20 бит), 0x678 – смещение (12 бит). Если используется MMU, то номер страницы будет преобразован в номер физической страницы через таблицу трансляции страниц, на которую указывает CR3. Смещение не участвует в трансляции и не меняется.

Если очень хочется, то можете для себя писать 0x12345:678, но зачем?

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от wandrien

Про Сегментный -> линейный

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

линейный адрес = сегментный адрес + опорный адрес сегмента опорный адрес сегмента - что за опорный адрес?

wadic2
() автор топика
Ответ на: комментарий от wadic2

Проц берет сегментный адрес - откуда берет?

«Адрес» = «сегментный адрес». В современных ОС обычно настраивают сегментацию так, чтобы было «сегментный адрес» = «линейный адрес».

X512 ★★★★★
()
Ответ на: комментарий от X512

Вы имеете в виду «Адрес» = «номер виртуальной страницы»*4096» + смещение = «сегментный адрес»? Как именно настраивают сегментацию, чтобы «сегментный адрес» = «линейный адрес»?

wadic2
() автор топика
Ответ на: комментарий от X512

Я ему просто первые попавшиеся ссылки из гугла кидаю по запросу «intel защищенный режим туториал», везде всё написано.

Чел пишет «Я кучу статей прочитал и не при помню такой сложной адресации.»

Жоско…

wandrien ★★
()
Ответ на: комментарий от wandrien

Вы не правы. Вот по Вашей же ссылке http://bsuir-helper.ru/sites/default/files/2013/01/26/met/solod2.pdf написано в разделе 1.6. Страничное управление памятью. Что сегментная и страничная адресация это разные вещи.

wadic2
() автор топика
Ответ на: комментарий от wadic2

Что сегментная и страничная адресация это разные вещи.

Разные вещи.

Сначала выполняется сегментная трансляция, а потом страничная.

Сегментная выполняется всегда, а страничная только если в CR0 установлены флаги PE и PG.

Абсолютно разные вещи.

wandrien ★★
()
Ответ на: комментарий от wandrien

Где написано что сегментная выполняется всегда? Статью в студию. Вот статья про страничную адресацию: https://ru.bmstu.wiki/%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C_(%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5_%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B)#.D0.9C.D0.B5.D1.85.D0.B0.D0.BD.D0.B8.D0.B7.D0.BC_.D1.80.D0.B0.D0.B1.D0.BE.D1.82.D1.8B Страничная адресация как раз ставится в противовес сегментной, за свою страничную простоту. Там ни слова о таком сложной адресации что Вы написали. Там есть похожее на то что Вы написали, это «Сегментно-страничная виртуальная память», но мне это не нужно. Мне просто страничная адресация нужна. В гугл сделайте запрос «Страничная адресация». Вы же где то взяли тот вариант (сложный), что тут написали, у Вас наверно ссылка на него есть?

wadic2
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.