嵌入式linux基础教程第二版 第二章

时间:2022-06-27 18:51:42

      本章将带您观摩一个典型的嵌入式开发系统的开发环境,重点介绍嵌入式开发的一些组件和概念

      1.嵌入和非嵌入

             嵌入式系统的一些常见的特性

             a.包含一个处理引擎,比如通用微处理器

             b.一般针对某种具体的应用或目的而设计的

             c.包含一个简单的用户界面

             d.通常资源有限,例如只有很少的内存,并且没有硬盘驱动器

             e.可能会受到供电的限制,比如需要使用电池

              f.一般不会用作通用的计算平台

             g.一般内置了应用程序,用户不能自己选择

             h.出场时软硬件已经预先集成好了

              i.常常针对无人值守的应用环境

     另外,一个桌面PC有可能是一个嵌入式系统。在远程数据中心运行的桌面PC就是一个嵌入式系统。

      嵌入式系统的资源很有限,比如嵌入式系统通常只有很少的内存,小容量的硬盘驱动器,有时还没有外部网络连接。而且一个系统仅有的用户界面就是一个串行端口加上几个发光二极管。正是因为这些资源的有限给嵌入式软件开发者带来了很大的挑战


      bios和引导加载程序的对比

      在电脑加电时,BOIS首先获得处理器的控制器,它的主要任务是初始化硬件,特别是内存子系统,并且从PC的硬盘驱动中加载操作系统。在典型的嵌入式系统中,引导加载程序完成与bois相同的功能。对于定制嵌入式系统,必须开发针对具体硬件板卡的引导加载程序。

      如果你的嵌入式系统基于定制的硬件平台,这些引导加载程序的功能必须由你,也就是系统的设计者来提供。如果你的嵌入式系统基于商用现货那么其引导加载程序一般就包含在硬件板卡中了。在第七中详细介绍。

     2.剖析嵌入式系统

       介绍了一个典型嵌入式系统框图。这个系统架构以一个(1)32位的RISC处理器位中心,(2)系统中的闪存用于存储非易失性程序和数据,(3)主存储器SDRAM其容量可从几兆至几百兆字节,视应用而定。(4)一个通常由电池供电的实时时钟模块记录着当前时间。包含(5)以太网和(6)usb接口,利用(7)串行端口可基于RS-232标准访问控制台。(7)802.11芯片组或者模块实现了无线调至解调器的功能。

       嵌入式系统的处理器完成很多功能,不仅仅是处理传统的核心指令流。很多处理器都包含集成在处理器外的外设,有时这些系统被成为片上系统(SOC)。比如RISC上的URAT、USB、和以太网控制器。

    3.典型的嵌入式Linux

        运行一个linux发行版本,嵌入式Linux开发板通过一根RS-232串行端口线与主机相连。目标板的以太网接口插接到本地以太网集线器或者交换机上,开发主机也通过以太网连接到上面。开发主机包含开发工具和程序以及目标文件,通常这些都可从一个嵌入式Linux发行版中获得。

        主机上运行的串行端口终端程序用于和目标板通信。minocom是最常用的串行端口通信应用程序之一,几乎所有的linux发行版中都有这个应用程序(在自己的发行版上安装minicom)。本书中使用的是screen作为串行端口通信程序。这个程序在trace方面很灵活。

    4.启动目标板

          第一次加电,目标板上的引导加载程序立即获得处理器的控制权,该程序执行一些非常底层的硬件初始化,包括处理器和内存的设置,初始化UART用于控制串行端口,以及初始化以太网控制器。下面代码清单显示了从串行端口接受到的字符。

          引导加载程序从串行端口输出的初始信息

                  U-Boot    2009.01(May 20 2009 - 09:45:35)

                  

                  CPU:      8548E,  Version:  2.1, (0x80390021)

                  Core:      E500, Version:   2.2,  (0x80210022)

                  Clock  Configuration:

                                CPU: 990 MHz,   CCB:  396   MHz,

                                DDR: 198 MHz (396  MT/s  data  rate),  LBC: 49.500   MHz

                   L1:         D-cache    32   kb   enabled

                   L2:         I-cache    32    kb   enabled

                   Board:   CDS   Version  0x13,   PCI  Slot   1

                   CPU  Board  Version    0.0(0x0000)

                   I2C:   ready

                   DRAM:   Initializing

                           SDRAM:  64MB

                           DDR:  256MB

                   FLASH:   16MB

                   L2;       512  KB  enabled

                   Invalid   ID(ff  ff  ff  ff)

                           PCI:    64bit,  unknown MHz,  async,  host,  external-arbiter

                                               Scanning  PCI  bus  00

                   PCI  on  bus  00 - 02


                                   PCIE  connected  to  slot  as  Root  Complex(base address  e000a000)

                   PCIE on  bus  3  -  3

                   In:  serial

                   Out:  serial

                   Err:  serial

                   Net:  eTSEC0, eTSEC1, eTSEC2, eTSEC3

                   =>

                   在目标板加电时,U-Bootz执行一些底层的硬件初始化,包括串行端口,然后打印标题。上面第一行,接着显示CPU和CORE的型号和版本,接下来描述时钟配置和缓存配置的数据,在后面是一串文字描述了这个目标板。

                   初始的硬件配置完成后,U-Boot根据其静态设置来配置其他硬件子系统。U-Boot配置了I2C、DRAM、闪存(FLASH)、2级缓存(L2 cache)、PCI和网络子系统。最后U-Boot等待来自串行端口控制台的输入,显示命令行提示符=>

         5.引导内核

            U-Boot已经初始化了硬件、串行接口以及以太网接口,在其短暂且有益的生命中还剩一件工作:加载并引导LINUX内核。所有的引导加载程序都提供了命令用于加载和执行操作系统镜像。下面代码显示了使用U-BOOT手动加载并引导linux kernel的一种常用办法。

            加载linux kernel

                =>tftp 600000 uImage

                Speed: 1000, full deplex

                Using eTSECO0 device

                TFTP from server 192.168.0.103;our IP address is 192.168.0.18

                Filename 'uImage'

                Load address:0x600000

                Loading:##########################################################################

                               ##########################################################################

                done

                Bytes transferred = 1838553(1c0dd9 hex)

                =>tftp c00000 dtb

                Speed: 1000, full duplex

                Using eTSEC0 device

                TFTP from server 192.168.0.103;our IP address is 192.168.0.18

                Filename 'dtb'

                Load address: 0xc00000

                Loading: ##

                done

                Bytes transferred = 16384(4000 hex)

                =>bootm 600000 - c00000

                ## Booting kernel from Legacy Image at 00600000..

                Image Name:    MontaVista Linux 6/2.6.27/freesc

                Image Type:      PowerPC Linux Kernel Image(gzip compressed)

                Data Size:         1838489  Bytes = 1.8MB

                Load Address: 00000000

                Entry Point: 00000000

                Verifying Checksum........OK

                ##Flattened Device Tree blob at 00c00000

                     Booting using the fdt blob at 0xc00000

                     Uncompressing Kernel Image ....OK

                     Loading Device Tree to 007f9000, end 007fffff...OK          在这之前是由内核引导程序打印的信息之后全是linux kernel产生的


                Using MPC85xx CDS machine description

                Memory CAM mapping: CAM0=256MB,CAM1 = 0MB,CAM2 = 0MB, residual: 0MB

                ...

                省略linux内核的引导消息

                ...

                freescale-8548cds login: << ----Linux登陆命令提示符

             tftp命令指示U-Boot使用TFTP协议将内核镜uImage通过网络加载到内存。在这个例子中,内核镜像存放于开发工作站(通常,这个开发工作站就是通过串行端口与目标机相连的那台主机)。执行tftp命令时,需要传入一个地址参数,这个地址用于指定内核镜像将要被加载到的目标板内存的物理地址。

       第二次执行tftp命令加载了一个目标板配置文件,成为设备树,这个文件其他名字比如扁平设备树和设备树二进制文件或dtb。这个文件和目标板有关包含了内核所需的用于引导目标板的信息。

       执行uboot(从内存镜像引导)命令来让U-Boot引导刚才加载至内存的内核,起始地址就是在tftp中指定的地址。在这个使用bootm命令的例子中,我们让U-Boot加载放在地址0x600000处的内核,并将加载到地址0xC00000处的设备树二进制文件传给内核,bootm命令会将控制权移交给Linux内核,假设内核配置正确,这个命令的正确结果是在引导LINUX内核直至在目标板上出现控制台命令提示符,如同登陆提示符所示

       当linux内核掌握控制权的时候引导加载程序就不复存在了。linux内核会要求收回那些之前被引导加载程序所占用的内存和系统资源,将控制权交回给引导加载程序的唯一办法就是重起目标板。

      6.内核初始化

      在kernel开始执行之前它会输出大量的状态消息。

       Linux内核加载的最后几行引导消息

         ...

                  looking up port of RPC 100005/1 on 192.168.0.9

                  VFS:Mounted root(nfs filesystem)

                  Freeing unused kernel memory:152k init

                  INIT:version 2.86 booting

      

                  freescale-8548cds login:

       linux在串行端口终端显示登陆提示符之前,会挂载一个根文件系统。linux必须通过一系列必要的步骤,从一个NFS服务器远程(通过以太网)挂载其根文件系统,这个NFS服务器程序运行于IP地址为192.168.0.9的主机上。通常这个主机就是你开发的工作站。根文件系统包含整个linux系统的应用程序,系统库和工具软件。

              linux必须有一个文件系统,一个文件系统由一组预定义的系统目录和文件组成,这些目录和文件按照特定的布局存储在硬盘或者其他存储介质上,而linux内核可以挂载这些介质作为其根文件系统