Linux内核源码分析_setup_arch函数的主要作用
来源:互联网 发布:彩印编织袋价格算法 编辑:程序博客网 时间:2024/05/21 05:44
`一、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_COREconvert_to_tag_list(tags);//如果不是,这需要转换成新的内核参数类型,新的内核参数类型用下面的structtag结构表示#endifif (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_SMPif (is_smp())smp_init_cpus();//要配置CONFIG_KEXEC,否则为空函数,2410中没有配置#endifreserve_crashkernel(); cpu_init();//初始化一个CPU,并设置一个per-CPU栈tcm_init();//初始化ARM内部的TCM(紧耦合内存)#ifdef CONFIG_MULTI_IRQ_HANDLERhandle_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#endifearly_trap_init();//对中断向量表进行早期的初始化//如果设备描述结构体定义了init_early函数(应该是早期初始化之意),则在这里调用 if (mdesc->init_early)mdesc->init_early();}
参考网址:
http://blog.csdn.net/boarmy/article/details/8652343
http://www.wesage.net/bbs/forum.php?mod=viewthread&tid=212&page=1
0 0
- Linux内核源码分析_setup_arch函数的主要作用
- linux内核启动2_setup_arch函数
- Linux内核PROC文件系统的初始化和主要函数分析
- inline函数的主要作用
- Linux内核源码分析
- linux主要目录的作用
- Linux 内核的主要工作
- linux内核的主要模块
- Linux内核源码分析--系统时间初始化(kernel_mktime()函数)
- Linux内核源码分析--打开块设备文件--open_bdev_excl函数
- linux内核分析-简单的操作系统内核源码解读
- 《第一篇 从linux 0.11系统初始化main.c的fork()函数调用分析内核源码》
- RTMPDump源码分析-主要函数调用(0)
- linux内核源码源码分析之zImage的出生实录
- Linux内核中start_kernel函数的分析
- 深入分析Linux内核源码
- 深入分析Linux内核源码
- 深入分析Linux内核源码
- 11种UITextField键盘种类
- 42、MySQL-更新视图
- MySQL导入.sql文件及常用命令
- 登录界面 Android简单http get请求(含服务器端)二
- time_wait
- Linux内核源码分析_setup_arch函数的主要作用
- android 调用webservice时出错org.xmlpull.v1.XmlPullParserException的解决办法
- 自定义drawable文件夹下的button和图片选择
- unity3d如何算出一个点到一个平面的垂直距离
- ASP.NET连接数据库操作
- java基础之:集合
- 43、MySQL-删除视图
- ios自动布局
- (转)iOS 8 AutoLayout与Size Class自悟