这里开始就是各个node的内存的初始化了。
OK,直接看代码.
怎么把一个段加入到boot_mem_map中进行管理呢?
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