здравствуйте уважаемые. разбираюсь вот с РМ, возникли вопросы, в интеловских манах что-то никак не врублюсь. надеюсь кто-нить поможет. итак суть. значит при использовании страничной адресации в РМ линейный адрес распадается на 3 части (в случае 4 КБ страниц): далее собственно формирование адреса. база PDE формируется насколько я понял так: к старшим 20-ти битам регистра CR3 , потом как бы автоматически добавляются 12 нулевых битов справа. получается что 12 младших бит CR3 одновременно трактуются как атрибуты каталога, так и адрес базы каталога, только в последнем случае всегда трактуются как равные нулю. далее. полученное в итоге 32-битное значение есть база каталога страниц. конкретная запись в PDE формируется так -- к значению базы прибавляются старшие 10 бит взятые из распавшегося линейного адреса. но вот вроде и ясно, а вроде и не совсем. каким образом процессор адресует 4 килобайта 10-ю битами ? (как я понимаю 10-ю битами можно только 1024 байта адресовать ?) получается что процессор прибавляет 10 бит из линейного адреса не к младшим битам CR3 (0-9), а к битам 2-11 ?? ну тут в целом понятно, это уж если до самых гаек разбираться... далее пусть получили конкретную запись в PDE. (хотелось бы сразу уточнить, пусть каталог у нас один; имеет 1024 записи, получается, что у нас 1024 таблицы страниц по 1024 записей в каждой. понятно что можно несколько каталогов, и таблиц и страниц не обязательно брать по максимуму -- но представим так. тогда получается, что каталог занимает в памяти 4 килобайта, а все 1024 таблицы -- 4 мегабайта ? и в то же время получается такой парадокс как бы -- если в данном случае размер страницы 4 КБ, то получается, что уже 1025 страниц заняты (одна под каталог, 1024 под таблицы) ?? ) собственно биты 12-31 этой структуры данных указывают на адрес базы таблицы страниц. дальше, я так понимаю все аналогично вышеуказанному базе/смещению в каталоге -- младшие 12 бит всегда равны нулю (если трактуются как база таблицы, а не как атрибуты страницы...). смещение в таблице получается путем прибавления бит 12-21 из линейного адреса к битам 2-11 базы таблицы страниц (записи в PDE) -- то есть проц опять я так понимают сдвигает на 2 битика влево, чтоб смещение шло по 4 байта -- то есть все практически аналогично вышеописанному формированию базы каталога и смещению в каталоге. итого после всех этих мытарств мы получаем запись в таблице страниц, конкретную PTE описывающую конкретную страницу. ну и собственно конец. имеем биты 12-31 структуры PTE, они указывают на базу страницы. младшие 12 бит PTE опять же в данном случае (трактуем как адрес) равны нулю, и смещение, берущееся из младших 12 бит линейного адреса прибавляется к младшим 12 битам структуры, т.е. 0-11. надеюсь я прав. вот собственно и все. вопросов как таковых нету, кроме тех которые явно указаны по тексту, ну и надеюсь у кого-нибудь хватит терпения сие осилить и меня поправить если не прав где. специально старался все описать поподробнее, чтоб и знатоки вспомнили если что, ну и так для себя. писал все по памяти, тока на картинки посматривал заранее всем спасибо, если кто откликнется. peace.
MMIX А те, которые указаны по тексту, Вами же и отвечены. В общем-то всё верно. А 4 килобайта адресовать и не надо. Надо адресовать 1 килоиндекс в таблице. Или Вы усматриваете какой-то смысл в том, чтобы адресовать середину элемента таблицы? Т.е. всё правильно: биты индекса в каталоге страниц и биты индекса в таблице страниц попадают во 2-11 биты полного адреса элемента соответствующей таблицы. Да. А в чём же парадокс? Ну сдвига как такового нет в явном виде. Упрощённо говоря, сигнальные линии от соответствующего куска линейного адреса напрямую направлены в биты 2-11 некоторого внутреннего регистра, в котором формируется адрес элемента в каталоге/таблице.
MMIX Если использовать тот режим, который вы изобразили, каталог у нас только один. Что касается линейного адреса, то, как уже было сказано, группы по 10 бит позволяют хранить по 1024 индекса, которых как раз достаточно для индексации 4-байтовых элементов в 4-килобайтовой странице. Если читать документацию Intel, то к этому и приходишь. Однако на самом деле нужны только 1024 страницы. Один из входов каталога должен указывать сам на себя. Причем здесь экономия одной страницы - это лишь дополнительный бонус. Самое главное, что тем самым ты автоматически отображаешь все 4-килобайтовые таблицы в непрерывный 4-мегабайтовый участок виртуального адресного пространства (я его просто называю таблицей страниц), с помощью которого можешь управлять отображением страниц уже после включения пэйджинга.
l_inc да-да, спасибо, вот этот момент я и имел ввиду, говоря про сдвиг. спасибо, теперь прояснилось многое. Phantom_84 вот за эту тонкость спасибо, хотя еще и не понял до конца. получается одна запись каталога ссылается не на таблицу, а содержит в себе базу (и атрибуты) каталога (также как и в CR3 по сути ?) ? тогда выходит, что таблиц получается не 1024, а 1023 ?
MMIX Какая тебе разница, сколько их на самом деле? ОС, особенно многозадачная, не обязана сразу выделять "драгоценную" физ.память под все 1024 таблицы на каждый процесс, а может это делать по мере необходимости. Зачем все так усложнять Записи PDE и PTE это просто физ.адреса, в которых для экономии места в младших 12 разрядах вместо нулей хранятся флаги\атрибуты. И каталог, и каждая таблица страниц это просто массив из 1024 таких указателей+атрибутов. Старшие 10-битовые части линейного адреса являются индексами этих таблиц. Т.е. вся трансляция сводится к тому, что из CR3 берется адрес каталога страниц, из старших 10 бит лин.адреса берется индекс записи PDE, читается значение PDE по заданному индексу, младшие 12 бит обнуляются и получается физ.адрес таблицы страниц. Из след.10 бит лин.адреса получается индекс PTE, точно также читается значение по индексу с обнулением младших бит и получается физ.адрес 4К страницы. Осташиеся 12 бит лин.адреса являются смещением в этой странице. У-се PS: Но если спуститься с высокого уровня на низкий, то да - смещение элемента в массиве = индексу элемента * на размер элемента, и соотв-но при размере = 4 байта получаем, что 10 битный индекс должен прибавляться со смещением на 2, т.е. "к битам 2-11"
Когда поймешь, тогда почувствуешь всю ее мощь. В CR3 используются только атрибуты кэширования. Здесь же используются все атрибуты, причем они имеют двойное назначение, например, заданный только в этом входе атрибут Supervisor/PL0/U=0 будет автоматически защищать всю 4-мегабайтовую таблицу страниц от доступа с прикладного уровня, а не только сам каталог. Суть в том, что каталог одновременно будет являться еще и 4-килобайтовой таблицей страниц, описывающей всю 4-мегабайтовую таблицу страниц в виртуальном адресном пространстве. Поэтому у тебя будет и 1024 таблицы, и каталог, но на все это потребуется максимум 1024 страницы памяти. Не обязательно, но тогда для одновременного отображения всех таблиц (чтобы их изменять) тебе по сути придется дублировать каталог. И все равно должна быть ссылка на каталог, но только в таблице.
Phantom_84 Из Вашего предыдущего поста можно подумать, что это обязательно, а, читая интеловскую документацию, можно прийти к неверным выводам (это, конечно, верно для некоторых других моментов, но не в данном случае). Дублировать не придётся. А вообще, начнём с того, что использовать page directory, как page table — это грязный хак. Чтобы отобразить все таблицы в виртуальное АП, корректнее их запихать в одну 4-метровую страницу. Эффективность отображения та же, но без грязных хаков. Ну а кроме того изменять их (что, кстати, вообще не всегда нужно) можно и отключая пэйджинг. Хотя тоже неэффективно.
Phantom_84 Ну да. Потому что по четыре метра непрерывной физической памяти на процесс — это, конечно, роскошь. Но, как я уже сказал, все претензии были к слову "должен". Архитектура таких требований к таблицам не предъявляет, поэтому в конечном счёте это уже решение программиста.
Если ты "их запихнешь в одну 4-метровую таблицу", то тебе для этого понадобится столько же памяти. Я же при помощи единственной 4-килобайтовой страницы памяти с циклической ссылкой на себя имею каталог и возможность автоматического отображения в виртуальное пространство 4-мегабайтовой таблицы страниц с уже отображенным в ней каталогом.
Я об этом написал, но вижу, что ты и сам понял Я имел в виду: "Для этого один из входов каталога должен..."
В принципе все ясно, спасибо всем за ответы и за дискуссию. Еще вот вопрос. Смотрю у того же Broken Sword'a в манах, страничная адресация. Требуется записать по адресу начала видеопамяти 0B8000h некое сообщение. В сегментной адресации мы использовали ES:0, где ES содержал селектор на дескриптор с базой 0B8000h. То же самое делаем и при использовании страничной адресации. Вот код (наиболее важные отрывки): Код (Text): mov EDI,100000h ; начало каталога страниц (1 Мб) mov EAX,101007h ; первый значащий элемент в каталоге ; ;вот тут у Broken Sword'a не указано, но для строковой инструкции я думаю ;не лишним было бы указать направление, т.е., к EDI прибавлется 4 ; cld ; DF = 0, EDI увеличивается stosd ; ES:[EDI] <-- EAX (в итоге в 100000h помещаем 101007h (первая таблица?)) mov ECX,1023 ; заполняем каталог полностью, 1023 записи + 1 уже готова xor EAX,EAX rep stosd ;вроде бы ясно, -- начиная с адреса 100000h до 101000h расположен ;каталог страниц, 1024 PDE'шки ; ;теперь создадим и заполним 1 таблицу страниц ; mov EAX,00000007h ; первая запись -- адрес нулевой страницы равен 0 mov ECX, 1024 ; 1024 страницы в таблице fill_page_table: stosd ; сохраним первый элемент (00000007h в EDI = 101000h) add EAX,1000h ; добавим 4 КБ loop fill_page_table ; повторить ; и того как я понял, получаем в 1 таблице 1024 страницы по 1000h (4КБ) каждая... mov EAX,00100000 ; mov CR3,EAX ; ; включаем страничную адресацию ; mov EAX,CR0 or EAX,80000000h mov CR0,EAX ; ;меняем физический адрес страницы 12000h на 0B8000h ; mov EAX,000B8007h mov ES:00101000h+012h*4,EAX Вроде все. Собственно, вопросов как таковых нет, вроде во все вкурил более-менее подробно, так что вопрос касается последнего кусочка кода. ES -- селектор на дескриптор, ясно; 00101000h -- это конец нашего каталога страниц и соответственно начало таблицы страниц, непонятно почему 012h*4 -- указываем на 12 запись в таблице страниц чтоли? Если да, то почему 12 запись в таблице страниц указывает/указывала на 12000h ?? -- вот в чем мой главный вопрос. (Предположу, что: 12 запись (PTE) указывает на 12000h потому, что идет планомерное прибавление 4 КБ к нулю, т.е. если 00000007h это нулевая запись, то 00001007h -- следующая и т.д. ?)
MMIX I Учли, что при этом будет также отмаплен и сам каталог страниц с таблицей? Потому что один элемент каталога (одна полная таблица) мапит 4МБ = 400000h, а каталог у Вас начинается с 100000h. По сути ничего страшного, просто это должно быть сделано сознательно. II Потому что Вы сами заполнили так нулевую таблицу страниц (тождественное отображение): 0-й элемент таблицы — адрес 0. 1h-й элемент таблицы — адрес 1000h 2h-й элемент таблицы — адрес 2000h ... 12h-й элемент таблицы — адрес 12000h III Не очень понятно, зачем на физический адрес 0B8000h отображать 12h-ю виртуальную страницу, если туда отображает уже 0B8h-я виртуальная страница. IV Заменять адрес элемента таблицы страниц желательно до того, как будет включён пэйджинг. В данном случае не критично, т.к. обращений к этой таблице ещё не было. Но если после включения пэйджинга вставить сначала обращение к 12h-й виртуальной странице, а потом заменить адрес, то после замены адреса обращения к 12h-й виртуальной странице будут всё равно приводить к обращениям к 12h-й физической странице (а не к 0B8h-й), т.к. процессор будет иметь старый адрес в своих TLB. Поэтому по хорошему после замены адресов в элементах таблиц/каталогов страниц необходимо либо выполнять явную инвалидацию TLB либо заменять адреса до включения пэйджинга (при включении/выключении инвалидация, естесственно, автоматическая).
l_inc Да, учел этот момент, просто во-первых в оригинале так, а, во-вторых, тут не суть важно в общем-то. Опять же -- в оригинале так. Просто чтобы показать суть страничной адресации. И 12h страница взята не более чем с потолка. Также, с потолка взято и дополнительное задание -- Код (Text): А теперь небольшое партийное задание: переделать прогу так, чтобы начало видеопамяти совпадало с адресом 66000h. Спасибо, принял к сведению. Общую суть РМ уловил, теперь пора переходить к манам. Еще раз спасибо вам большое -- очень приятно, когда есть люди, которые внимательно прочитают твою простынку на пару экранов, поймут о чем там речь и не поленятся направить на путь истинный.
MMIX Вам в свою очередь спасибо за положительный feedback. Без него нет морального удовлетворения от оказания любого рода помощи, которое является одним из решающих мотиваторов для участия в теме.
l_inc Ну просто я интересуюсь этим для себя, 4fun так скажем. Мне реально интересно все это дело (без каких-либо корыстных целей, разумеется), поэтому в первую очередь я хочу разобраться сам. А многие, как я успел заметить, делают вид интересующегося проблемой, а сами тупо хотят чтобы кто-то сделал за них их лабораторную работу, хехе. Понятно что таких видно насквозь и у мастеров нет желания помогать своего рода халявщикам. Еще раз спасибо вам.