Информация об изменениях

Сообщение Re[10]: история персональной ВТ от 20.01.2022 11:50

Изменено 20.01.2022 11:55 Pavel Dvorkin

Re[10]: история персональной ВТ
Здравствуйте, m2l, Вы писали:

Уф, уволь. Возьми Соломона-Руссиновича и найди там что-то, подтверждающее твои умозаключения о роли LDT.
То. что она используется — несомненно, с этим я не спорю. То, что что-то хранится в GDT, а что-то в LDT — тоже. Но это все (о виртуальных машинах не говорю)

Я не поленился, провел поиск. "LDT" упоминается 6 раз, при этом в одном месте, где описывается KPROCESS. Больше там ничего нет.

А про переключение процессов через CR3 есть

В специальном регистре CR3 процессоров х86 хранит­ся это значение для текущего процесса (один из программных потоков которого
обратился к виртуальному адресу). Это означает, что если при переключении кон­текста на процессоре окажется, что новый поток принадлежит другому процессу,
в регистр CR3 должен быть загружен адрес PDPT нового процесса из его структуры KPR0CESS.


При выделении памяти процессом создаются новые PTE. Если AWE, то PTE 64-битные, поэтому хватит для адресации 64Г с помощью лишь страничного механизма. Да, процесс может выделить больше чем 2 Гб, но одновременно использовать эту память не сможет — у него адреса 32-битные. Поэтому и существуют

https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-allocateuserphysicalpages#:~:text=The%20AllocateUserPhysicalPages%20function%20is%20used,function%20will%20fail%20with%20ERROR_PRIVILEGE_NOT_HELD.

но и

https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapuserphysicalpages

С помощью первой можно зааллокировать много, PTE позволят. Вот только адрес она не вернет, а вернет

[out] PageArray

A pointer to an array to store the page frame numbers of the allocated memory.

То есть, видимо, элементы PTE

А адрес можно получить только с помощью второй (конечно, после вызова первой и предварительного вызова VirtualAlloc. И будет он 32-битным.


Про flat model и сегментные регистры

Плоская модель памяти предполагает, что задача состоит из одного сегмента, который, в свою очередь, разбит на страницы.
...
В абсолютном большинстве современных 32(64)-разрядных операционных систем (для микропроцессоров Intel) используется плоская модель памяти.

https://prog-cpp.ru/asm-memory/

Одного сегмента! Что возможно только если сегментные регистры реально не влияют на вычисление линейного адреса, иначе будет не один сегмент.

Ну и вот еще

В плоской модели памяти базовые адреса всех сегментов равны нулю,пределы 4Гб-1 а защита ядра от программ осуществляется при помощи таблиц страниц. При такой схеме если программа передаёт ядру указатель на свои данные, например буфер для чтения файла, ядру нет необходимости переводить его в своё адресное пространство прибавлением std_application_base_address как это происходит сейчас.

http://board.kolibrios.org/viewtopic.php?t=636

Ну и напоследок

Когда CPU находится в 32-битных режимах, регистры и инструкции могут в любом случае адресовать всё линейное адресное пространство. Итак, почему бы не установить базовый адрес в ноль и позволить логическим адресам совпадать с линейными адресами? Intel называет это «плоской моделью», и это именно то, что делают современные ядра операционных систем под x86. Это эквивалентно отключению сегментации.

https://acm.bsu.by/wiki/Unix2019b/%D0%9E%D1%80%D0%B3%D0%B0%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D0%B8_%D0%BD%D0%B0_x86-64

Не думал я , что мне придется вести поиск на эту тему.

В общем, я эту дискуссию намерен закончить.
Re[10]: история персональной ВТ
Здравствуйте, m2l, Вы писали:

Уф, уволь. Возьми Соломона-Руссиновича и найди там что-то, подтверждающее твои умозаключения о роли LDT.
То. что она используется — несомненно, с этим я не спорю. То, что что-то хранится в GDT, а что-то в LDT — тоже. Но это все (о виртуальных машинах не говорю)

Я не поленился, провел поиск. "LDT" упоминается 6 раз, при этом в одном месте, где описывается KPROCESS. Больше там ничего нет.

А про переключение процессов через CR3 есть

В специальном регистре CR3 процессоров х86 хранит­ся это значение для текущего процесса (один из программных потоков которого
обратился к виртуальному адресу). Это означает, что если при переключении кон­текста на процессоре окажется, что новый поток принадлежит другому процессу,
в регистр CR3 должен быть загружен адрес PDPT нового процесса из его структуры KPR0CESS.


При выделении памяти процессом создаются новые PTE. Если AWE, то PTE 64-битные, поэтому хватит для адресации 64Г с помощью лишь страничного механизма. Да, процесс может выделить больше чем 2 Гб, но одновременно использовать эту память не сможет — у него адреса 32-битные. Поэтому и существуют

https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-allocateuserphysicalpages#:~:text=The%20AllocateUserPhysicalPages%20function%20is%20used,function%20will%20fail%20with%20ERROR_PRIVILEGE_NOT_HELD.

но и

https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapuserphysicalpages

С помощью первой можно зааллокировать много, PTE позволят. Вот только адрес она не вернет, а вернет

[out] PageArray

A pointer to an array to store the page frame numbers of the allocated memory.

То есть, видимо, элементы PTE

А адрес можно получить только с помощью второй (конечно, после вызова первой и предварительного вызова VirtualAlloc. И будет он 32-битным.


Про flat model и сегментные регистры

Плоская модель памяти предполагает, что задача состоит из одного сегмента, который, в свою очередь, разбит на страницы.
...
В абсолютном большинстве современных 32(64)-разрядных операционных систем (для микропроцессоров Intel) используется плоская модель памяти.


https://prog-cpp.ru/asm-memory/

Одного сегмента! Что возможно только если сегментные регистры реально не влияют на вычисление линейного адреса, иначе будет не один сегмент.

Ну и вот еще

В плоской модели памяти базовые адреса всех сегментов равны нулю,пределы 4Гб-1 а защита ядра от программ осуществляется при помощи таблиц страниц. При такой схеме если программа передаёт ядру указатель на свои данные, например буфер для чтения файла, ядру нет необходимости переводить его в своё адресное пространство прибавлением std_application_base_address как это происходит сейчас.


http://board.kolibrios.org/viewtopic.php?t=636

Ну и напоследок

Когда CPU находится в 32-битных режимах, регистры и инструкции могут в любом случае адресовать всё линейное адресное пространство. Итак, почему бы не установить базовый адрес в ноль и позволить логическим адресам совпадать с линейными адресами? Intel называет это «плоской моделью», и это именно то, что делают современные ядра операционных систем под x86. Это эквивалентно отключению сегментации.



https://acm.bsu.by/wiki/Unix2019b/%D0%9E%D1%80%D0%B3%D0%B0%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D0%B8_%D0%BD%D0%B0_x86-64

Не думал я , что мне придется вести поиск на эту тему.

В общем, я эту дискуссию намерен закончить.