The zen of kernel virtual addresses

From: Jonathan Corbet (corbet-lk@lwn.net)
Date: Sat Oct 21 2000 - 14:37:26 EST


Howdy,

I'm trying to get a better handle on how the kernel handles addresses.
Could anybody who is so inclined have a look at the following and tell me
(gently) where I've gone wrong?

There are several different ways of specifying an address in the kernel,
and the code is not always all that explicit on which it's using in any
given place. The terminology doesn't even seem to be there to make the
distinction, so I've made up some of my own. Here's the various ways I've
been able to find to refer to a page:

struct page
        The cookie used, increasingly, to represent any page in the
        system. Also where much of the page's housekeeping information
        lives.

page frame number
        Essentially an index into mem_map - what you would once get from
        MAP_NR. There is very little use of page frame numbers in the
        2.4 kernel - struct page is used instead.

physical address
        An address as known by the low-level hardware. In the modern
        world, these can be 64-bit quantities, even on 32-bit systems.
        These are the addresses used by /dev/mem - which appears to work
        only for low memory.

direct-mapped kernel virtual address
        An address as seen by the kernel - on many architectures it's just
        the physical address with an offset applied. Much of the
        kernel treats these as if they were physical addresses, but they
        are virtual and do not work for highmem pages.

        Back in my VMS days we would have called these "logical"
        addresses. There appears, however, to be a form of Godwin's law
        that applies to this list: if somebody mentions VMS the
        conversation stops. So I won't do that.

pure kernel virtual address
        An address which can be dereferenced by the kernel, but which does
        not directly map to a physical address. Examples include addresses
        returned by vmalloc() and kmap(). The union of the direct-mapped
        and pure kernel virtual addresses is exported by /dev/kmem.

user virtual address
        A basic virtual address used in user space.

There are ways of moving between various types of addresses:

virt_to_page()
        Maps a "logical" kernel address to a struct page. Does not work
        for pure kernel virtual or user virtual addresses.

__pa() Turns a logical kernel address into a physical address. Also known
        as virt_to_phys().

__va() Turns a (lowmem) physical address into a logical address. Also
        known as phys_to_virt().

page_address()
        Maps a struct page to a logical (for lowmem) or kernel virtual (for
        highmem which has been mapped) address. The comment on the i386
        version claims it returns the "permanent" address, but that is not
        true for highmem pages which have been kmap'd.

pte_page()
        Turns a page table entry into a struct page.

There does not appear to be a function to go from a user or kernel virtual
address to a physical address or struct page - one must manually walk
through the levels of page tables to get there via the pte.

Any corrections / suggestions would be much appreciated.

jon

Jonathan Corbet
Executive editor, LWN.net
corbet@lwn.net
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Oct 23 2000 - 21:00:18 EST