




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
char * command_line;/命令行,用来存放bootloader传递过来的参数extern const struct kernel_param _start_param, _stop_param;/这两个变量为地址指针,指向内核启动参数处理相关结构体在内存的位置,ARM平台定义的位置在kernel/include/asm-generic/Vmlinux.lds.h/* Need to run as early as possible, to initialize the lockdep hash: */lockdep_init();/建立一个哈希表(hash tables),就是一个前后指向的指针结构体数组。【函数的主要作用是初始化锁的状态跟踪模块。由于内核大量使用锁来进行多进程多处理器的同步操作,死锁就会在代码不合理的时候出现,但是要定位哪个锁比较困难,用哈希表可以跟踪锁的使用状态。死锁情况:一个进程递归加锁同一把锁;同一把锁在两次中断中加锁;几把锁形成闭环死锁】smp_setup_processor_id();/针对SMP处理器,用于获取当前CPU的硬件ID,如果不是多核,函数为空【判断是否定义了CONFIG_SMP,如果定义了调用read_cpuid_mpidr读取寄存器CPUID_MPIDR的值,就是当前正在执行初始化的CPU ID,为了在初始化时做个区分,初始化完成后,所有处理器都是平等的,没有主从】debug_objects_early_init();/初始化哈希桶(hash buckets)并将static object和pool object放入poll列表,这样堆栈就可以完全操作了【这个函数的主要作用就是对调试对象进行早期的初始化,就是HASH锁和静态对象池进行初始化,执行完后,object tracker已经开始完全运作了】/* Set up the the initial canary ASAP: */boot_init_stack_canary();/初始化堆栈保护的加纳利值,防止栈溢出攻击的堆栈保护关键字cgroup_init_early();/在系统启动时初始化cgroups,同时初始化需要early_init的子系统【这个函数作用是控制组(control groups)早期的初始化,控制组就是定义一组进程具有相同资源的占有程度,比如,可以指定一组进程使用CPU为30%,磁盘IO为40%,网络带宽为50%。目的就是为了把所有进程分配不同的资源】local_irq_disable();/关闭当前CPU的所有中断响应,操作CPSR寄存器。对应后面的early_boot_irqs_disabled = true;/系统中断关闭标志,当early_init完毕后,会恢复中断设置标志为false。/* Interrupts are still disabled. Do necessary setups, then enable them */tick_init();/初始化内核时钟系统,tick control,调用clockevents_register_notifier,就是监听时钟变化事件【这个函数主要作用是初始化时钟事件管理器的回调函数,比如当时钟设备添加时处理。在内核里定义了时钟事件管理器,主要用来管理所有需要周期性地执行任务的设备】boot_cpu_init();/设置当前引导系统的CPU在物理上存在,在逻辑上可以使用,并且初始化准备好,即激活当前CPU【在多CPU的系统里,内核需要管理多个CPU,那么就需要知道系统有多少个CPU,在内核里使用cpu_present_map位图表达有多少个CPU,每一位表示一个CPU的存在。如果是单个CPU,就是第0位设置为1。虽然系统里有多个CPU存在,但是每个CPU不一定可以使用,或者没有初始化,在内核使用cpu_online_map位图来表示那些CPU可以运行内核代码和接受中断处理。随着移动系统的节能需求,需要对CPU进行节能处理,比如有多个CPU运行时可以提高性能,但花费太多电能,导致电池不耐用,需要减少运行的CPU个数,或者只需要一个CPU运行。这样内核又引入了一个cpu_possible_map位图,表示最多可以使用多少个CPU。在本函数里就是依次设置这三个位图的标志,让引导的CPU物理上存在,已经初始化好,最少需要运行的CPU。】page_address_init();/初始化高端内存的映射表【在这里引入了高端内存的概念,那么什么叫做高端内存呢?为什么要使用高端内存呢?其实高端内存是相对于低端内存而存在的,那么先要理解一下低端内存了。在32位的系统里,最多能访问的总内存是4G,其中3G空间给应用程序,而内核只占用1G的空间。因此,内核能映射的内存空间,只有1G大小,但实际上比这个还要小一些,大概是896M,另外128M空间是用来映射高端内存使用的。因此0到896M的内存空间,就叫做低端内存,而高于896M的内存,就叫高端内存了。如果系统是64位系统,当然就没未必要有高端内存存在了,因为64位有足够多的地址空间给内核使用,访问的内存可以达到10G都没有问题。在32位系统里,内核为了访问超过1G的物理内存空间,需要使用高端内存映射表。比如当内核需要读取1G的缓存数据时,就需要分配高端内存来使用,这样才可以管理起来。使用高端内存之后,32位的系统也可以访问达到64G内存。在移动操作系统里,目前还没有这个必要,最多才1G多内存】printk(KERN_NOTICE %s, linux_banner);/输出各种信息【Linuxversion 2.6.37+ (tonytony-desktop) (gcc version 4.3.3 (Sourcery G+Lite 2009q1-203) ) #40 Tue Mar 20 17:49:58 CST 2012 Linux_banner是在kernel/init/version.c中定义的,这个字符串是编译脚本自动生成的】setup_arch(&command_line);/很重要的一个函数 arch/arm/kernel/setup.c【内核架构相关初始化函数,是非常重要的一个初始化步骤。其中包含了处理器相关参数的初始化、内核启动参数(tagged list)的获取和前期处理、内存子系统的早期初始化(bootmem分配器)】mm_init_owner(&init_mm, &init_task);/初始化代表内核本身内存使用的管理结构体init_mm,init_mm定义了整个kernel的内存空间。mm_init_cpumask(&init_mm);/每一个任务都有一个mm_struct结构来管理内存空间,init_mm是内核的mm_structsetup_command_line(command_line);/对cmdline进行备份和保存setup_nr_cpu_ids();/设置最多有多少个nr_cpu_ids结构setup_per_cpu_areas();/为系统中每个CPU的per_cpu变量申请空间,同时拷贝初始化段里数据(.data.percpu)smp_prepare_boot_cpu();/* arch-specific boot-cpu hooks */为SMP系统里引导CPU(boot-cpu)进行准备工作。在ARM系统单核里是空函数build_all_zonelists(NULL);/设置内存管理相关的node(节点,每个CPU一个内存节点)和其中的zone(内存域,包含于节点中,如)数据结构,以完成内存管理子系统的初始化,并设置bootmem分配器page_alloc_init();/设置内存页分配通知器printk(KERN_NOTICE Kernel command line: %sn, boot_command_line);/输出命令参数到显示终端parse_early_param();/解析cmdline中的启动参数parse_args(Booting kernel, static_command_line, _start_param,_stop_param - _start_param,0, 0, &unknown_bootoption);【这行代码主要对传入内核参数进行解释,如果不能识别的命令就调用最后参数的函数】jump_label_init();/* * These use large bootmem allocations and must precede * kmem_cache_init()*/bootmem是内核启动时使用的临时内存分配器,之后要由slab接手,而kmem_cache_init()初始化了slab分配器(内核高速缓存分配器),这就意味着bootmem的结束,同时内核的内存管理系统正式启动了。所以bootmem的分配必须先于kmem_cache_init()。setup_log_buf(0);/使用bootmeme分配一个记录启动信息的缓冲区pidhash_init();/进程ID的HASH表初始化,用bootmem分配并初始化PID散列表,由PID分配器管理空闲和已指派的PID,这样可以提供通PID进行高效访问进程结构的信息。LINUX里共有四种类型的PID,因此就有四种HASH表相对应。vfs_caches_init_early();/前期虚拟文件系统(vfs)的缓存初始化sort_main_extable();/对内核异常表(exception table)按照异常向量号大小进行排序,以便加速访问trap_init();/对内核陷阱异常进行初始化,在ARM系统里是空函数,没有任何的初始化mm_init();/标记哪些内存可以使用,并且告诉系统有多少内存可以使用,当然是除了内核使用的内存以外【初始化内核内存分配器,包括六个子函数1、page_cgroup_init_flatmem();获取page_cgroup所需内存2、mem_init;关闭并释放bootmem分配器,打印内存信息,内核启动时看到Virtual kernel memory layout:的信息就是这个函数的3、kmem_cache_init();初始化slab分配器4、percpu_init_late();PerCPU变量系统后期初始化5、pgtable_cache_init();也表缓存初始化,arm中是个空函数6、vmalloc_init();初始化虚拟内存分配器】/* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() * time - but meanwhile we still have a functioning scheduler. */sched_init();/对进程调度器的数据结构进行初始化,创建运行队列,设置当前任务的空线程,当前任务的调度策略为CFS调度器/* * Disable preemption - early bootup scheduling is extremely * fragile until we cpu_idle() for the first time. */preempt_disable();/关闭优先级调度。由于每个进程任务都有优先级,目前系统还没有完全初始化,还不能打开优先级调度。if (!irqs_disabled() printk(KERN_WARNING start_kernel(): bug: interrupts were enabled *very* early, fixing itn);local_irq_disable();【这段代码主要判断是否过早打开中断,如果是这样,就会提示,并把中断关闭】idr_init_cache();/ 为IDR机制分配缓存,主要是为 struct idr_layer结构体分配空间perf_event_init();/CPU性能监视机制初始化,此机制包括CPU同一时间执行指令数,cache miss数,分支预测失败次数等性能参数rcu_init();/初始化直接读拷贝更新的锁机制。 Read-Copy Update【RCU主要提供在读取数据机会比较多,但更新比较的少的场合,这样减少读取数据锁的性能低下的问题。】radix_tree_init();/内核radis 树算法初始化/* init some links before init_ISA_irqs() */early_irq_init();/前期外部中断描述符初始化,主要初始化数据结构init_IRQ();/对应架构特定的中断初始化函数,在ARM中就是machine_desc-init_irq(),就是运行设备描述结构体中的init_irq函数arch/arm/mach-msm/board-xxx.cprio_tree_init();/初始化内核基于radix树的优先级搜索树(PST),初始化结构体init_timers();/初始化引导CPU的时钟相关的数据结构,注册时钟的回调函数,当时钟到达时可以回调时钟处理函数,最后初始化时钟软件中断处理hrtimers_init();/初始化高精度的定时器,并设置回调函数。softirq_init();/初始化软件中断,软件中断与硬件中断区别就是中断发生时,软件中断是使用线程来监视中断信号,而硬件中断是使用CPU硬件来监视中断。timekeeping_init();/初始化系统时钟计时,并且初始化内核里与时钟计时相关的变量。time_init();/初始化系统时钟。开启一个硬件定时器,开始产生系统时钟就是system_timer的初始化,arch/arm/mach-msm/board-*.cprofile_init();/分配内核性能统计保存的内存,以便统计的性能变量可以保存到这里call_function_init();/初始化所有CPU的call_single_queue,同时注册CPU热插拔通知函数到CPU通知链中if (!irqs_disabled() printk(KERN_CRIT start_kernel(): bug: interrupts were enabled earlyn);early_boot_irqs_disabled = false;local_irq_enable();/对应前面的local_irq_disable()【打开本CPU的中断,也即允许本CPU处理中断事件,在这里打开引CPU的中断处理。如果有多核心,别的CPU还没有打开中断处理。】/* 中断已经使能,GFP分配是安全的*/gfp_allowed_mask = _GFP_BITS_MASK;开启所有GFP分配允许标志kmem_cache_init_late();/这是内核内存缓存(slab分配器)的后期初始化,当初始化完成之后,就可以使用通用内存缓存了/* HACK ALERT! This is early. Were enabling the console before weve done PCI setups etc, and console_init() must be aware of this. But we do want output early, in case something goes wrong. */console_init();【初始化控制台,从这个函数之后就可以输出内容到控制台了。在这个函数初化之前,都没有办法输出内容,就是输出,也是写到输出缓冲区里,缓存起来,等到这个函数调用之后,就立即输出内容】if (panic_later) panic(panic_later, panic_param);【判断分析输入的参数是否出错,如果有出错,就启动控制台输出之后,立即打印出错的参数,以便用户立即看到出错的地方。】lockdep_info();【打印锁的依赖信息,用来调试锁。通过这个函数可以查看目前锁的状态,以便可以发现那些锁产生死锁,那些锁使用有问题。】/* Need to run this when irqs are enabled, because it wants to self-test hard/soft-irqs on/off lock inversion bugs too: */locking_selftest();【测试锁的API是否使用正常,进行自我测试。比如测试自旋锁、读写锁、一般信号量和读写信号量。】#ifdef CONFIG_BLK_DEV_INITRDif (initrd_start & !initrd_below_start_ok & page_to_pfn(virt_to_page(void *)initrd_start) min_low_pfn) printk(KERN_CRIT initrd overwritten (0x%08lx 0x%08lx) - disabling it.n, page_to_pfn(virt_to_page(void *)initrd_start), min_low_pfn);/系统可用的最小pfn(页帧号)initrd_start = 0;#endif【检查initrd的位置是否符合要求,也就是判断传递进来initrd_start对应的物理地址是否正常,如果有误就打印错误信息,并清零initrd_start。】page_cgroup_init();/初始化容器组的页面内存分配,mem_cgroup是cgroup体系中提供的用于memory隔离的功能,debug_objects_mem_init();/这个函数是创建调试对象内存分配初始化,所以紧跟内存缓存初始化后面kmemleak_init();/内核内存泄漏检测机制初始化;setup_per_cpu_pageset();/创建每个CPU的高速缓存集合数组并初始化,此前只有启动页组。因为每个CPU都不定时需要使用一些页面内存和释放页面内存,为了提高效率,就预先创建一些内存页面作为每个CPU的页面集合。numa_policy_init();/初始化NUMA的内存访问策略。所谓NUMA,它是NonUniform Memory AccessAchitecture(非一致性内存访问)的缩写,主要用来提高多个CPU访问内存的速度。因为多个CPU访问同一个节点的内存速度远远比访问多个节点的速度来得快。if (late_time_init) late_time_init();/主要运行时钟相关后期的初始化功能。sched_clock_init();/对每个CPU进行系统进程调度时钟初始化calibrate_delay();/主要计算CPU需要校准的时间,这里说的时间是CPU执行时间。如果是引导CPU,这个函数计算出来的校准时间是不需要使用的,主要使用在非引导CPU上,因为非引导CPU执行的频率不一样,导致时间计算不准确。BogoMIPS值,也是衡量cpu性能的标志pidmap_init();/进程位图初始化,一般情况下使用一页来表示所有进程占用情况。anon_vma_init();/初始化反向映射的匿名内存,提供反向查找内存的结构指针位置,快速地回收内存。#ifdef CONFIG_X86if (efi_enabled)efi_enter_virtual_mode();#endif/初始化EFI的接口,并进入虚拟模式。EFI是ExtensibleFirmware Interface的缩写,就是INTEL公司新开发的BIOS接口。thread_info_cache_init();/线程信息(thread_info)的缓存初始化。cred_init();/任务信用系统初始化fork_init(totalram_pages);/根据当前物理内存计算出来可以创建进程(线程)的最大数量,并进行进程环境初始化,为task_struct分配空间。proc_caches_init();/进程缓存初始化,为进程初始化创建机制所需的其他数据结构申请空间buffer_init();/初始化文件系统的缓冲区,并计算最大可以使用的文件缓存。key_init();/初始化内核安全键管理列表和结构,内核密钥管理系统security_init();/初始化内核安全管理框架,以便提供访问文件登录等权限。dbg_late_init();/内核调试系统后期初始化vfs_caches_init(totalram_pages);/虚拟文件系统进行缓存初始化,提高虚拟文件系统的访
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年医院医疗废弃物处理及环保合规性全面评估执行合同
- 2025年小微企业员工健康体检及安全培训服务合同
- 2025年度矿产资源开采安全与环保管理体系建设合同
- 2025年高端酒店特色菜肴研发团队劳动合同
- 2025年青少年体育训练基地场地租赁及综合维护保养协议书
- 2025年环保领域专用设备采购及定期维护与保养协议
- 2025年金融行业客户信息保密及风险管理服务协议
- 2025年度非物质文化遗产艺术展品租借管理合同
- 彭水公务员面试题及答案
- 护理中医知识试题及答案
- 2025年六安市裕安区石婆店镇公开招考村级后备干部8名笔试备考试题及答案解析
- 公司领导财务知识培训课件
- 2025年全国中小学校党组织书记网络培训示范班在线考试题库及答案
- 子痫患者护理查房
- 2024仁爱科普版八年级英语上册 Unit 1 Healthy Mind and Body(知识梳理与考点训练)解析版
- 医疗护理员职业技能竞赛试题及答案
- 出货标签管理办法
- 中石化计划管理办法
- 我国军兵种介绍课件
- 小学劳动技术课课件
- 医院医德医风管理制度
评论
0/150
提交评论