再读uclinux-2008r1(bf561)内核存储区域管理(5):page初始化

 

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

   

 

本文适用于

ADI bf561 DSP

优视BF561EVB开发板

uclinux-2008r1-rc8 (移植到vdsp5)

Visual DSP++ 5.0

   

欢迎转载,但请保留作者信息

 

 

1.1.1   page初始化

1.1.1.1             memmap_init

这个宏用于初始化mem_map中每个page的数据。

#define memmap_init(size, nid, zone, start_pfn) /

     memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)

/*

 * Initially all pages are reserved - free ones are freed

 * up by free_all_bootmem() once the early boot process is

 * done. Non-atomic initialization, single-pass.

 */

void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,

         unsigned long start_pfn, enum memmap_context context)

{

     struct page *page;

     unsigned long end_pfn = start_pfn + size;

     unsigned long pfn;

 

     for (pfn = start_pfn; pfn < end_pfn; pfn++) {

         /*

          * There can be holes in boot-time mem_map[]s

          * handed to this function.  They do not

          * exist on hotplugged memory.

          */

         if (context == MEMMAP_EARLY) {

              if (!early_pfn_valid(pfn))

                   continue;

              if (!early_pfn_in_nid(pfn, nid))

                   continue;

         }

         page = pfn_to_page(pfn);

         set_page_links(page, zone, nid, pfn);

         init_page_count(page);

         reset_page_mapcount(page);

         SetPageReserved(page);

         INIT_LIST_HEAD(&page->lru);

     }

}

调用此函数时size为整个SDRAM区域的页数,对于 64M 内存(限制为 60M ),其值为0x3bff。其余几个参数均为0

从这个函数可以看出,它依次对每个页的描述符page均进行了初始化。

pfn_to_page的定义如下:

#define pfn_to_page(pfn)    virt_to_page(pfn_to_virt(pfn))

#define pfn_to_virt(pfn)    __va((pfn) << PAGE_SHIFT)

#define __va(paddr)         phys_to_virt((unsigned long)(paddr))

#define phys_to_virt(vaddr) ((void *) (vaddr))

#define virt_to_page(addr)  (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))

其实就是根据一个内存地址找到它所在页的描述结构page

/*

 * Setup the page count before being freed into the page allocator for

 * the first time (boot or memory hotplug)

 */

static inline void init_page_count(struct page *page)

{

     atomic_set(&page->_count, 1);

}

_count成员初始化为1

/*

 * The atomic page->_mapcount, like _count, starts from -1:

 * so that transitions both from it and to it can be tracked,

 * using atomic_inc_and_test and atomic_add_negative(-1).

 */

static inline void reset_page_mapcount(struct page *page)

{

     atomic_set(&(page)->_mapcount, -1);

}

比较简单,将_mapcount值设置为1

#define SetPageReserved(page)    set_bit(PG_reserved, &(page)->flags)

从这里可以看出,初始化后的flags成员将带有唯一的标记PG_reserved

 

 

1.1.1.2             set_page_links

此函数位于include/linux/mm.h

static inline void set_page_links(struct page *page, enum zone_type zone,

     unsigned long node, unsigned long pfn)

{

     set_page_zone(page, zone);

     set_page_node(page, node);

     set_page_section(page, pfn_to_section_nr(pfn));

}

static inline void set_page_zone(struct page *page, enum zone_type zone)

{

     page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT);

     page->flags |= (zone & ZONES_MASK) << ZONES_PGSHIFT;

}

在这个函数中,zone值为ZONE_DMA,即0值,因此这个函数相当于啥也不做。

static inline void set_page_section(struct page *page, unsigned long var_section)

{

     page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT);

     page->flags |= (var_section & SECTIONS_MASK) << SECTIONS_PGSHIFT;

}

#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)

#define PFN_SECTION_SHIFT 0

#define SECTIONS_PGSHIFT    (SECTIONS_PGOFF * (SECTIONS_WIDTH != 0))

#define SECTIONS_WIDTH      0

#define SECTIONS_MASK       ((1UL << SECTIONS_WIDTH) - 1)

这个函数也相当于什么都不做。

因而set_page_links这个函数相当于一个空函数。

 

 

参考资料

uClinux2.6(bf561)中的CPLB( 2008/2/19 )

uclinux2.6(bf561)中的bootmem分析(1):猜测( 2008/5/9 )

uclinux2.6(bf561)中的bootmem分析(2):调用前的参数分析( 2008/5/9 )

uclinux2.6(bf561)中的bootmem分析(3)init_bootmem_node( 2008/5/9 )

uclinux2.6(bf561)中的bootmem分析(4)alloc_bootmem_pages( 2008/5/9 )

uclinux2.6(bf561)内核中的paging_init( 2008/5/12 )

uclinux-2008r1(bf561)内核的icache支持(1):寄存器配置初始化( 2008/5/16 )

uclinux-2008r1(bf561)内核的icache支持(2)icplb_table的生成( 2008/5/16 )

uclinux-2008r1(bf561)内核的icache支持(3)__fill_code_cplbtab( 2008/5/16 )

uclinux-2008r1(bf561)内核的icache支持(4):换页问题( 2008/5/16 )

再读uclinux-2008r1(bf561)内核中的bootmem( 2008/6/3 )

uclinux-2008r1(bf561)内核中与存储管理相关的几个全局变量( 2008/6/4 )

uclinux-2008r1(bf561)内核存储区域初探( 2008/6/4 )

uclinux-2008r1(bf561)内核中的zonelist初始化( 2008/6/5 )

uclinux-2008r1(bf561)内核中内存管理相关的几个结构体( 2008/6/5 )

再读内核存储管理(1):相关的全局变量( 2008/6/17 )

再读内核存储管理(2):相关的数据结构( 2008/6/17 )

再读内核存储管理(3)bootmem分配策略( 2008/6/17 )

再读内核存储管理(4):存储区域管理( 2008/6/17 )

再读内核存储管理(5)buddy算法( 2008/6/17 )

再读内核存储管理(6):高速缓存的应用( 2008/6/17 )

再读内核存储管理(7)icache支持( 2008/6/17 )

再读内核存储管理(8):片内SRAM的使用( 2008/6/17 )

初读SLAB( 2008/6/26 )

三读bootmem( 2008/7/24 )

再读uclinux-2008r1(bf561)内核存储区域管理(1):相关数据结构( 2008/7/25 )

再读uclinux-2008r1(bf561)内核存储区域管理(2):可用页表初始化( 2008/7/25 )

再读uclinux-2008r1(bf561)内核存储区域管理(3):zone初始化( 2008-7-25 )

再读uclinux-2008r1(bf561)内核存储区域管理(4):zonelist初始化( 2008-7-25 )

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌云阁主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值