Краткая справка

Предыдущая  Содержание  Следующая V*D*V

Эта глава ввела следующие символы, связанные с обработкой памяти.

Вводный материал

#include <linux/mm.h>

#include <asm/page.h>

Большинство функций и структур, связанных с управлением памятью, являются прототипизированными и определёнными в этих заголовочных файлах.

void *__va(unsigned long physaddr);

unsigned long __pa(void *kaddr);

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

PAGE_SIZE

PAGE_SHIFT

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

struct page

Структура, которая представляет собой аппаратную страницу в карте памяти системы.

struct page *virt_to_page(void *kaddr);

void *page_address(struct page *page);

struct page *pfn_to_page(int pfn);

Макрос, который выполняет преобразование между логическими адресами ядра и связанными с ними записями в карте памяти. page_address работает только для страниц нижней памяти или страниц верхней памяти, которые были отображены явным образом. pfn_to_page преобразует номера страничного блока в связанный с ним указатель struct page.

unsigned long kmap(struct page *page);

void kunmap(struct page *page);

kmap возвращает виртуальный адрес ядра, который отображается на данную страницу, создавая отображение, если это будет необходимо. kunmap удаляет отображение для данной страницы.

 

#include <linux/highmem.h>

#include <asm/kmap_types.h>

void *kmap_atomic(struct page *page, enum km_type type);

void kunmap_atomic(void *addr, enum km_type type);

Высокопроизводительная версия kmap; результирующие отображения могут быть проведены только атомарным кодом. Для драйверов типы должны быть KM_USER0, KM_USER1, KM_IRQ0 или KM_IRQ1.

struct vm_area_struct;

Структура, описывающая VMA.

Реализация mmap

int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_add,

                         unsigned long pfn, unsigned long size, pgprot_t prot);

int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_add,

                         unsigned long phys_add, unsigned long size, pgprot_t prot);

Функции, которые находятся в центре mmap. Они отображают size байт физических адресов, начиная с номера страницы, указанного pfn для виртуального адреса virt_add. Защитные биты, связанные с виртуальным пространством, указаны в prot. Когда целевой адрес находится в пространстве памяти ввода/вывода, следует использовать io_remap_page_range.

struct page *vmalloc_to_page(void *vmaddr);

Преобразует виртуальный адреса, полученный от vmalloc, в соответствующий указатель struct page.

Выполнение прямого ввода/вывода

int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,

                        unsigned long start, int len, int write, int force, struct page **pages,

                        struct vm_area_struct **vmas);

Функция, которая блокирует буфер пользовательского пространства в памяти и возвращает соответствующие указатели struct page. Вызывающий должен иметь mm->mmap_sem.

SetPageDirty(struct page *page);

Макрос, который отмечает данную страницу как "грязную" (изменённую) и нуждающуюся в записи в резервное хранилище прежде, чем она может быть освобождена.

void page_cache_release(struct page *page);

Освобождает данную страницу из страничного кэша.

int is_sync_kiocb(struct kiocb *iocb);

Макрос, который возвращает ненулевое значение, если данное IOCB требует синхронного выполнения.

int aio_complete(struct kiocb *iocb, long res, long res2);

Функция, которая свидетельствует о завершении операции асинхронного ввода/вывода.

Прямой доступ к памяти

#include <asm/io.h>

unsigned long virt_to_bus(volatile void * address);

void * bus_to_virt(unsigned long address);

Устаревшие и осуждаемые для использования функции, которые выполняют преобразования между адресами ядра, виртуальными и шинными. Для общения с периферийными устройствами должны быть использованы шинные адреса.

 

#include <linux/dma-mapping.h>

Заголовочный файл, необходимый для определения универсальных функций DMA.

int dma_set_mask(struct device *dev, u64 mask);

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

void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *bus_addr, int flag)

void dma_free_coherent(struct device *dev, size_t size, void *cpuaddr, dma_handle_t bus_addr);

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

 

#include <linux/dmapool.h>

struct dma_pool *dma_pool_create(const char *name, struct device *dev, size_t size, size_t align, size_t allocation);

void dma_pool_destroy(struct dma_pool *pool);

void *dma_pool_alloc(struct dma_pool *pool, int mem_flags, dma_addr_t *handle);

void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t handle);

Функции, которые создают, уничтожают и используют пулы DMA для управления небольшими областями DMA.

enum dma_data_direction;

DMA_TO_DEVICE

DMA_FROM_DEVICE

DMA_BIDIRECTIONAL

DMA_NONE

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

dma_addr_t dma_map_single(struct device *dev, void *buffer, size_t size,

                           enum dma_data_direction direction);

void dma_unmap_single(struct device *dev, dma_addr_t bus_addr, size_t size,

                           enum dma_data_direction direction);

Создают и уничтожают одноразовое потоковое отображение DMA.

void dma_sync_single_for_cpu(struct device *dev, dma_handle_t bus_addr,

                          size_t size, enum dma_data_direction direction);

void dma_sync_single_for_device(struct device *dev, dma_handle_t bus_addr,

                          size_t size, enum dma_data_direction direction);

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

 

#include <asm/scatterlist.h>

struct scatterlist { /* ... */ };

dma_addr_t sg_dma_address(struct scatterlist *sg);

unsigned int sg_dma_len(struct scatterlist *sg);

Структура scatterlist, описывающая операцию ввода/вывода, которая включает в себя более одного буфера. Для получения шинных адресов и размеров буферов для передачи устройству при реализации операций разборки/сборки могут быть использованы макросы sg_dma_address и sg_dma_len.

dma_map_sg(struct device *dev, struct scatterlist *list, int nents,

                   enum dma_data_direction direction);

dma_unmap_sg(struct device *dev, struct scatterlist *list, int nents,

                   enum dma_data_direction direction);

void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,

                   enum dma_data_direction direction);

void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,

                   enum dma_data_direction direction);

dma_map_sg отображает операцию разборки/сборки, а dma_unmap_sg отменяет это отображение. Если буферы должны быть доступны, когда отображение активно, для синхронизации могут быть использованы dma_sync_sg_*.

 

/proc/dma

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

 

#include <asm/dma.h>

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

int request_dma(unsigned int channel, const char *name);

void free_dma(unsigned int channel);

Выполняют регистрацию DMA. Регистрация должна быть выполнена перед использованием каналов DMA на ISA.

unsigned long claim_dma_lock( );

void release_dma_lock(unsigned long flags);

Запрашивают и освобождают спин-блокировку DMA, которая должна удерживаться до вызова других функций DMA для ISA, описанных далее в этом списке. Они также отключают или снова включают прерывания на местном процессоре.

void set_dma_mode(unsigned int channel, char mode);

void set_dma_addr(unsigned int channel, unsigned int addr);

void set_dma_count(unsigned int channel, unsigned int count);

Программирование информации DMA в контроллер DMA. addr является шинным адресом.

void disable_dma(unsigned int channel);

void enable_dma(unsigned int channel);

Во время настройки канал DMA должен быть отключён. Эти функции изменяют состояние канала DMA.

int get_dma_residue(unsigned int channel);

Если драйверу необходимо узнать, как выполняется передача DMA, он может вызвать эту функцию, которая возвращает количество передаваемых данных, которые ещё не переданы. После успешного завершения DMA функция возвращает 0; во время передачи данных значение непредсказуемо.

void clear_dma_ff(unsigned int channel);

Для передачи 16-ти разрядных значений с помощью двух 8-ми разрядных операций контроллером используется DMA триггер. Перед отправкой любых данных в контроллер он должно быть очищен.

Предыдущая  Содержание  Следующая