linux 内核 物理内存,Linux内核之物理内存管理

Linux内核对于内存的管理摒弃了i386复杂的段式管理,而是采用了页式管理。Linux把整个的物理内存空间化为成一个个单独的页面,每页占4K空间大小。Linux把所有页面链接到一个全局的数组mem_map[]中,mem_map的每一个元素都是一个指针指向page数据结构。系统中的每个物理页面都对应着一个page数据结构,并根据需要把这些页面划分为不同的管理区:ZONE_DMA,ZONE_NORMAL和ZONE_HIGHMEM(用于物理内存超过1G空间的地址)。

typedef struct page {

struct list_head list;/* ->mapping has some page lists. */

struct address_space *mapping;/* The inode (or ...) we belong to. */

unsigned long index;/* Our offset within mapping. */

struct page *next_hash;/* Next page sharing our hash bucket in

the pagecache hash table. */

atomic_t count;/* Usage count, see below. */

unsigned long flags;/* atomic flags, some possibly

updated asynchronously */

struct list_head lru;/* Pageout list, eg. active_list;

protected by pagemap_lru_lock !! */

struct page **pprev_hash;/* Complement to *next_hash. */

struct buffer_head * buffers;/* Buffer maps us to a disk block. */

/*

* On machines where all RAM is mapped into kernel address space,

* we can simply calculate the virtual address. On machines with

* highmem some memory is mapped into kernel virtual memory

* dynamically, so we need a place to store that address.

* Note that this field could be 16 bits on x86 ... ;)

*

* Architectures with slow multiplication can define

* WANT_PAGE_VIRTUAL in asm/page.h

*/

#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)

void *virtual;/* Kernel virtual address (NULL if

not kmapped, ie. highmem) */

#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */

} mem_map_t;

DMA管理区是单独进行管理的,不经过MMU映射,而一般的外设都对地址空间有一定的限制。地址空间不能太大,而且要求地址连续。

每个管理区都对应着一个zone_struct结构,这个结构体中有一组空闲队列free_area_t。这些队列中要有一个队列保持一些离散的物理页面,另一个队列要保持长度为2的指数的连续物理页面。

typedef struct zone_struct {

/*

* Commonly accessed fields:

*/

spinlock_tlock;

unsigned longfree_pages;

unsigned longpages_min, pages_low, pages_high;

intneed_balance;

/*

* free areas of different sizes

*/

free_area_tfree_area[MAX_ORDER];

/*

* wait_table-- the array holding the hash table

* wait_table_size-- the size of the hash table array

* wait_table_shift-- wait_table_size

* == BITS_PER_LONG (1 << wait_table_bits)

*

* The purpose of all these is to keep track of the people

* waiting for a page to become available and make them

* runnable again when possible. The trouble is that this

* consumes a lot of space, especially when so few things

* wait on pages at a given time. So instead of using

* per-page waitqueues, we use a waitqueue hash table.

*

* The bucket discipline is to sleep on the same queue when

* colliding and wake all in that wait queue when removing.

* When something wakes, it must check to be sure its page is

* truly available, a la thundering herd. The cost of a

* collision is great, but given the expected load of the

* table, they should be so rare as to be outweighed by the

* benefits from the saved space.

*

* __wait_on_page() and unlock_page() in mm/filemap.c, are the

* primary users of these fields, and in mm/page_alloc.c

* free_area_init_core() performs the initialization of them.

*/

wait_queue_head_t* wait_table;

unsigned longwait_table_size;

unsigned longwait_table_shift;

/*

* Discontig memory support fields.

*/

struct pglist_data*zone_pgdat;

struct page*zone_mem_map;

unsigned longzone_start_paddr;

unsigned longzone_start_mapnr;

/*

* rarely used fields:

*/

char*name;

unsigned longsize;

} zone_t;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值