Linux内核启动流程 一、读取CPU内部ID 芯片公司在做芯片的时候,会给芯片一个唯一的编号,这个编号相当于身份证号,把CPU内部的ID号和自己保存的ID比对是否匹配,会通过==__lookup_processor_type==查看这个内核是否支持该CPU,如果不支持就会报错。(汇编代码) 二、获取bootloader传递的板子的ID 这个ID是开发板的ID,这个ID要向Linux内核申请,获取ID,fs4412这个开发板没有ID。能够运行是因为这款开发板是照着三星origen开发板画的,因此用的是三星的origen开发板。代码通过==__lookup_mach_type==来检查内核是否支持该开发板,如果不支持则报错。 三、使能MMU 操作系统运行之后就不是物理地址,而是虚拟地址,所以CPU和开发板的ID验证完之后,就要使能MMU。MMU的功能是打开虚拟地址和物理地址的映射。建立一级页表:刚开始映射的方法很简单,假如物理地址为40000000,一级页表就是一 一对应,有多少物理地址就对应多少虚拟地址。然后就是使能MMU,后面还是重新映射。 四、为C语言提供环境 1、清除.bss段 C语言程序在编译完成后,初始化为非零的全局变量存放在.data段,而未初始化或初始化为0的全局变量存放在.bss段中,包括静态的变量,如果没有清除.bss段默认为随机值 2、设置sp 对应函数的局部变量保存在栈区 3、保存一些变量 保存开发板的IP、保存CPU的IP,__atags_pointer这个全局变量存储的就是r2的寄存器值,是设备树在内存中的起始地址,将设备树起始地址传递给setup_machine_fdt,对设备树进行解析。 五、跳转到C语言函数start_kernel 开始启动内核,C语言的程序运行,开始打印信息 1、打印Linux版本信息 2、处理bootloader给Linux内核传递的tag参数列表 3、初始化控制台,这里的控制台就是输入输出,这里输入和输出就是串口 4、获取内存信息,重新建立页表虚拟地址与物理地址之间的映射关系(上面虽然也是虚拟地址但是虚拟地址和物理地址相同,下面全是虚拟地址,每个进程可以占用4GB的进程空间,独立的地址空间,就是虚拟地址空间) 5、初始化异常处理 6、加载所有驱动模块 7、挂载文件系统 8、执行根文件系统上的“init”程序,启动init进程