博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核源码分析_setup_arch函数的主要作用
阅读量:4180 次
发布时间:2019-05-26

本文共 3664 字,大约阅读时间需要 12 分钟。

`一、setup_arch函数的主要作用

start_kernel
中,调用
setup_arch
函数,传给他的参数是那个未被初始化的内部变量
command_line
。这个
setup_arch()
函数是
start_kernel
阶段最重要的一个函数,每个体系都有自己的
setup_arch()
函数,是体系结构相关的,具体编译哪个体系的
setup_arch()
函数,由顶层
Makefile
中的
ARCH
变量决定:

它首先通过检测出来的处理器类型进行处理器内核的初始化,然后通过 bootmem_init()函数根据系统定义的 meminfo 结构进行内存结构的初始化,最后调用paging_init()开启 MMU,创建内核页表,映射所有的物理内存和 IO空间。

  • start_kernel () --> setup_arch () --> paging_init () --> bootmem_init () --> alloc_bootmem_low_pages ()

具体代码分析如下:

void __init setup_arch(char **cmdline_p){	struct tag *tags = (struct tag *)&init_tags; //定义了一个默认的内核参数列表	struct machine_desc *mdesc;		//设备描述的结构体	char *from = default_command_line;	init_tags.mem.start = PHYS_OFFSET;	unwind_init();	setup_processor();   				//汇编的CPU初始化部分	mdesc = setup_machine(machine_arch_type);	machine_desc = mdesc;	machine_name = mdesc->name;	//下面一部分通过匹配struct machine_desc结构体数据,初始化一些全局变量	//通过struct machine_desc 中的soft_reboot设置重启类型	if (mdesc->soft_reboot) 		reboot_setup("s");	//检查bootloader是否传入参数,如果传入,则给tags赋值,若果没有传入则传递默认的启动参数地址	if (__atags_pointer)			tags = phys_to_virt(__atags_pointer);	else if (mdesc->boot_params) {#ifdef CONFIG_MMU		/*		 * We still are executing with a minimal MMU mapping created		 * with the presumption that the machine default for this		 * is located in the first MB of RAM.  Anything else will		 * fault and silently hang the kernel at this point.		 */		if (mdesc->boot_params < PHYS_OFFSET ||		    mdesc->boot_params >= PHYS_OFFSET + SZ_1M) {			printk(KERN_WARNING			       "Default boot params at physical 0x%08lx out of reach\n",			       mdesc->boot_params);		} else#endif		{			tags = phys_to_virt(mdesc->boot_params);		}	}#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)	/*	 * If we have the old style parameters, convert them to	 * a tag list.	 */	if (tags->hdr.tag != ATAG_CORE)	//内核参数列表第一项为ATAG_CORE		convert_to_tag_list(tags);	//如果不是,这需要转换成新的内核参数类型,新的内核参数类型用下面的structtag结构表示#endif	if (tags->hdr.tag != ATAG_CORE)		tags = (struct tag *)&init_tags;	//如果没有内核参数,则选用默认的内核参数,在init_tags文件中有定义	if (mdesc->fixup)		mdesc->fixup(mdesc, tags, &from, &meminfo);	//用选用的内核参数列表填充meminfo ,fixup函数出现在注册machine_desc中,即MACHINE_START、MACHINE_END定义中,这个函数,有些板子有,但在2410中没有定义这个函数。	if (tags->hdr.tag == ATAG_CORE) {		if (meminfo.nr_banks != 0)	//如果内存被初始化过			squash_mem_tags(tags);			//如果是tag list,那么如果系统已经创建了默认的meminfo.nr_banks,清除tags中关于MEM的参数,以免再次被初始化			save_atags(tags);		parse_tags(tags);	//做一些针对各个tags的处理	}	//解析内核参数列表,然后调用内核参数列表的处理函数对这些参数进行处理。比如,如果列表为命令行,则最终会用parse_tag_cmdlin函数进行解析,这个函数用_tagtable编译连接到了内核里	init_mm.start_code = (unsigned long) _text;	init_mm.end_code   = (unsigned long) _etext;	init_mm.end_data   = (unsigned long) _edata;	init_mm.brk	   = (unsigned long) _end;	//记录了内核代码的起始,结束虚拟地址	/* parse_early_param needs a boot_command_line */	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);	/* populate cmd_line too for later use, preserving boot_command_line */	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);	*cmdline_p = cmd_line;	//将boot_command_line复制到cmd_line中	parse_early_param();				//解释命令行参数	arm_memblock_init(&meminfo, mdesc);	//将设备实体登记注册到总线空间链表中去	paging_init(mdesc);	request_standard_resources(mdesc);	#ifdef CONFIG_SMP	if (is_smp())		smp_init_cpus();	//要配置CONFIG_KEXEC,否则为空函数,2410中没有配置#endif	reserve_crashkernel(); 	cpu_init();	//初始化一个CPU,并设置一个per-CPU栈	tcm_init();	//初始化ARM内部的TCM(紧耦合内存)#ifdef CONFIG_MULTI_IRQ_HANDLER	handle_arch_irq = mdesc->handle_irq;#endif#ifdef CONFIG_VT#if defined(CONFIG_VGA_CONSOLE)	conswitchp = &vga_con;#elif defined(CONFIG_DUMMY_CONSOLE)	conswitchp = &dummy_con;#endif#endif	early_trap_init();		//对中断向量表进行早期的初始化	//如果设备描述结构体定义了init_early函数(应该是早期初始化之意),则在这里调用 	if (mdesc->init_early)					mdesc->init_early();}
参考网址:

转载地址:http://doqai.baihongyu.com/

你可能感兴趣的文章
Centos7系统Mysql5.6下载与安装
查看>>
Linux环境下Redis的安装与配置
查看>>
面试感悟:3年工作经验java程序员应有的技能
查看>>
Java代码实现多线程下载和断点续传
查看>>
mysql分表分区
查看>>
mysql分区详解
查看>>
java线程池管理多线程的应用
查看>>
redis集群图解
查看>>
linux(centos 6.8 64位)下安装JDK8
查看>>
linux(centos6.8 64位)下安装tomcat8
查看>>
java中高级面试题总结
查看>>
centos安装tomcat
查看>>
spring cloud学习,转载自纯洁的微笑
查看>>
Dubbo背景和简介以及入门demo
查看>>
IOC的实现原理—反射与工厂模式
查看>>
spring的aop原理
查看>>
分布式锁的几种实现方式~
查看>>
幂等、分布式锁
查看>>
TCP三次握手和四次挥手以及缺陷(详细)
查看>>
公钥,私钥和数字签名理解
查看>>