1.入门知识
1.1硬件构成
嵌入式系统硬件主控板主要由这些硬件构成:
①ARM架构为硬核的处理器,如TI/FreeScale等芯片厂商制造的处理器。
②存储芯片:包括内存RAM和闪存FLASH。内存RAM中是在上电时存储程序运行的指令和数据的,掉电后数据消失,常用的是DDR2或DDR3芯片,低级一点的可以用SRAM芯片;闪存FLASH存储的是烧录或拷贝的各种文件(包括指令和数据),上电后FLASH的文件会拷贝至RAM运行,掉电后FLASH中的数据不会消失,常用的是NOR FLASH和NAND FLASH。
③外设:主要是电源模块、GPIO扩展口、ADC、RTC、TFT屏接口、JTAG烧录口、通信接口(UART/USB/I2C/CAN/网口等)。这些外设需要专门的驱动程序支持才能使用。
1.2 Bootloader
bootloader是一个引导程序,它最主要的功能是加载内核,所谓加载内核就是让内核代码常驻内存,并且得到执行。
每一种CPU都有自己的启动方式,具体如下(网上看到的):
①CPU上电后从某个确定的内存地址开始取指令运行,这样的指令往往是已经固化的,因为RAM刚上电时,里面的内容是没有意义的,很多单片机是这样方式。这种BOOT方式可以认为是固化模式,其实就是没有所谓的BOOT过程。
②CPU上电后从ROM读代码到RAM,然后跳到RAM里开始执行。这种方式的CPU一般会拷贝固定长度的二进制代码到RAM,因为它不知道有效代码有多长,只有一个固定的长度拷贝完成后,CPU才知道拷贝工作完成,以便从RAM执行。这就是拷贝固定长度二进制代码的BOOT过程。
③对方式②进行了改进,方式②只能拷贝固定长度的代码到RAM运行,为了拷贝更多的代码到RAM运行,首先进入RAM的代码不是一个功能固件,而是另一个功能代码的加载器(loader),这就是Bootloader。
1.2.1 ARM的Bootloader
ARM会拷贝4K长度的代码运行。显然arm不是为4K的固件设计的。拷贝代码到RAM并不需要很多指令,因为ARM对RAM的管理需要一个MMU控制器(可以让CPU访问更多的RAM或许)而这个控制器需要配置相关寄存器,所以代码可能要多一点,另外可能还有许多别的功能,所以代码可能会更多。当然都不超过4K时都没问题,但往往还是要过4K的。所以真正arm-linux的bootloader一般有两步骤:
①拷贝4K代码到RAM,开始执行。 ② 拷贝另一段代码到RAM并初始化一些必须的硬件设置,开始执行 。
1.2.2 U-Boot
u-boot是一种很流行的bootloader,除了加载内核,它还提供了许多其他功能。基本上u-boot是一个精简的linux,源代码布局和Linux相似,它提供人机交换接口,一般现在linux开发都采用串口方式使用u-boot。
关于u-boot的说明有很多,我简单说明一下:
①u-boot可以被打断,通过串口向u-boot输入命令后,u-boot中断,可以执行各种命令,这些命令有专门的手册可以查询。串口其实就是u-boot的一个远程终端。
②u-boot可以设置网络,通过TFTP服务,u-boot可以下载代码到RAM然后执行,也可以烧写到flash。
③u-boot之所以有这么多功能是因为里面集成了许多驱动,如果要让u-boot有更多的功能可以在u-boot源代码里添加,如果要用硬件就需要添加驱动。
④ 嵌入式系统硬件千差万别,使用U-Boot时需要修改(也就是移植),修改后需要重新编译。
1.3 Linux内核
内核就是Linux操作系统的核心,也就是一组程序,负责驱动硬件、分配管理硬件资源和管理活动(进程、中断)。内核直接作用于硬件,控制硬件的数字逻辑运算。如果让用户直接访问操作硬件的话,对于复杂电路来说,这是非常困难甚至是不可能的;而内核通过硬件抽象(HAL/BSP)的方法屏蔽了用户直接操作硬件的复杂性和多样性。内核向应用程序(用户程序)提供了统一和简洁的接口,应用程序只需调用这个接口就可以完成相应操作。用下图形象表示:
1.3.1内核组成
Linux 内核由进程管理、内存管理、文件系统、网络协议、进程间通信、 设备驱动等模块组成。如下图所示:
各个组成部分的详细讲解可以去搜索相关资料。
1.3.2 内核的交叉编译
所谓的交叉编译,就是在宿主机(PC机,Windows/Linux系统)平台上使用某种特定的交叉编译器,为某种与宿主机不同平台的目标系统编译程序,得到的程序在目标系统(ARM开发板,Linux系统)上运行而非在宿主机本地运行。这里的平台包含两层含义:一是核心处理器的架构,二是所运行的系统。这样,交叉编译有 3 种情形:
①目标系统与宿主机处理器相同,运行不同的系统; ②目标系统与宿主机处理器不同,运行相同的系统; ③目标系统与宿主机处理器不同,运行不同的系统。交叉编译器命名方式一般遵循“处理器-系统-gcc”这样的规则,一般通过名称便可以知道交叉编译器的功能。交叉编译器在Linux操作系统中的下载及安装过程:
①网站上下载编译器,比如arm-linux-gcc 3.4.1;
②解压安装:sudo tar vxjf arm-linux-gcc 3.4.1.bz2;
③命令行编译需要设置环境变量:sudo gedit /etc/bash.bashrc; 在文件最后添加:export PATH=$PATH:/usr/local/arm/3.4.1/bin 重新登录。
④arm-linux-gcc –v 查看版本便知道交叉编译器是否安装成功 。
1.3.3内核裁剪(内核移植)
内核移植涉及到硬件驱动修改裁剪和内核配置Kconfig。这是一个很复杂的过程,需要专门的文章详细介绍。
1.4 烧写
烧写内核有多种方式:USB烧写、TF卡烧写、镜像文件烧写等。
这些烧写都要借助一定的软硬件工具来进行。以镜像文件烧写为例:
①内核镜像是被bootloader加载的,比如u-boot可以把内核镜像加载到RAM并执行。制作u-boot可加载的镜像需要使用mkimage工具。 安装:sudo cp ~/tools/mkimage /usr/bin;编译:make uImage;
注意:如果mkimage权限不对make uImage是会出错的,可以设置一下权限 sudo chmod 777 /usr/bin/mkimage 如果一切成功那么在linux-xxxx/arch/arm/boot下就有uImage文件了。
②U-Boot烧写过程: a) 中断u-boot ;b) 需要一个tftp服务器,比如Windows XP下可以安装tftpwin ;c) 调用u-boot命令启动下载烧写。(网上看到的,不一定准确)