Poster of Linux kernelThe best gift for a Linux geek
 Linux kernel map 
⇦ prev ⇱ home next ⇨

15.5. Quick Reference

This chapter introduced the following symbols related to memory handling.

15.5.1. Introductory Material

#include <linux/mm.h>

#include <asm/page.h>

Most of the functions and structures related to memory management are prototyped and defined in these header files.

void *_ _va(unsigned long physaddr);

unsigned long _ _pa(void *kaddr);

Macros that convert between kernel logical addresses and physical addresses.

PAGE_SIZE

PAGE_SHIFT

Constants that give the size (in bytes) of a page on the underlying hardware and the number of bits that a page frame number must be shifted to turn it into a physical address.

struct page

Structure that represents a hardware page in the system memory map.

struct page *virt_to_page(void *kaddr);

void *page_address(struct page *page);

struct page *pfn_to_page(int pfn);

Macros that convert between kernel logical addresses and their associated memory map entries. page_address works only for low-memory pages or high-memory pages that have been explicitly mapped. pfn_to_page converts a page frame number to its associated struct page pointer.

unsigned long kmap(struct page *page);

void kunmap(struct page *page);

kmap returns a kernel virtual address that is mapped to the given page, creating the mapping if need be. kunmap deletes the mapping for the given page.

#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);

The high-performance version of kmap; the resulting mappings can be held only by atomic code. For drivers, type should be KM_USER0, KM_USER1, KM_IRQ0, or KM_IRQ1.

struct vm_area_struct;

Structure describing a VMA.

15.5.2. Implementing 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);

Functions that sit at the heart of mmap. They map size bytes of physical addresses, starting at the page number indicated by pfn to the virtual address virt_add. The protection bits associated with the virtual space are specified in prot. io_remap_page_range should be used when the target address is in I/O memory space.

struct page *vmalloc_to_page(void *vmaddr);

Converts a kernel virtual address obtained from vmalloc to its corresponding struct page pointer.

15.5.3. Implementing Direct I/O

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);

Function that locks a user-space buffer into memory and returns the corresponding struct page pointers. The caller must hold mm->mmap_sem.

SetPageDirty(struct page *page);

Macro that marks the given page as "dirty" (modified) and in need of writing to its backing store before it can be freed.

void page_cache_release(struct page *page);

Frees the given page from the page cache.

int is_sync_kiocb(struct kiocb *iocb);

Macro that returns nonzero if the given IOCB requires synchronous execution.

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

Function that indicates completion of an asynchronous I/O operation.

15.5.4. Direct Memory Access

#include <asm/io.h>

unsigned long virt_to_bus(volatile void * address);

void * bus_to_virt(unsigned long address);

Obsolete and deprecated functions that convert between kernel, virtual, and bus addresses. Bus addresses must be used to talk to peripheral devices.

#include <linux/dma-mapping.h>

Header file required to define the generic DMA functions.

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

For peripherals that cannot address the full 32-bit range, this function informs the kernel of the addressable range and returns nonzero if DMA is possible.

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);

Allocate and free coherent DMA mappings for a buffer that will last the lifetime of the driver.

#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);

Functions that create, destroy, and use DMA pools to manage small DMA areas.

enum dma_data_direction;

DMA_TO_DEVICE

DMA_FROM_DEVICE

DMA_BIDIRECTIONAL

DMA_NONE

Symbols used to tell the streaming mapping functions the direction in which data is moving to or from the buffer.

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);

Create and destroy a single-use, streaming DMA mapping.

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);

Synchronizes a buffer that has a streaming mapping. These functions must be used if the processor must access a buffer while the streaming mapping is in place (i.e., while the device owns the buffer).

#include <asm/scatterlist.h>

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

dma_addr_t sg_dma_address(struct scatterlist *sg);

unsigned int sg_dma_len(struct scatterlist *sg);

The scatterlist structure describes an I/O operation that involves more than one buffer. The macros sg_dma_address and sg_dma_len may be used to extract bus addresses and buffer lengths to pass to the device when implementing scatter/gather operations.

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 maps a scatter/gather operation, and dma_unmap_sg undoes that mapping. If the buffers must be accessed while the mapping is active, dma_sync_sg_* may be used to synchronize things.

/proc/dma

File that contains a textual snapshot of the allocated channels in the DMA controllers. PCI-based DMA is not shown because each board works independently, without the need to allocate a channel in the DMA controller.

#include <asm/dma.h>

Header that defines or prototypes all the functions and macros related to DMA. It must be included to use any of the following symbols.

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

void free_dma(unsigned int channel);

Access the DMA registry. Registration must be performed before using ISA DMA channels.

unsigned long claim_dma_lock( );

void release_dma_lock(unsigned long flags);

Acquire and release the DMA spinlock, which must be held prior to calling the other ISA DMA functions described later in this list. They also disable and reenable interrupts on the local processor.

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);

Program DMA information in the DMA controller. addr is a bus address.

void disable_dma(unsigned int channel);

void enable_dma(unsigned int channel);

A DMA channel must be disabled during configuration. These functions change the status of the DMA channel.

int get_dma_residue(unsigned int channel);

If the driver needs to know how a DMA transfer is proceeding, it can call this function, which returns the number of data transfers that are yet to be completed. After successful completion of DMA, the function returns 0; the value is unpredictable while data is being transferred.

void clear_dma_ff(unsigned int channel)

The DMA flip-flop is used by the controller to transfer 16-bit values by means of two 8-bit operations. It must be cleared before sending any data to the controller.

    ⇦ prev ⇱ home next ⇨
    Poster of Linux kernelThe best gift for a Linux geek