交叉开发环境

交叉开发、交叉开发环境?为何需要交叉开发环境?
所谓交叉开发是指先在一台通用PC上进行软件的编辑、编译与连接,然后下载到嵌入式设备中运行调试的开发过程。通用PC成为宿主机,嵌入式设备成为目标机。

交叉开发环境一般由运行于宿主机上的交叉开发软件、宿主机到目标机的调试通道组成。

需要交叉开发环境是因为目标机一般对体积、功耗等有严格限制,资源也面向应用,较为紧张,要求仅仅能流畅运行代码即可(不具备自举开发能力),而将用户开发软件(包括各种库、工具)放置在主机上,而且现在的集成开发环境提供了各种修改好的功能库,用起来也方便。

如何构建交叉编译环境
构建交叉编译环境有两种方式,从现成的二进制代码构建和从源代码直接安装。
从现成的二进制代码构建:

  1. 下载源文件,补丁和建立编译的目录
  2. 建立内核头文件
  3. 建立二进制工具(binutils)
  4. 建立初始编译器(bootstrap gcc)
  5. 建立c库(glibc)
  6. 建立全套编译器(full gcc)
Linux启动过程

Linux内核在目标板上启动的过程?需要考虑哪些因素

嵌入式 Linux系统开机首先运行BootLoader,然后由BootLoader引导启动内核,由内核检查和初始化硬件设备,载入设备的驱动程序模块,安装root文件系统,然后内核将启动一个名为 init的进程。
在init运行完成并启动其它必要的后续进程后,系统开始运行,引导过程结束。init进程启动时需要读取inittab配置文件,该文件确定init在系统启动和关机时的工作特性。init进程是其他进程的父进程。

1、通过合适的bootloader找到内核源代码,加载到内存
2、内核源代码开始进行初始化
3、内核源代码初始化完毕,开始调用和用户有关的进程。用户进程初始化选用和目标板相配的启动装载程序

嵌入式软件开发工作
交叉编译环境构建
初始化引导代码bootloader编写
嵌入式操作系统代码内核编译加载
驱动程序代码驱动模块编写编译
文件系统文件系统制作挂载
GUI(可选)
应用程序代码应用程序编写
简述嵌入式开发的流程
  1. 建立开发环境
    在宿主机上下载如GCC交叉编译器进行安装,构建交叉编译环境

  2. 配置开发主机
    配置网络等,主要是配置NFS网络文件系统,简化嵌入式网络调试环境设置过程

  3. 烧写引导装载程序bootloader
    从网络上下载一些公开源代码的BOOTLOADER,如U-BOOT、等,根据自己具体的芯片进行移植修改。

  4. 下载内核
    下载后再添加自己的特定硬件的驱动程序,进行调试修改编译。如果有专门针对你所使用的 CPU 移植好的 LINUX 操作系统那是再好不过

  5. 建立根文件系统
    下载使用BUSYBOX软件进行功能裁减,产生一个最基本的根文件系统,再根据自己的应用需要添加其他程序。默认的启动脚本一般都不会符合应用的需要,所以就要修改根文件系统中的启动脚本,它的存放位置位于/etc目录下,包括:/etc/init.d/rc.S、/etc/profile、/etc/.profile等,自动挂装文件系统的配置文件/etc/fstab,具体情况会随系统不同而不同。根文件系统在嵌入式系统中一般设为只读,需要使用mkcramfs、genromfs等工具产生烧写映像文件。

  6. 建立应用程序的Flash磁盘分区

  7. 开发应用程序
    应用程序可以放入根文件系统中,也可以放入如YAFFS、JFFS2文件系统中,有的应用不使用根文件系统,直接将应用程序和内核设计在一起。

什么是 bootloader

Boot Loader 是在操作系统内核运行之前运行的第一段小程序,加电后能够自启动,工作流程如下:

  1. 初始化硬件设备
  2. 建立内存空间的映射图
  • 将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
加载操作系统内核映像到RAM中,并将系统的控制权传递给它


Boot Loader 包含两种不同的操作模式:

启动加载模式:
Boot Loader从目标机上的某个固态存储设备上自主将操作系统加载到 RAM 中运行,在嵌入式产品发布时,Boot Loader必须工作在该模式下

下载模式:
从开发机下载内核映像和根文件系统映像,一般用在更新系统时。


Boot Loader 的实现依赖于 CPU 体系结构,大多数 Boot Loader 都分为 stage1 和 stage2 两大部分

Stage1:
特点:
依赖于 CPU 体系结构,如设备初始化代码
通常用汇编语言实现,短小精悍
步骤:

  1. 硬件设备初始化
  2. 为加载 Boot Loader的stage2准备RAM空间
  3. 拷贝 Boot Loader的stage2到RAM 空间中
  4. 设置好堆栈
  5. 跳转到 stage2 的 C 入口点

Stage2:
特点:
通常用C语言
可以实现复杂功能
代码具有较好的可读性和可移植性
步骤:

  1. 初始化本阶段要使用到的硬件设备
  2. 检测系统内存映射(memory map)
  3. 将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中
  4. 为内核设置启动参数
  5. 调用内核
根文件系统

什么是根文件系统?Linux 内核启动与根文件系统的关系?

首先要明白的是“什么是文件系统”,文件系统是对一个存储设备上的数据和元数据进行组织的机制。
根文件系统首先是内核启动时所mount的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。根文件系统就是出了内核以外,其它所有文件的最终挂载点。

Linux 内核在运行期必须要用到的存储代码体系,与内核同时存在,只在内核运行时才存于内存中。根文件系统必须能够提供 Linux 内核启动过程中要加载的模块。

常见的文件系统有FAT、NTFS、ext2等

根文件系统挂载流程