linux内核启动分析(二)

  我们前面看了start_kernel前的汇编进行的初始化工作,现在开始看start_kernel函数了:

  set_task_stack_end_magic函数就做了一件事,获取内核栈的末尾地址,然后给这个地址赋值STACK_END_MAGIC。然后linux内核是使用task_stack_end_corrupted这个宏判断内核是否栈溢出的。linux内核会在cpu睡眠的时候检查当前栈是否发生溢出。如果开启了schedule debug则会在schedule的时候检查上一个进程的栈是否发生溢出。如果我们真的担心这个问题,最好的做法是在内核的启动参数,一般是grub中添加stacktrace,那么开启内核的函数调用堆栈追踪功能,同事会检查堆栈是否溢出。

  smp_setup_processor_id函数主要做了两个事情:

  读取MPIDR_EL1,把该寄存器的4个等级的aff提取出来,写入该cpu号为下标的__cpu_logical_map数组中。这4组aff值在每个core中是唯一的,加起来可以表示core在整个soc的位置。aff0表示一个core中的第几个线程,因为有可能使用超线程技术,一个core中有两个线程;aff1表示core在cluster中的第几个core;aff2表示这是在第几个cluster中。这个值是soc厂商写死的,用于表示core的信息。初始化tpidr_el1和tpidr_el2寄存器为0。以前我一直以为它表示当前cpu处于0号进程,当时认为这个寄存器是用来存放当前cpu正在处理的进程的进程号的,加速cpu找到current这个task_struct结构体。 现在看了代码才知道,这个寄存器是存放每cpu的offs值的,用于快速找到每cpu变量所在的内存。 我们没有开启CONFIG_DEBUG_OBJECTS,是个空函数。

  我们cgroup开启了cpuset、cpu、cpuacct、io、memory、devices、perf_event、hugetlb、pids这几个子系统。

  cgroup_init_early函数主要做了几件:

  调用函数init_cgroup_root注册和初始化根控制组;初始化init_task.cgroups,这个RCU类型的指针;遍历所有启用的cgroup子系统,初始化他们,主要是使用cgroup_init_subsys函数初始化子系统。 init_cgroup_root函数主要做了一下工作:

  初始化cgroup_root的链表,设置cgroup的数量为1;调用函数init_cgroup_housekeeping初始化根cgroup的后勤工作;初始化root的flags、release_agent_path、name、cgrp。 init_cgroup_housekeeping主要是做了以下工作:

  初始化存放兄弟cgroup的链表self.sibling初始化存放子cgroup的链表self.children初始化指向cgrp_cset_links的列表cgrp->cset_links初始化存放进程pid的链表cgrp->pidlists初始化保护pidlists的互斥锁cgrp->pidlist_mutex初始化cgrp的其他成员参数 因为启动阶段,ss->early_init为0,cgroup_init_subsys没有执行,先不看。

  local_irq_disable这个宏主要做了3个工作:

  调用函数raw_irqs_disabled读取irq的状态;调用函数raw_local_irq_disable关中断;判断步骤一获取到的状态是否关闭,如果还没有关闭,就执行trace_hardirqs_off函数进行trace。 raw_irqs_disabled主要做了:

  调用函数arch_local_save_flags获取daif,其中表示了cpu的irq情况,调用函数arch_irqs_disabled_flags对步骤一的返回值进行处理,只保留irq的bit。 raw_local_irq_disable主要是执行了汇编 “msr daifset, #2” ,从而达到关闭irq。

  这个函数追进去看不太懂,只知道这是ftrace的东西。

  boot_cpu_init主要是设置当前cpu的状态,这些状态保存在全局变量__cpu_online_mask、__cpu_active_mask、__cpu_present_mask、__cpu_possible_mask中。

  page_address_init函数只有一个作用就是初始化page_address_htable数组,这个数组是一个哈希桶,这个列表存放的是struct page_address_map结构体,看到这个结构体我么就知道这是一个page到虚拟地址的映射关系,也就是说我们经常挺熟的反向映射。

  不太能看懂,后续补,先学习一下。