Каков механизм P2V, макрос V2P в Xv6

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

Как и в следующем примере, линейный адрес состоит из трех частей.

  1. Индекс каталога страниц
  2. Индекс таблицы страниц
  3. Компенсировать

Вот иллюстрация:

Изображение для перевода страницы

Теперь, когда я смотрю на исходный код Xv6 в memorylayout.h

#define V2P(a) (((uint) (a)) - KERNBASE)
#define P2V(a) (((void *) (a)) + KERNBASE)

#define V2P_WO(x) ((x) - KERNBASE)    // same as V2P, but without casts
#define P2V_WO(x) ((x) + KERNBASE)    // same as P2V, but without casts

Как могут V2P или P2V правильно работать без преобразования адресов?


person brianmeowmeow    schedule 28.04.2018    source источник
comment
Я предполагаю, что это сделано при установке KERNBASE   -  person Barmar    schedule 28.04.2018


Ответы (1)


Макросы V2P и P2V не делают больше, чем вы думаете. Они просто вычитают и добавляют константу KERNBASE, которая помечена как 2 ГБ.

Похоже, вы правильно понимаете механизм сопоставления оборудования MMU. Правила сопоставления сохраняются в таблицах страниц для каждого процесса. Эти таблицы образуют виртуальное пространство процесса.

В частности, в XV6 структура виртуального пространства процесса строится (с помощью соответствующих сопоставлений) следующим образом: виртуальный адрес макет пространства

Как показано на диаграмме выше, XV6 специально строит виртуальное адресное пространство процесса так, чтобы виртуальные адреса 2–4 ГБ отображались на 0 в физические адреса PHYSTOP (соответственно). Как поясняется в официальном комментарии XV6:

Xv6 включает все сопоставления, необходимые для запуска ядра в таблице страниц каждого процесса; все эти сопоставления появляются над KERNBASE. Он сопоставляет виртуальные адреса KERNBASE: KERNBASE + PHYSTOP с 0: PHYSTOP.

Также указывается мотивация этого решения:

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

Другими словами, поскольку ядро ​​заставило все таблицы страниц отображать 2 ГБ виртуальных на 0 физических (и вплоть до PHYSTOP), мы можем легко найти физический адрес виртуального адреса, размер которого превышает 2 ГБ. Например: физический адрес виртуального адреса 0x10001000 можно легко найти: это 0x00001000, мы просто вычитаем 2 ГБ, потому что так мы его сопоставили.

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

Конечно, вышеупомянутый «обходной путь» не является бесплатным, так как это заставляет нас тратить ценное виртуальное адресное пространство (2 ГБ из него), потому что теперь каждый физический адрес имеет по крайней мере уже 1 виртуальный адрес. даже если мы никогда не собираемся его использовать. это оставляет реальному процессу только 2 ГБ, оставшиеся от всего виртуального адреса (всего это 4 ГБ, потому что мы используем 32-битный для подсчета адресов). Это также было объяснено в официальном комментарии XV6:

Недостатком такой схемы является то, что xv6 не может использовать более 2 ГБ физической памяти.

Я рекомендую вам прочитать больше об этом в комментарии XV6 под заголовком «Адресное пространство процесса». Комментарий XV6

person Omer Efrat    schedule 14.05.2018