mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-09-26 15:33:35 +08:00
...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+85
-12
@@ -154,23 +154,61 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
这个阶段的内存分配其实很简单, 因此我们往往称之为内存分配器(而不是内存管理器), 早期的内核中内存分配器使用的**bootmem引导分配器**, 它基于一个内存位图bitmap, 使用最优适配算法来查找内存, 但是这个分配器有很大的缺陷, 最严重的就是内存碎片的问题, 因此在后来的内核中将其舍弃《而使用了**新的memblock机制**. memblock机制的初始化在arm64上是通过[arm64_memblock_init](http://lxr.free-electrons.com/source/arch/arm64/kernel/setup.c?v=4.7#L229)函数来实现的
|
||||
|
||||
```cpp
|
||||
```cpp
|
||||
start_kernel()
|
||||
|---->page_address_init()
|
||||
| 考虑支持高端内存
|
||||
| 业务:初始化page_address_pool链表;
|
||||
| 将page_address_maps数组元素按索引降序插入
|
||||
| page_address_pool链表;
|
||||
| 初始化page_address_htable数组.
|
||||
|
|
||||
|---->setup_arch(&command_line);
|
||||
| 初始化特定体系结构的内容
|
||||
|
|
||||
|---->arm64_memblock_init( );
|
||||
| 初始化引导阶段的内存分配器memblock
|
||||
|
|
||||
|---->paging_init();
|
||||
| 分页机制初始化
|
||||
|
|
||||
|---->bootmem_init();
|
||||
| 始化内存数据结构包括内存节点, 内存域和页帧page
|
||||
|
|
||||
|---->arm64_numa_init();
|
||||
| 支持numa架构
|
||||
|
|
||||
|---->zone_sizes_init(min, max);
|
||||
来初始化节点和管理区的一些数据项
|
||||
|
|
||||
|---->free_area_init_node
|
||||
| 初始化内存节点
|
||||
|
|
||||
|---->free_area_init_core
|
||||
| 初始化zone
|
||||
|
|
||||
|---->memmap_init
|
||||
| 初始化page页面
|
||||
|
|
||||
|---->memblock_dump_all();
|
||||
| 初始化完成, 显示memblock的保留的所有内存信息
|
||||
|
|
||||
|---->build_all_zonelist() [当前位置]
|
||||
| 为系统中的zone建立后备zone的列表.
|
||||
| 所有zone的后备列表都在
|
||||
| pglist_data->node_zonelists[0]中;
|
||||
|
|
||||
| 期间也对per-CPU变量boot_pageset做了初始化.
|
||||
|
|
||||
```
|
||||
|
||||
|
||||
|
||||
##1.6 今日内容(第二阶段--初始化buddy内存管理)
|
||||
##1.6 今日内容(第二阶段(二)--初始化备用内存域列表zonelists)
|
||||
-------
|
||||
|
||||
|
||||
**初始化内存分页机制**
|
||||
|
||||
|
||||
在初始化内存的结点和内存区域之前, 内核先通过pagging_init初始化了内核的分页机制, 这样我们的虚拟运行空间就初步建立, 并可以完成物理地址到虚拟地址空间的映射工作.
|
||||
|
||||
|
||||
在arm64架构下, 内核在start_kernel()->setup_arch()中通过arm64_memblock_init( )完成了memblock的初始化之后, 接着通过setup_arch()->paging_init()开始初始化分页机制
|
||||
|
||||
|
||||
paging_init负责建立只能用于内核的页表, 用户空间是无法访问的. 这对管理普通应用程序和内核访问内存的方式,有深远的影响
|
||||
我们之前讲了在memblock完成之后, 内存初始化开始进入第二阶段, 第二阶段是一个漫长的过程, 它执行了一系列复杂的操作, 从体系结构相关信息的初始化慢慢向上层展开, 其主要执行了如下操作
|
||||
|
||||
|
||||
|
||||
@@ -179,6 +217,41 @@ paging_init负责建立只能用于内核的页表, 用户空间是无法访问
|
||||
|
||||
在完成了基础的内存结点和内存域的初始化工作以后, 我们必须克服一些硬件的特殊设置
|
||||
|
||||
* 在初始化内存的结点和内存区域之前, 内核先通过pagging_init初始化了内核的分页机制, 这样我们的虚拟运行空间就初步建立, 并可以完成物理地址到虚拟地址空间的映射工作.
|
||||
|
||||
在arm64架构下, 内核在start_kernel()->setup_arch()中通过arm64_memblock_init( )完成了memblock的初始化之后, 接着通过setup_arch()->paging_init()开始初始化分页机制
|
||||
|
||||
|
||||
paging_init负责建立只能用于内核的页表, 用户空间是无法访问的. 这对管理普通应用程序和内核访问内存的方式,有深远的影响
|
||||
|
||||
|
||||
* 在分页机制完成后, 内核通过setup_arch()->bootmem_init开始进行内存基本数据结构(内存结点pg_data_t, 内存域zone和页帧)的初始化工作, 就是在这个函数中, 内核开始从体系结构相关的部分逐渐展开到体系结构无关的部分, 在zone_sizes_init->free_area_init_node中开始, 内核开始进行内存基本数据结构的初始化, 也不再依赖于特定体系结构无关的层次
|
||||
|
||||
```cpp
|
||||
bootmem_init
|
||||
始化内存数据结构包括内存节点, 内存域和页帧page
|
||||
|
|
||||
|---->arm64_numa_init();
|
||||
| 支持numa架构
|
||||
|
|
||||
|---->zone_sizes_init(min, max);
|
||||
来初始化节点和管理区的一些数据项
|
||||
|
|
||||
|---->free_area_init_node
|
||||
| 初始化内存节点
|
||||
|
|
||||
|---->free_area_init_core
|
||||
| 初始化zone
|
||||
|
|
||||
|---->memmap_init
|
||||
| 初始化page页面
|
||||
|
|
||||
|---->memblock_dump_all();
|
||||
| 初始化完成, 显示memblock的保留的所有内存信息
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
**建立内存管理的数据结构**
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Reference in New Issue
Block a user