Linux初始化内核临时页表之后的setup_memory函数
话说在linux内核初始化完内核临时页表来映射前8MB内存后,在欲望的驱使下,linux开始着手抢占
896MB以下的内存了。然而抢夺这896MB内存绝非易事。linux还有许多麻烦的事要做。比如说进攻和占领伊拉克等等。于是
setup_memory函数开始为linux策划和筹备此事。主要任务是建立一张与物理内存页框号对应的位图。如果该页框被占用则对应位图中的位被置
1,否则置0。在伙伴系统建立前对内存进行临时管理。在初始化内核最终页表时alloc_bootmem_low_pages内存分配函数就用到了这个位
图。
核心数据结构:
typedef struct
bootmem_data
{
unsigned long node_boot_start; /* 起始页框号0 */
unsigned long node_low_pfn; /* 如果物理内存大于896MB,node_low_pfn为0x37FFF。
如果物理内存小于等于896MB,node_low_pfn为物理内存的最大页框号。*/
void *node_bootmem_map; /* 位图的起始地址 */
/* 下面三个变量的作用用于alloc_bootmem_low_pages函数 */
unsigned long last_offset;
unsigned long last_pos;
unsigned long last_success;
}
bootmem_data_t
;
创建位图的函数流程:
start_kernel->setup_arch->setup_memory->init_bootmem
->init_bootmem_core
。
linux/arch/i386/kernel/setup.c
在setup_memory()中执行
start_pfn = PFN_UP(init_pg_tables_end);
/* start_pfn是指映射8MB所用页表之后第一个页框号。PFN_UP的作用是把地址按页的大小进行对齐。也就是地址是4kb的整数倍大小。*/
find_max_pfn();
/* 找到物理内存中最大页框号。放入max_pfn中。*/
max_low_pfn=find_max_low_pfn();
/* 如果物理地址小于等于896MB,max_low_pfn=max_pfn。大于896MB时,max_low_pfn为896MB内存大小的最大页框号 */
bootmap_size = init_bootmem(start_pfn,max_low_pfn);
进入init_bootmem中
unsigned long
__init
init_bootmem
(unsigned long
相关文档:
Service Discovery Protocol(SDP)提供一种能力,让应用程序有方法发现哪种服务可用以及这种服务的特性。
服务发现协议(SDP或Bluetooth SDP)在蓝牙协议栈中对蓝牙环境中的应用程序有特殊的含意,发现哪个服务是可用的和确定这些可用服务的特征。SDP定义了bluetooth client发现可用bluetooth server服务和它们的特征的方法。 ......
举例来说,硬盘的文件名称即为 /dev/hd[a-d] ,其中, 括号内的字母为 a-d 当中的任何一个,亦即由 /dev/hda, /dev/hdb, /dev/hdc, 及 /dev/hdd 这四个档案的意思 (注:这种型式的表示法在后面的章节当中会使用得很频繁,请特别留意)。 那么光驱与软盘呢?分别是 /dev/cdrom, /dev/fd0 啰! 好了,其它的接口设备呢? ......
大家知道Linux中创建子进程的一个很好的方法是函数调用fork,但是很多初学者对fork的理解上可能有点困难。下面举个例子来看看fork的用法吧。
其实,大家用fork的时候记住fork是“分叉”的意思就很好理解了。
  ......
解释一:
高端内存是指物理地址大于 896M 的内存。
对于这样的内存,无法在“内核直接映射空间”进行映射。
为什么?
因为“内核直接映射空间”最多只能从 3G 到 4G,只能直接映射 1G 物理内存,对于大于 1G 的物理内存,无能为力。
实际上,“内核直接映射空间”也达不到 1G, 还得留点 ......