Подтвердить что ты не робот

Какова связь между virt_to_phys и процессором MMU в ядре Linux?

Я читаю об управлении памятью Linux. Я знаю, что

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

Но я также знаю, что ядро ​​может использовать некоторые свои функции для управления памятью, например virt_to_phys(), virt_to_page(), __pa(),...

Пример:

static inline unsigned long virt_to_phys(volatile void *address)
{
    return __pa(address);
}

используется для перевода виртуального адреса на физический адрес.

Я очень смущен ими. Пожалуйста, помогите мне показать отношения между переводом MMU и переводом ядра и отличить их?

4b9b3361

Ответ 1

В системах с виртуальной памятью ядро ​​ОС отвечает за установление сопоставления между физическими и виртуальными адресами.

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

Указанные выше функции могут использоваться внутри кода ядра, чтобы получить перевод виртуальных физических адресов для некоторых адресов, которые используются в коде ядра. Например, для цели x86 вы можете определить определение virt_to_phys в io.h:

/**
 *  virt_to_phys    -   map virtual addresses to physical
 *  @address: address to remap
 *
 *  The returned physical address is the physical (CPU) mapping for
 *  the memory address given. It is only valid to use this function on
 *  addresses directly mapped or allocated via kmalloc.
 *
 *  This function does not give bus mappings for DMA transfers. In
 *  almost all conceivable cases a device driver should not be using
 *  this function
 */

static inline phys_addr_t virt_to_phys(volatile void *address)
{
    return __pa(address);
}

и если вы выполните определение __pa(address), вы увидите, что он вызывает вызов __phys_addr, который определяется как:

unsigned long __phys_addr(unsigned long x)
{
    if (x >= __START_KERNEL_map) {
        x -= __START_KERNEL_map;
        VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
        x += phys_base;
    } else {
        VIRTUAL_BUG_ON(x < PAGE_OFFSET);
        x -= PAGE_OFFSET;
        VIRTUAL_BUG_ON(!phys_addr_valid(x));
    }
    return x;
}

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

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

Ответ 2

Вы можете прочитать "Понимание книги ядра Linux", чтобы получить дополнительную информацию.

Ответ 3

По моему мнению, любое использование физического адреса на стороне ядра просто для справки и, скорее всего, просто будет переведено для любых реальных изменений/ходов. Для этого существует ряд причин: одна из них заключается в том, что память может быть переназначена для другой цели, IE перемещает данные из физической памяти в файл страницы (на диске) или перемещается в пределах выделения физической памяти, если больше места для этих данных. Таким образом, было бы нецелесообразно использовать физический адрес, если ядро ​​будет просто перемещать его, не сообщая вам. Вот интересный бит на эту тему. И гораздо подробнее здесь.

Ответ 4

Virt_to_phys() и другие на самом деле используют разные атрибуты таблиц страниц, такие как PAGE_OFFSET и т.д. Эти таблицы страниц создаются подсистемой управления памятью ядра, но они в свою очередь используют оборудование MMU для чтения/записи физическая страница в основной памяти.

Вы также можете ссылаться на различные доступные документы: один из них: https://www.kernel.org/doc/gorman/html/understand/understand006.html

Ответ 5

Вот точки.

1.) Ядро и другие мягкие работы с точки зрения виртуальных адресов. Каждый раз для поиска подходящего поиска таблицы аппаратных страниц аппаратного обеспечения (или выборки TLB) необходимо.

2.) В момент загрузки ядро ​​устанавливает виртуальное отображение: для простоты я скажу, что он отображает память по адресам 0x0.. n в 0xc0000000.. 0xc0000000 + n (так называемая низкая память).

3.) Установленное отображение является статическим. Для адресов lowmem подходят следующие функции:

virt_to_page(), __pa(), ...

Это означает, что

virtual address = physical address + some offset

Таким образом, вы можете легко получить адрес phys/virt для соответствующей страницы lowmem в коде ядра (MMU использует универсальные механизмы, т.е. ежедневную таблицу страниц). Это смещение - это просто соглашение, не более того.

Ответ 6

Трансляция адресов MMU - это аппаратное (процессорное) поведение. Перевод должен быть выполнен, так как физический адрес является допустимым адресом, который может использоваться аппаратным обеспечением для доступа к памяти. С другой стороны, функция ядра, такая как va_to_pa(), используется для преобразования логического адреса ядра (va) в физический адрес (pa), что означает, что ядро ​​использует виртуальный адрес, отличный от физического адреса, хотя это просто постоянный сдвиг между va и pa.

Инструкции и данные ядра находятся в виртуальном адресе, но ядро ​​использует физический адрес для выполнения многих задач, таких как подготовка записи в таблице страниц, получение адреса dma для устройства и скоро. Поэтому для ядра нужны функции типа va_to_pa().