Linux Memory初始化过程

您所在的位置:网站首页 结界师男主和女主在一起了吗 Linux Memory初始化过程

Linux Memory初始化过程

2024-07-15 11:30:10| 来源: 网络整理| 查看: 265

文章目录 Linux Memory初始化过程start_kernel()setup_arch()boot memeory allocator初始化页表初始化Zone初始化以及buddy allocator初始化 mem_init()kmem_cache_init()

Linux Memory初始化过程 start_kernel()

首先我们来看看Linux的系统启动函数中的start_kernel()中与memory相关的处理步骤:

asmlinkage void __init start_kernel(void) { ........... setup_arch(&command_line); ....................... build_all_zonelists();//create zone fallback order page_alloc_init();//register callback ............... mem_init(); //boot memory retire,create buddy allocator kmem_cache_init();//init slab allocator ........... anon_vma_init();//create a vma slab ................. }

从start_kernel()函数,memory相关的步骤,可以大致分为三大块:

setup_arch(): boot memory allocator初始化 和直接映射和固定映射的页表创建,然后再 启动分页单元,再初始化每个Node下的Zonemem_init(): 将boot memory allocator退休,将已经在boot memory阶段使用的memory标示为reserve,将未使用的memory以page为单位释放给buddy allocatorkeme_cache_init():初始化slab allocator的原始slab:cache_cache,在此过后,slab allocator开始使用。

start_kernel

setup_arch()

在setup_arch() 函数下,做了好多事情,下面来详细讲述下:

boot memeory allocator初始化

下面是boot memory allocator的初始化核心函数,每个node下都有一个boot memory allocator, 然后再初始化boot memory allocator结构pgdat->bdata:

node_boot_start:当前bootmem_data结构中所描述的memory块的起始物理地址。 node_low_pfn:当前bootmem_data结构中所描述memory块的结束pfn。换句话说,就是该node中ZONE_NORMAL的结束物理地址。 node_bootmem_map:代表page分配状态的bitmap的地址。 last_offset:在某个page中上次分配完成之后的偏移。如果为0,则代表该page全部被分配完了。 last_pos:上次分配所使用的page的PFN。将last_pos和last_offset联合起来,可以测试多个分配是否可以合并到一个page中进行而不是使用一个全新的page last_success:上次分配所对应的物理地址

static unsigned long __init init_bootmem_core (pg_data_t *pgdat, unsigned long mapstart, unsigned long start, unsigned long end) { bootmem_data_t *bdata = pgdat->bdata; unsigned long mapsize = ((end - start)+7)/8;//node_bootmem_map 大小,字节对齐 pgdat->pgdat_next = pgdat_list;//将node插入到list中 pgdat_list = pgdat; mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL); bdata->node_bootmem_map = phys_to_virt(mapstart unsigned long vaddr; pgd_t *pgd_base = swapper_pg_dir; ......... kernel_physical_mapping_init(pgd_base); //分配直接映射的page table remap_numa_kva(); /* * Fixed mappings, only the page table structure has to be * created - mappings will be set by set_fixmap(): */ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; page_table_range_init(vaddr, 0, pgd_base);//分配高端内存中固定映射需要的页表 permanent_kmaps_init(pgd_base); ......... }

页表的初始化,被分为两个阶段: 第一阶段,启动初始化阶段,在内核静态代码中有静态定义swapper_pg_dir 为全局pgd,其中内核代码使用物理地址1MB ~ 9MB的这8Mb空间,因此在内核启动阶段,会生成临时内核页表项:pg0和pg1,其中pg0 对应swapper_pg_dir中的第0项和第768项,pg1位第1项和第769项,因此内核启动阶段静态代码在分页机制为启动之前就可以使用临时内核页表所映射的虚拟地址了 第二阶段,虚拟地址低端内存的部分以及虚拟地址高端内存固定映射的页表分配。 其中kernel_physical_mapping_init() 映射低端内存的页表项 而page_table_range_init()分配用用映射高端内存固定映射的部分的页表项。 其中pmd和pte的物理页框的分配用到了boot memory allocator的函数:alloc_bootmem_low_pages()

Zone初始化以及buddy allocator初始化

zone_sizes_init()函数循环初始化每一个node中的各个zone,根据配置项中的配置得知每个node的物理页框范围,然后再计算出各个node下各个zone的物理页框起始位置,和大小,再调用free_area_init_node()来初始化zone.

void __init free_area_init_node(int nid, struct pglist_data *pgdat, unsigned long *zones_size, unsigned long node_start_pfn, unsigned long *zholes_size) { pgdat->node_id = nid; pgdat->node_start_pfn = node_start_pfn; calculate_zone_totalpages(pgdat, zones_size, zholes_size); if (!pfn_to_page(node_start_pfn)) node_alloc_mem_map(pgdat); //如果是NUMA,则需要动态分配mem_map的空间,如果是UMA,则直接使用contig_page_data.node_mem_map静态定义的物理地址,alloc_bootmem_node()分配n个struct page大小 free_area_init_core(pgdat, zones_size, zholes_size); } static void __init free_area_init_core(struct pglist_data *pgdat, unsigned long *zones_size, unsigned long *zholes_size) { unsigned long i, j; const unsigned long zone_required_alignment = 1UL node_start_pfn; pgdat->nr_zones = 0; init_waitqueue_head(&pgdat->kswapd_wait); for (j = 0; j struct page *start = pfn_to_page(start_pfn); struct page *page; for (page = start; page int order; for (order = 0; ; order++) { unsigned long bitmap_size;

INIT_LIST_HEAD(&zone->free_area[order].free_list); if (order == MAX_ORDER-1) { zone->free_area[order].map = NULL; break; } bitmap_size = pages_to_bitmap_size(order, size); zone->free_area[order].map = (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size); }

}

mem_init()

主要是调用free_all_bootmem_core()来释放low memory到buddy allocator,set_highmem_pages_init()来释放high memory到buddy allocator。 其中free_all_bootmem_core()的核心步骤如下: (1)boot memory allocator中未分配的pages: 清除struct page中的PG_reserve的标记位 将count设置为1 调用__free_pages()将memory移交给buddy allocator来构建它的free lists (2) 释放bitmap中使用过的pages并将这些pages移交给buddy allocator。

kmem_cache_init()

初始化slab allocator的第一个object:cache_cache



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭