由于受到众多硬件厂商及软件巨头的支持,以及自身学术性和应用性的完美结合,Linux操作系统在各个方面尤其是嵌入式领域得到了广泛应用。同时,作为开源软件,市面上虽然已经有不少介绍Linux内核启动流程的文章和书籍,但往往都过于简陋,流于表面,或者过于分散,无法得到一个整体的印象。本文基于ARM FVP模拟器平台ARMv7 Cortext-A9处理器,专注于Linux 4.10内核启动流程中的内核初始化环节,对整个过程中涉及到的ARM和Linux内核的基本知识进行介绍,使得用户可以对整个启动流程有一个整体的概念,从而有助于解决启动过程中遇到的各种问题。
关键词:嵌入式系统,虚拟化,Linux内核,32位ARM架构,ARMv7,Cortext-A9;内核初始化
1. 介绍
1.1 基本环境
本文使用的调试环境如下:
- 调试器采用ARM公司的DS-5 V5.27.1;
- 模拟器采用DS-5继承的ARM FVP(Fixed Virtual Platform,固定虚拟平台);
- 模拟器目标板采用ARM vexpress,处理器为Cortext-A9 4核处理器;
- Linux内核版本为4.10;
- 配置文件采用vexpress_defconfig;
- 内核格式为非压缩的Image;
- DTB文件采用DS-5自带的rtsm_ve-cortex_a9x4.dtb。
注意:
- 本文读者应具备基础的ARM架构指令集知识(工作模式、寄存器组织、寻址模式等)和C语言常识;
- 本文关注的是32位ARMv7架构启动流程,无关代码以
...
表示从而方便阅读 - DS-5和ARM FVP的使用方法可参见ARM FVP(固定虚拟平台)Linux内核调试简明手册;
- Linux内核代码可参考Linux源码主线;
- ARM体系结构可参考官网ARMv8-A Reference Manual
- ARM指令可参考ARM官网ARM and Thumb-2 Instruction Set Quick Reference Card (Chinese);
- ARM 32位架构ABI可参考ARM官网针对ARM体系结构的应用程序二进制接口(ABI)
1.2 初始化阶段划分
Linux内核初始化划分为如下几个阶段:
- 入口阶段,即内核入口到C语言入口start_kernel()之前的阶段,基本上使用汇编语言实现;
- 早期初始化阶段,即start_kernel()过程,用于为kernel_init线程(PID为1)和线程调度准备最基本的运行环境;
- 初始化阶段,即kernel_init线程的执行过程,用于进行真正的内核初始化,包括驱动、文件系统、网络协议栈等模块的真正初始化,并最终执行跟文件系统中的初始化脚本;
- 用户空间初始化,即初始化脚本定义的用户程序执行和模块加载等,不属于本文讨论范围。
网友评论