结构体 一、引导内存分配器 bootmem 简介 ---- 1、引导内存分配器 bootmem 引入 Linux 内核 初始化 时 , 需要进行内存分配 , 启动阶段的 内存分配 与 运行时的 内存分配...机制不同 ; 此时 Linux 内核 提供了一个 临时的 " 引导内存分配器 bootmem " , 该 内存分配器 只在启动过程中使用 , 启动完成后 , 就会被丢弃 ; 2、引导内存分配器 bootmem...工作机制 " 引导内存分配器 bootmem " 工作机制如下 : Linux 内核初始化过程中 , 临时提供一个 " 引导内存分配器 bootmem " , 引导内存分配器 bootmem 的主要作用是...bootmem 描述 bootmem_data 结构体 ---- 在 Linux 内核中 , 使用 struct bootmem_data 结构体 , 描述 " 引导内存分配器 bootmem " ;...struct bootmem_data 结构体 定义在 Linux 内核源码的 linux-4.12\include\linux\bootmem.h#33 位置 , 源码如下 : /* * node_bootmem_map
成员 5、hint_idx成员 二、引导内存分配器 bootmem_data 与 内存节点 pglist_data 的关联 在上一篇博客 【Linux 内核 内存管理】引导内存分配器 bootmem...① ( 引导内存分配器 bootmem 工作机制 | 引导内存分配器 bootmem 的描述 bootmem_data 结构体 ) 引入了 " 引导内存分配器 bootmem " 其作用是在 Linux...last_end_off; unsigned long hint_idx; struct list_head list; } bootmem_data_t; 源码路径 : linux-4.12\include...\linux\bootmem.h#33 一、bootmem_data 结构体源码分析 ---- bootmem_data 结构体 成员分析 : 1、node_min_pfn 成员 node_min_pfn...#ifndef CONFIG_NO_BOOTMEM struct bootmem_data *bdata; #endif ... }
在许多CPU上, 必须显式设置适用于Linux内核的内存模型. 例如在x86_32上需要切换到保护模式, 然后内核才能检测到可用内存和寄存器....include/linux/bootmem.h?...___alloc_bootmem_nopanic table th:nth-of-type(1){ width: 30%; } 这些函数的定义在include/linux/bootmem.h http...://lxr.free-electrons.com/source/include/linux/bootmem.h?.../linux/bootmem.h #define alloc_bootmem_low(x) \ __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0) #define
文章目录 一、bootmem 引导内存分配器算法 1、低端内存映射 2、内存记录位图 3、最先适配算法 4、内存分配记录 二、bootmem 引导内存分配器 内存操作 函数 ( alloc_bootmem...| free_bootmem ) 一、bootmem 引导内存分配器算法 ---- bootmem 引导内存分配器算法 ; 1、低端内存映射 低端内存映射 : 内核启动过程中 , 将 " 低端内存 "...后面的 物理页位置 索引 , 下次分配优先分配该索引 物理页 ; 在下一次分配内存时 , 如果 上次内存分配的物理页 的剩余空间 小于等于 要分配的内存 , 那么 直接在该 物理页 上分配内存 ; 二、bootmem...引导内存分配器 内存操作 函数 ( alloc_bootmem | free_bootmem ) ---- " bootmem 引导内存分配器 " 对外提供的 内存操作 函数如下 : 内存分配函数 :...alloc_bootmem 内存释放函数 : free_bootmem 注意 : 在 ARM64 架构中 , 没有使用 引导内存分配器 ;
linux内存三大分配器:引导内存分配器,伙伴分配器,slab分配器 一、引导内存分配器 1.引导内存分配器的作用因为内核里面有很多内存结构体,不可能在静态编译阶段就静态初始化所有的这些内存结构体。...2.引导内存分配器的原理在Linux内核中使用struct bootmem_data来描述一个引导内存分配,其节点结构下的一个成员,也就是说每一个节点都有一个引导内存分配。...linux内核可以通过宏定义选择nobootmem 或者bootmem 来在伙伴起来之前管理内存。...这两种机制对提供的API是一致的,因此对用户是透明的 5.bootmem小分析bootmem结构体位于文件include/linux/bootmem.h: typedef struct bootmem_data...; bootmem接口函数: 1)bootmem分配内存函数:alloc_bootmem 2)bootmem释放内存函数:free_bootmem #define alloc_bootmem(x) \
Linux面试专题 1 Linux中主要有哪几种内核锁? Linux 的同步机制不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。...下面就是申请并导出启动内存的一段示例代码: void* x_bootmem = NULL; EXPORT_SYMBOL(x_bootmem); unsigned long x_bootmem_size...= 0; EXPORT_SYMBOL(x_bootmem_size); static int __init x_bootmem_setup(char *str) { x_bootmem_size...= memparse(str, &str); x_bootmem = alloc_bootmem(x_bootmem_size); printk(“Reserved %lu bytes from...%p for x\n”, x_bootmem_size, x_bootmem); return 1; } __setup(“x-bootmem=”, x_bootmem_setup); 可见其应用还是比较简单的
而我们今天要讲的boot阶段就是系统初始化阶段使用的内存分配器. 1 前景回顾 1.1 Linux内存管理的层次结构 Linux把物理内存划分为三个层次来管理 层次 描述 存储节点(Node) CPU被划分为多个节点...尤其是, Linux内核必须处理80x86体系结构的两种硬件约束....因此我们可以把linux内核的内存管理分三个阶段。...在UMA系统上该分配的实现与CPU无关, 而NUMA系统内存结点与CPU相关联, 因此采用了特定体系结构的解决方法. bootmem_data的结构定义在include/linux/bootmem.h?...obj-y += bootmem.o endif 由于接口是一致的, 那么他们共同使用一份 头文件 bootmem接口 nobootmem接口 include/linux/
(); } 流程 描述 arm64_memblock_init 初始化memblock内存分配器 paging_init 初始化分页机制 bootmem_init 初始化内存管理 该函数主要执行了如下操作...这个阶段的内存分配其实很简单, 因此我们往往称之为内存分配器(而不是内存管理器), 早期的内核中内存分配器使用的bootmem引导分配器, 它基于一个内存位图bitmap, 使用最优适配算法来查找内存,...移交早期的分配器到内存管理器 最后我们的内存管理器已经初始化并设置完成, 可以投入运行了, 因此内核将内存管理的工作从早期的内存分配器(bootmem或者memblock)移交到我们的buddy伙伴系统...内核将繁重的内存数据结构创建和初始化的工作交给free_area_init_node(s)函数来完成, 3 free_area_init_nodes初始化NUMA管理数据结构 注意 此部分内容参照 Linux...内存管理伙伴算法 linux 内存管理 - paging_init 函数 free_area_init_nodes初始化了NUMA系统中所有结点的pg_data_t和zone、page的数据, 并打印了管理区信息
手把手教你分析 Linux 启动流程 上一次咱们分析了 Linux 的启动流程和初始化流程,今天主要分析一下内存方面的初始化和常见的内存分配方式。...start_kernel |--->mm_init |--->mem_init linux4.14/init/main.c 在 mem_init 函数中会初始化伙伴系统和 slab...2、有的人可能知道 Linux 有一个 bootmem 分配器,这个是在Linux初始化过程中的一个临时分配器,他会在 setup_arch 函数中初始化,然后在 mm_init 中关掉,只是在伙伴系统出现之前的临时使用...bootmem 分配器按块进行分配,颗粒度很大,不够精细,比较浪费内存。bootmem 分配器只会在 start_kernel 函数和mm_init 函数之前存在,中间的函数会调用它进行内存分配。...start_kernel |--->setup_arch |--->paging_init |--->bootmem_init ·············
前面已经分析了linux内存管理算法(伙伴管理算法)的准备工作。...* With CONFIG_DEBUG_PAGEALLOC initialization of highmem pages has to * be done before free_all_bootmem...managed_pages则是记录管理区的管理页面数,totalhigh_pages则是记录高端内存的页面总数; 具体看一下__free_reserved_page(): 【file:/include/linux...ClearPageReserved(page); init_page_count(page); __free_page(page); } 其中ClearPageReserved定义在/include/linux...接着回到mem_init ()里面下一个调用free_all_bootmem(): 【file:/mm/nobootmem.c】 unsigned long __init free_all_bootmem
在linux内核中,所有的物理内存都用struct page结构来描述,这些对象以数组形式存放,而这个数组的地址就是mem_map。...mem_map的定义 /* \linux\mm\memory.c */ #ifndef CONFIG_NEED_MULTIPLE_NODES /* use the per-pgdat data instead...+0x16c/0x1b0) [ 0.000000] [] (bootmem_init) from [] (paging_init+0xd28/0xd90)...*/ alloc_node_mem_map源码分析 /* \linux\mm\page_alloc.c */ static void __ref alloc_node_mem_map(struct pglist_data...offset = pgdat->node_start_pfn - start; /* ia64 gets its own node_mem_map, before this, without bootmem
kernel需要从该物理地址上读取到dtb文件并解析,才能得到最终的内存信息 上面两个步骤可以简单参考上篇文章,本文在上面2个步骤的基础上延续向下讲,进入 paging_init()和 bootmem_init...void __init bootmem_init(void) { unsigned long min, max; min = PFN_UP(memblock_start_of_DRAM());...PAGE_SHIFT); max_pfn = max_low_pfn = max; arm64_numa_init(); /* * Sparsemem tries to allocate bootmem...「Linux是如何组织物理内存的?」...最后 至此linux对物理内存的初始化和虚拟地址和物理地址的映射关系算是告一段落,相信你已经知道 linux 虚拟寻址空间layout的来龙去脉,以及如何把物理内存通过node, zone, page
内核启动源码 start_kernel ---- 在 Linux 内核初始化完成后 , 会在 " 初始化内存 " 时 , 输出 内存布局 ; Linux 内核启动源码是定义在 linux-5.6.18.../ ... /* * These use large bootmem allocations and must precede * kmem_cache_init() */ setup_log_buf...extra init args", extra_init_args, NULL, 0, -1, -1, NULL, set_init_arg); /* * These use large bootmem...set_highmem_pages_init(); /* this will put all low memory onto the freelists */ memblock_free_all(); after_bootmem...= 1; x86_init.hyper.init_after_bootmem(); mem_init_print_info(NULL); printk(KERN_INFO "virtual kernel
内核中 , 使用 pglist_data 结构体 描述 " 内存节点 " , 该结构体定义在 Linux 内核源码中的 linux-4.12\include\linux\mmzone.h#601 位置...内核中 , 使用 pglist_data 结构体 描述 " 内存节点 " , 该结构体定义在 Linux 内核源码中的 linux-4.12\include\linux\mmzone.h#601 位置...Memory statistics and page replacement data structures are maintained on a * per-zone basis. */ struct bootmem_data...node_mem_map; #ifdef CONFIG_PAGE_EXTENSION struct page_ext *node_page_ext; #endif #endif #ifndef CONFIG_NO_BOOTMEM...struct bootmem_data *bdata; #endif #ifdef CONFIG_MEMORY_HOTPLUG /* * Must be held any time you expect
root@sw6a:~# uname -a Linux sw6a 4.4.15-deepin-aere #176 SMP Thu Dec 19 17:36:51 CST 2019 sw_64 GNU/Linux...12582912 [ 0.000000] memcluster 3, usage 0, start 12584056, end 16777216 [ 0.000000] Initializing bootmem...start 1144, end 4194304 [ 0.000000] freeing pages 1144:4194304 [ 0.000000] Initializing bootmem...start 4195448, end 8388608 [ 0.000000] freeing pages 4195448:8388608 [ 0.000000] Initializing bootmem...start 8389752, end 12582912 [ 0.000000] freeing pages 8389752:12582912 [ 0.000000] Initializing bootmem
下面就是申请并导出启动内存的一段示例代码: void* x_bootmem = NULL; EXPORT_SYMBOL(x_bootmem); unsigned long x_bootmem_size...= 0; EXPORT_SYMBOL(x_bootmem_size); static int __init x_bootmem_setup(char *str) { x_bootmem_size = memparse...(str, &str); x_bootmem = alloc_bootmem(x_bootmem_size); printk("Reserved %lu bytes from %p for x\n",...x_bootmem_size, x_bootmem); return 1; } __setup("x-bootmem=", x_bootmem_setup); 可见其应用还是比较简单的,不过利弊总是共生的...30) Linux软中断和工作队列的作用是什么? Linux中的软中断和工作队列是中断处理。
作者简介:伟林,中年码农,从事过电信、手机、安全、芯片等行业,目前依旧从事Linux方向开发工作,个人爱好Linux相关知识分享。...Buddy 简介 内存是计算机系统中最重要的核心资源之一,Buddy 系统是 Linux 最底层的内存管理机制,它使用 Page 粒度来管理内存。...这就是 Buddy 系统初始的状态,除了保留的内存,其他的内存都处于 Free 状态: start_kernel() → mm_init() → mem_init() → free_all_bootmem...(): unsigned long __init free_all_bootmem(void) { unsigned long pages; /* (1) 将每个node每个zone管理的...*/ while (start + (1UL end) order--; /* (2.2.1.2) 继续释放 */ __free_pages_bootmem
现在的服务器大部分都是运行在Linux上面的,所以,作为一个程序员有必要简单地了解一下系统是如何运行的。...机器指令中出现的是逻辑地址,逻辑地址规则如下: 在Linux中的逻辑地址等于线性地址,也就是说Inter为了兼容把事情搞得很复杂,Linux简化顺便偷个懒。...内存管理的方式 在系统boot的时候会去探测内存的大小和情况,在建立复杂的结构之前,需要用一个简单的方式来管理这些内存,这就是bootmem,简单来说就是位图,不过其中也有一些优化的思路。...bootmem再怎么优化,效率都不高,在要分配内存的时候毕竟是要去遍历,buddy系统刚好能解决这个问题:在内部保存一些2的幂次大小的空闲内存片段,如果要分配3page,去4page的列表里面取一个,分配...Linux中使用slab来解决小对象的分配: 在运行时,slab向buddy“批发”一些内存,加工切块以后“散卖”出去。
如下图,这是前面已经看到过的linux物理内存管理框架的层次关系。 ? 现着重分析一下各个管理结构体的成员功能作用。...【file:/include/linux/mmzone.h】 typedef struct pglist_data { struct zone node_zones[MAX_NR_ZONES];...*bdata; ——该数据指向bootmem_node_data,可以通过system.map查到。...kswapd_max_order; ——用于表示kswapd守护线程每次回收的页面个数; enum zone_type classzone_idx; ——该成员与kswapd有关; 【file:/include/linux...int nr_migrate_reserve_block; ——用于优化的,记录内存迁移保留的页面数; const char *name; ——用于记录该管理区的名字; 【file:/include/linux
bottom_up 成员 2、current_limit 成员 3、memory 成员 4、reserved 成员 5、physmem 成员 三、物理内存类型 与 内存类型 ARM64 架构体系中 , 不能使用 bootmem...引导内存分配器 , 使用的是 memblock 分配器 ; 一、memblock 分配器 ---- memblock 分配器 定义在 Linux 内核源码的 linux-4.12\include\linux...memblock_type reserved; #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP struct memblock_type physmem; #endif }; 源码路径 : linux...-4.12\include\linux\memblock.h#48 二、memblock 结构体分析 ---- 1、bottom_up 成员 bottom_up 成员表示 内存分配方式 , TRUE
领取专属 10元无门槛券
手把手带您无忧上云