mips架构linux启动分析(六)(arch_mem_init(node内存)内存初始化)

本文分析了MIPS架构下Linux系统的内存初始化过程,包括zone结构的初始化、页表的建立、非线性区域的配置、DMA地址映射以及多核CPU间的IPI初始化和缓存设置等关键步骤。
摘要由CSDN通过智能技术生成
这里开始就是各个node的内存的初始化了。
OK,直接看代码.
static void __init arch_mem_init(char **cmdline_p)
{
	extern void plat_mem_setup(void);

//定义板级的屏幕的相关信息
	plat_mem_setup();
//把代码段也加入到boot_mem_map进行管理(bootm机制)
	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
			 BOOT_MEM_RAM);
//把init段(初始化段)也加入到boot_mem_map中进行管理
	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, BOOT_MEM_INIT_RAM);

//在arcs_cmdline之后加入一个空格后,在把builtin_cmdline加入其中
	if (builtin_cmdline[0]) {
	   strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
	   strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
	}
//把arcs_cmdline拷贝到boot_command_line
	strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
//把boot_command_line拷贝到command_line中
	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
//用指针cmdline_p指向command_line
	*cmdline_p = command_line;
//对参数进行解析
	parse_early_param();
//bootmem的初始化
	bootmem_init();
//mips中crashkernel时的信息段
	mips_parse_crashkernel();
//把crashkernel段设置为保留段
	if (crashk_res.start != crashk_res.end)
		reserve_bootmem(crashk_res.start,
				crashk_res.end - crashk_res.start + 1,
				BOOTMEM_DEFAULT);
//空函数
	device_tree_init();
//分配的一个非线形段(no_liner section),具体作用,还不是很清楚??????????
	sparse_init();
//tlb信息的初始化
	plat_swiotlb_setup();
设置区zones
	paging_init();
}

定义板级screen的信息:

void __init plat_mem_setup(void)
{
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
	conswitchp = &vga_con;

	screen_info = (struct screen_info) {
		.orig_x			= 0,
		.orig_y			= 25,
		.orig_video_cols	= 80,
		.orig_video_lines	= 25,
		.orig_video_isVGA	= VIDEO_TYPE_VGAC,
		.orig_video_points	= 16,
	};
#elif defined(CONFIG_DUMMY_CONSOLE)
	conswitchp = &dummy_con;
#endif
#endif
}

怎么把一个段加入到boot_mem_map中进行管理呢?

static void __init arch_mem_addpart(phys_t mem, phys_t end, int type)
{
	phys_t size;
	int i;

	size = end - mem;
//如果要加入的段在boot_mem_map中,就退出
	for (i = 0; i < boot_mem_map.nr_map; i++) {
		if (mem >= boot_mem_map.map[i].addr &&
		    mem < (boot_mem_map.map[i].addr +
			   boot_mem_map.map[i].size))
			return;
	}
//把这段区域加入到boot_mem_map中
	add_memory_region(mem, size, type);
}

void __init add_memory_region(phys_t start, phys_t size, long type)
{
	int x = boot_mem_map.nr_map;
	int i;

//把要加入的段和已有的段进行合并
	for (i = 0; i < boot_mem_map.nr_map; i++) {
//从boot_mem_map第一个开始读取
		struct boot_mem_map_entry *entry = boot_mem_map.map + i;
		unsigned long top;
//如果类型不同,则进行下一个
		if (entry->type != type)
			continue;
//如果这个region大于要加入段的地址,则进行下一个
		if (start + size < entry->addr)
			continue;			/* no overlap */
//如果这个region小于要加入段的地址,则进行下一个
		if (entry->addr + entry->size < start)
			continue;			/* no overlap */
//到这里说明两个地址有重叠的部分,然后进行合并
		top = max(entry->addr + entry->size, start + size);
		entry->addr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值