嵌入式Linux应用开发完全手册

978-7-115-18262-3
作者: 韦东山
译者:
编辑: 黄焱

图书目录:

详情

内 容 提 要 本书全面介绍了嵌入式Linux系统开发过程中,从底层系统支持到上层GUI应用的方方面面,内容涵盖Linux操作系统的安装及相关工具的使用、配置,进行嵌入式编程所需要的基础知识(交叉编译工具的选项设置、Makefile语法、ARM汇编指令等),硬件部件的使用及编程(囊括了常见硬件,比如UART、I2C、LCD等),U-Boot、Linux内核的分析、配置和移植,根文件系统的构造(包括移植busybox、glibc、制作映象文件等),内核调试技术(比如添加kgdb补丁、栈回溯等),驱动程序编写及移植(LED、按键、扩展串口、网卡、硬盘、SD卡、LCD和USB等),GUI系统的移植(包含两个GUI系统:基于Qtopia和基于X),应用程序调试技术。 本书从最简单的点亮一个LED开始,由浅到深地讲解,使读者最终可以配置、移植、裁剪内核,编写驱动程序,移植GUI系统,掌握整个嵌入式Linux系统的开发方法。 本书由浅入深,循序渐进,适合刚接触嵌入式Linux的初学者学习,也可作为大中专院校嵌入式相关专业本科生、研究生的教材。

图书摘要

第1章 嵌入式Linux开发概述

本章目标

了解嵌入式系统的概念及发展历史

了解ARM处理器

了解各类嵌入式操作系统

1.1 嵌入式系统介绍

1.1.1 嵌入式系统的定义和特点

1.嵌入式系统的定义

嵌入式系统的定义为:以应用为中心、以计算机技术为基础、软硬件可裁剪、适用于应用系统,对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。它的主要特点是嵌入、专用。

从20世纪70年代起,微型机以小型、价廉、高速数值计算等特点迅速走向市场,它所具备的智能化水平在工业控制领域发挥了作用,常被组装成各种形状,“嵌入”到一个对象体系中,进行某类智能化的控制。这样一来,计算机便失去了原来的形态与“通用”的功能,为区别于通用计算机系统,将这类为了某个“专用”的目的,而“嵌入”到对象体系中的计算机系统,称为嵌入式计算机系统,简称嵌入式系统。

含有嵌入式系统的设备称为嵌入式设备,这在生活中随处可见:电子表、手机、MP3播放器、摇控器等,涵盖了生产、工业控制、通信、网络、消费电子、汽车电子、军工等领域。从通俗、广义的角度来说,除电脑、超级计算机等具备比较强大计算能力及系统资源(比如内存、存储器等)的电子系统之外,凡具备计算能力的设备都可称为嵌入式设备。随着技术的进步,嵌入式设备的性能越来越高,一个相对高级的PDA的性能并不弱于一般的电脑。

2.嵌入式系统的特点

嵌入式设备常应用于“特定”场合,与“通用的”个人电脑相比,具备以下特点。

(1)软件、硬件可裁剪。

将市面上的手机拆开,会发现虽然它们的功能是相似的,但是所用芯片多种多样,所用的操作系统也有多种,操作界面更是千变万化,操作的便利性各有千秋。这不同于个人电脑,CPU除了INTEL就是AMD公司的,操作系统多用Windows。功能、成本、开发效率等条件决定了嵌入式设备的选材多样化,软件、硬件可裁剪,即当不需要某项功能时,可以去除相关的软硬件。

(2)对功能、可靠性、成本、体积、功耗严格要求。

功能、可靠性、功耗这3点是软件开发人员最关注的地方。仍以手机为例,当选定硬件平台之后,处理器的性能已经被限定了,怎样使得手机的操作更人性化、菜单响应更快捷、具备更多更好的功能,这完全取决于软件。需要驱动程序和应用程序配合,最大程度地发挥硬件的性能。

也许读者见过这类手机,它的屏幕总是经过很长时间才熄灭,这使得它的电池很快耗光,只要在编写软件时进行改进,就可能成倍地延长电池的使用时间。一个优秀的嵌入式系统,对硬件性能的“压榨”、对软件的细致调节,已经到了精益求益的地步。有时候甚至为了节省几秒的启时间而大动脑筋,调整程序的启动顺序让耗时的程序稍后运行、改变程序的存储方式以便更快地加载等,甚至通过显示一个进度条让用户觉得时间没那么长。

1.1.2 嵌入式技术的发展历史

嵌入式技术在20世纪70年代起源于微型机,从此之后,通用计算机与嵌入式计算机就走上了两条不同的道路。通用计算机系统的技术要求是高速、海量的数值计算;技术发展方向是总线速度的无限提升,存储容量的无限扩大。 而嵌入式计算机系统的技术要求则是对象的智能化控制能力;技术发展方向是与对象系统密切相关的嵌入性能、控制能力与控制的可靠性。

嵌入式技术的发展日新月异,经历了单片机(SCM)、微控制器(MCU)、系统级芯片(SoC)3个阶段。

1.SCM(Single Chip Microcomputer)

又称单片微型计算机,简称单片机,随着大规模集成电路的出现及其发展,计算机的CPU、RAM、ROM、定时数器和多种I/O接口集成在一片芯片上,形成芯片级的计算机。

这个阶段主要是“寻求”单片形态嵌入式系统的最佳体系结构,也是从这个阶段起,嵌入式计算机技术与通用计算机技术走上两条不同的道路。

2.MCU(Micro Controller Unit)

MCU即微控制器阶段的特征是:“满足”各类嵌入式应用,根据对象系统要求扩展各种外围电路与接口电路,突显其对象的智能化控制能力。它所涉及的领域都与对象系统相关,因此,发展MCU的重任不可避免地落在电气、电子技术厂家的身上。

实际上,MCU、SCM之间的概念在日常工作中并不严格区分,很多时候一概以“单片机”称呼。随着能够运行更复杂软件(比如操作系统)的SoC的出现,“单片机”通常是指不运行操作系统、功能相对单一的嵌入式系统,但这不是绝对的,比如8051上就可以运行RTX51实时操作系统,它的大小只有6kB,相比于嵌入式Linux、WindowsCE等操作系统而言比较简单。

3.SoC(System on a Chip)

随着设计与制造技术的发展,集成电路设计从晶体管的集成发展到逻辑门的集成,现在又发展到IP的集成,即SoC(System on a Chip)设计技术。SoC可以有效地降低电子/信息系统产品的开发成本,缩短开发周期,提高产品的竞争力,是未来工业界将采用的最主要的产品开发方式。

虽然SoC一词多年前就已出现,但到底什么是SoC则有各种不同的说法。在经过了多年的争论后,专家们就SoC的定义达成了一致意见。这个定义虽然不是非常严格,但明确地表明了SoC的特征。

① 实现复杂系统功能的VLSI;

② 采用超深亚微米工艺技术;

③ 使用一个以上嵌入式CPU/数字信号处理器(DSP);

④ 外部可以对芯片进行编程;

⑤ 主要采用第三方IP进行设计。

从上述SoC的特征来看,SoC中包含了微处理器/微控制器、存储器以及其他专用功能逻辑,但并不是包含了微处理器、存储器以及其他专用功能逻辑的芯片就是SoC,8051就集成了微处理器、存储器时部件,它不属于SoC。SoC技术被广泛认同的根本原因,并不在于SoC可以集成多少个晶体管,而在于SoC可以用较短时间设计出来,这是SoC的主要价值所在——缩短产品的上市周期。

因此,SoC更合理的定义为:SoC是在一个芯片上由于广泛使用预定制模块IP(Intellectual Property)而得以快速开发的集成电路。

本书介绍的S3C2410/S3C2440就属于SoC,它们集成了处理器、内存管理单元(MMU)、NAND Flash控制器等部件,而处理器是基于ARM公司的IP设计的。

嵌入式软件随着硬件的发展,也发生了很大的变化。在SCM、MCU阶段,嵌入式软件的编写通常由相关行业的电气、电子技术专家编写,计算机专业队伍并没有真正进入单片机应用领域。因此,电子技术应用工程师以自己习惯性的电子技术应用模式从事单片机的应用开发。这种应用模式最重要的特点是:软、硬件的底层性和随意性;对象系统专业技术的密切相关性;缺少计算机工程设计方法。

随着嵌入式处理器性能的快速提高,网络、通信、多媒体技术得以发展,很多嵌入式设备都具备收发邮件、编写文档、视听等功能,计算机专业人士开始进入嵌入式领域。这形成了明显的技术特点:基于操作系统、以网络、通信为主的“非嵌入式底层”应用——除要完成的功能比较特殊、性能比较苛刻外,嵌入式应用软件的开发已经与普通软件开发没有差别。实际上,很多基于操作系统的嵌入式应用程序就是先在PC上模拟验证,最后才移入嵌入式设备的。

以一个简单的例子加以说明:以前基于单片机编写的软件,通常是在main函数中定义一个无限循环,然后在里面查询各类输入事件,并作出相应处理,它直接操作硬件;而基于SoC的软件多是在操作系统上面运行,通过驱动程序操作硬件,这使得软件开发以分工的形式进行。

1.2 基于ARM处理器的嵌入式Linux系统

1.2.1 ARM处理器介绍

1.ARM的概念

嵌入式处理器种类繁多,有ARM、MIPS、PPC等多种架构。ARM处理器的文档丰富,各类嵌入式软件大多(往往首选)支持ARM处理器,使用ARM开发板来学习嵌入式开发是个好选择。基于不同架构CPU的开发是相通的,掌握ARM架构之后,在使用其他CPU时也会很快上手。当然,作为产品进行选材时,需要考虑的因素就非常多了,这不在本书的介绍范围之内。ARM(Advanced RISC Machine),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 
ARM公司是32位嵌入式RISC微处理器技术的领导者,自从1990年创办公司以来,基于ARM技术IP核的微处理器的销售量已经超过了100亿。 
ARM公司并不生产芯片,而是出售芯片技术授权。其合作公司针对不同需求搭配各类硬件部件,比如UART、SDI、I 2C等,设计出不同的SoC芯片。 
ARM公司在技术上的开放性使得它的合作伙伴既有世界顶级的半导体公司,也有各类中、小型公司。随着合作伙伴的增多,也使得ARM处理器可以得到更多的第三方工具、制造和软件支持,又使整个系统成本降低,使新品上市时间加快,从而具有更大的竞争优势。 基于ARM的处理器以其高速度、低功耗、价格低等优点得到非常广泛的应用,它可以应用于以下领域: 
① 为无级通信、消费电子、成像设备等产品提供可运行复杂操作系统的开放应用平台; 
② 在海量存储、汽车电子、工业控制和网络应用等领域提供实时嵌入式应用; 
③ 安全系统,比如信用卡、SIM卡等。

2.ARM体系架构的版本

ARM体系架构的版本就是它所使用的指令集的版本。ARM架构支持32位的ARM指令集和16位的Thumb指令集,后者使得代码的存储空间大大减小。还提供了一些扩展功能,比如Java加速器(Jazelle)、用以提高安全性能的TrustZone技术、智能能源管理(IEM,Intelligent Energy Manager)、SIMD和NEONTM等技术。

还在使用的ARM指令集(ISA,Instruction Set Architecture)有以下版本。

(1)ARMv4。

这是当今市场上最老的版本,ARMv4只支持32位的指令集,支持32位的地址空间。一些ARM7系列的处理器和Intel公司的StrongARM处理采用ARMv4指令集。

(2)ARMv4T。

增加了16位的Thumb指令集,它可以产生更紧凑的代码,与相同功能的ARM代码相比,可以节省超过35%的存储空间,同时具备32位代码的所有优点。

(3)ARMv5TE。

在1999年,ARMv5TE版本改进了Thumb指令集,增加了一些“增强型DSP指令”,简称为E指令集。

这些指令用于增强处理器对一些典型的DSP算法的处理性能,使得音频DSP应用可以提升70%的性能。许多系统在使用微控制器来进行各类控制的同时,还需要具备数据处理能力,传统的做法要么是使用更高级的处理器(这使得成本增加),要么是使用多个处理器(这使得系统复杂度增高)。通过E指令集可以在一个普通CPU中增加DSP的功能,这在成本、性能、简化设计等方面都有优势。

(4)ARMv5TEJ。

在2000年,ARMv5TEJ版本中增加了Jazelle技术用于提供Java加速功能。相比于仅用软件实现的Java虚拟机,Jazelle技术使得Java代码的运行速度提高8位,而功耗降低80%。

Jazelle技术使得可以在一个单核的处理器上运行Java程序、已经建立好的操作系统和应用程序。

(5)ARMv6。

在2001年,ARMv6问世。它在很多方面都有改进:存储系统、异常处理,最重要的是增加了对多媒体功能的支持。ARMv6中包含了一些媒体指令以支持SIMD媒体功能扩展。SIMD媒体功能扩展为音频/视频的处理提供了优化功能,可以使音频/视频的处理性能提高4倍。

ARMv6中还引入了Thumb-2和TrustZone技术,这是两个可选的技术。之前的版本中,ARM 指令和Thumb指令分别运行于不同的处理器状态,执行不同指令集的指令前要进行切换。Thumb-2技术增加了混合模式的功能,定义了一个新的32位指令集,可以运行32位指令与传统16位指令的混合代码。这能够提供“ARM指令级别的性能”与“Thumb指令级别的代码密度”。TrustZone技术在硬件上提供了两个隔离的地址空间:安全域(secure world)和非安全域(non-secure world),给系统提供了一个安全机制。

(6)ARMv7。

ARMv7架构使用Thumb-2技术,还使用了NEON技术,将DSP和媒体处理能力提高了近4倍,并支持改良的浮点运算,满足下一代3D图形、游戏物理应用以及传统嵌入式控制应用的需求。

总结

版本名中的T表示Thumb指令集,E表示增强型DSP指令,J表示Java加速器。

3.ARM处理器系列

在相同指令集下,搭配不同部件就可以组装出具有不同功能的处理器,比如有无内存管理单元、有无调试功能等。它们可以分为8个系列,系列名中有7个后缀,这些后缀可以组合,含义如下。

① T:表示支持Thumb指令集。

② D:表示支持片上调试(Debug)。

③ M:表示内嵌硬件乘法器(Multiplier)。

④ I:支持片上断点和调试点。

⑤ E:表示支持增强型DSP功能。

⑥ J:表示支持Jazelle技术,即Java加速器。

⑦ S:表示全合成式(full synthesizable)。

这8个系列中,ARM7、ARM9、ARM9E和ARM10为通用处理器系列,每一个系列提供一套相对独特的性能来满足不同应用领域的需求。SecurCore系列专门为安全要求较高的应用而设计。

下面简要说明它们的特点,要了解更详细的信息请参考ARM公司的网站。(http://www. arm.com)

(1)ARM7。

ARM7系列处理器是低功耗的32位RISC微处理器,它主要用于对成本、功耗特别敏感的产品。最高可以达到130MIPS,支持Thumb 16位指令集和ARM 32位指令集。

ARM7系列微处理器包括如下几种类型的核:ARM7TDMI、ARM7TDMI-S、ARM720T、ARM7EJ-S。其中,ARM7TMDI是目前使用最广泛的32位嵌入式RISC处理器,属于低端ARM处理器核。

ARM7系列的处理器没有内存管理单元(MMU)。

(2)ARM9。

与ARM7相比,ARM9的最大差别在于:有MMU和Cache。它的指令执行效率较ARM7有较大提高,最高可达到300MIPS。

ARM7系列微处理器有ARM920T和ARM922T两种类型。

(3)ARM9E。

ARM9E系列微处理器在单一的处理器内核上提供了微控制器、DSP、Java应用系统的解决方案,极大地减少了芯片的面积和系统的复杂程度。ARM9E系列微处理器提供了增强的DSP处理能力,适合于那些需要同时使用DSP和微控制器的应用场合。

ARM9E系列微处理器有ARM926EJ-S、ARM946E-S、ARM966E-S、ARM968E-S和ARM996HS共5种类型。

(4)ARM10E。

ARM10E系列微处理器具有更加杰出的高性能、低功耗特点,由于使用了新的体系结构,它拥有所有ARM系列中最高的主频。ARM10E系列微处理器采用了一种新的省电模式,支持“64-bit load-store micro-architecture”,含有浮点运算协处理器(符合IEEE 754标准,支持向量运算)。

ARM10E系列微处理器有ARM1020E、ARM1022E和ARM1026EJ-S共3种类型。

(5)ARM11。

ARM11系列微处理器是ARM公司近年推出的新一代RISC处理器,它是ARM新指令架构——ARMv6的第一代设计实现。ARM11的媒体处理能力和低功耗特点特别适用于无线和消费类电子产品,其高数据吞吐量和高性能的结合非常适合网络处理应用。另外,在实时性能和浮点处理等方面ARM11可以满足汽车电子应用的需求。基于AMRv6体系结构的ARM11系列处理器将在上述领域发挥巨大的作用。

ARM11系列微处理器有这4种类型:ARM11 MPCore,ARM1136J(F)-S,ARM1156T2(F)-S 和ARM1176JZ(F)-S。

(6)Cortex。

Cortex系列处理器是基于ARMv7架构的,分为Cortex-A、Cortex-R和Cortex-M共3类。Cortex-A为传统的、基于虚拟存储的操作系统和应用程序而设计,支持ARM、Thumb和Thumb-2指令集;Cortex-R针对实时系统设计,支持ARM、Thumb和Thumb-2指令集;Cortex-M为对价格敏感的产品设计,只支持Thumb-2指令集。

(7)SecurCore。

SecurCore系列微处理器专为安全需要而设计,提供了完善的32位RISC技术的安全解决方案,因此,SecurCore系列微处理器除了具有ARM体系结构的低功耗、高性能的特点外,还具有其独特的优势,即提供了对安全解决方案的支持。

SecurCore系列微处理器有如下类型:SecurCoreSC100、SecurCore SC200。

(8)OptimoDE Data Engines。

这是一个新的IP核,针对高性能的嵌入式信号处理应用而设计。

另外,Intel公司的StrongARM、Xscale系列处理器也属于ARM架构。Intel StrongARM处理器是便携式通信产品和消费类电子产品的理想选择,已成功应用于多家公司的掌上电脑系列产品。Xscale处理器是基于ARMv5TE体系结构的解决方案,是一款全性能、高性价比、低功耗的处理器。它支持16位的Thumb指令和DSP指令集,已使用在数字移动电话、个人数字助理和网络产品等场合。

本书使用S3C2410、S3C2440芯片,它们的处理器都属于ARM920T系列,版本为ARMv4T。

1.2.2 在嵌入式系统中选择嵌入式Linux的理由

随着技术的发展及人们需求的增加,各种消费类电子产品的功能越来越强大,随身携带的电子设备变得“等同于PC”:上面有键盘、触摸屏、LCD等输入、输出设备,可以观看视频、听音乐,可以浏览网站、接收邮件,可以查看、编辑文档等。在工业控制领域,系统级芯片(SoC)以更低廉的价格提供了更丰富的功能,使得一个嵌入式系统可以同时完成更多的控制功能。

当系统越来越大、应用越来越多,使用操作系统很有必要。操作系统的作用有:统一管理系统资源、为用户提供访问硬件的接口、调度多个应用程序、管理文件系统等。在嵌入式领域可以选择的操作系统有很多,比如:嵌入式Linux、VxWorks、Windows CE、µC/OS-II等。

  VxWorks是美国WindRiver公司开发的嵌入式实时操作系统。单就性能而言,它是非常优秀的操作系统,具有可裁剪的微内核结构、高效的任务管理、灵活的任务间通信、微秒级的中断处理,支持POSIX 1003.1b实时扩展标准,支持多种物理介质及标准、完整的TCP/IP网络协议等。缺点是它支持的硬件相对较少,并且源代码不开放,需要专门的技术人员进行开发和维护,并且授权费比较高。

  Windows CE是微软公司针对嵌入式设备开发的32位、多任务、多线程的操作系统。它支持x86、ARM、MIPS、SH等架构的CPU,硬件驱动程序丰富,比如支持WiFi、USB 2.0等新型设备,并具有强大的多媒体功能;可以灵活裁剪以减小系统体积;与PC上的Windows操作系统相通,开发、调试工具使用方便,应用程序的开发流程与PC上的Windows程序的开发流程相似,就开发的便利性而言(特别是对于习惯在Windows下开发的程序员),Windows CE是最好的,但是,其源代码没有开放(目前开放了一小部分),开发人员难以进行更细致的定制;占用比较多的内存,整个系统相对庞大;版权许可费用也比较高。

  μC/OS-II是Micrium公司开发的操作系统,可用于8位、16位和32位处理器。可裁剪,对硬件要求较低;可以运行最多64个任务;调度方式为抢占式,即总是运行最高优先级的就绪任务。用户可以获得μC/OS-II的全部代码,但它不是开放源码的免费软件,作为研究和学习,可以通过购买相关书藉获得源码,用于商业目的时,必须购买其商业授权。相对于其他按照每个产品收费的操作系统,μC/OS-II采用一次性的收费方式,价格低廉。需要说明的是,μC/OS-II仅是一个实时内核,用户需要完成其他更多的工作,比如编写硬件驱动程序、实现文件系统操作(使用文件的话)等。

  Linux是遵循GPL协议的开放源码的操作系统,使用时无需交纳许可费用。内核可任意裁剪,几乎支持所有的32位、64位CPU;内核中支持的硬件种类繁多,几乎可以从网络上找到所有硬件驱动程序;支持几乎所有网络协议;有大量的应用程序可用,从编译工具、调试工具到GUI程序,几乎都有遵循GPL协议的相关版本;有庞大的开发人员群体,有数量众多的技术论坛,大多问题都可以得到快速而免费的解答。

Linux的缺点在于实时性,虽然2.6版本的Linux在实时性方面有较大改进,但是仍无法称为实时操作系统。有不少变种Linux在实时性方面做了很大改进,比如RTLinux达到了硬实时,TimeSys Linux提高了实时性。这些改进的Linux版本既有遵循GPL协议的免费版本,也有要付费的商业版本。

正是由于Linux开放源代码、易于移植、资源丰富、免费等优点,使得它在嵌入式领域越来越来流行。更重要的一点,由于嵌入式Linux与PC Linux源于同一套内核代码,只是裁剪的程度不一样,这使得很多为PC开发的软件再次编译之后,可以直接在嵌入式设备上运行,这使得软件资源“极大”非富,比如各类实用的函数库、小游戏等。

第2章 嵌入式Linux开发环境构建

本章目标

了解嵌入式Linux开发的交叉开发模式

搭建硬件、软件开发环境

掌握制作工具链的方法

2.1 硬件环境构建

2.1.1 主机与目标板结合的交叉开发模式

开发PC机上的软件时,可以直接在PC机上编辑、编译、调试软件,最终发布的软件也在PC机上运行。对于嵌入式开发,最初的嵌入式设备是一个空白的系统,需要通过主机为它构建基本的软件系统,并烧写到设备中;另外,嵌入式设备的资源并不足以用来开发软件。所以需要用到交叉开发模式:在主机上编辑、编译软件,然后在目标板上运行、验证程序。

主机指PC机,目标板指嵌入式设备,在本书中,目标板就是S3C2410、S3C2440开发板。

对于S3C2410、S3C2440开发板,进行嵌入式Linux开发时一般可以分为以下3个步骤。

(1)在主机上编译Bootloader,然后通过JTAG烧入单板。

通过JTAG接口烧写程序的效率非常低,它适用于烧写空白单板。为方便开发,通常选用具有串口传输、网络传输、烧写Flash功能的Bootloader,它可以快速地从主机获取可执行代码,然后烧入单板,或者直接运行。

(2)在主机上编译嵌入式Linux内核,通过Bootloader烧入单板或直接启动。

一个可以在单板上运行的嵌入式Linux内核是进行后续开发的基础,为方便调试,内核应该支持网络文件系统(NFS),即将应用程序放在主机上,单板启动嵌入式Linux内核后,通过网络来获取程序,然后运行。

(3)在主机上编译各类应用程序,单板启动内核后通过NFS运行它们,经过验证后再烧入单板。

烧写、启动Bootloader后,就可以通过Bootloader的各类命令来下载、烧写、运行程序了。启动嵌入式Linux后,也是通过执行各种命令来启动应用程序的。怎么输入这些命令、查看命令运行的结果呢?一般通过串口来进行输入/输出。所以交叉开发模式中,主机与目标板通常需要3种连接:JTAG、串口、网络,如图2.1所示。

注意

JTAG接口本来是用来调试程序的,但是本书中是通过它来烧写程序。

2.1.2 硬件要求

1.主机要求

一般的PC就可以用来进行嵌入式Linux开发,它应该满足以下要求。

① 有一个25针的并口接口,它用来接JTAG连线;

② 有一个9针的RS-232串行接口;

③ 支持网络;

④ 至少20GB的硬盘。

对于台式机,这3项要求一般都能满足;对于笔记本电脑,如果没有并口则需要使用其他电脑来烧写程序,如果没有串口,则可以使用USB-串口转换器。幸运的是,如果不是调试Bootloader,使用JTAG接口的次数会很少:只需要烧写一次Bootloader——当它启动后,就可以通过串口或网络下载程序,然后烧入单板。

2.目标板要求

本书的例子适用于两种开发板:S3C2410或S3C2440。市场上S3C2410、S3C2440开发板的原理图、配置基本相同,即使在细节上有所差异,理解代码后稍作修改即可使用。

开发板上对于S3C2410/S3C2440的每个硬件部件(UARG、NAND Flash控制器、I2C接口等)基本都外接了相关器件,有如下部件。

① 64MB SDRAM;

② 1MB NOR Flash;

③ 64MB NAND Flash;

④ 两个网卡(10MB和100MB);

⑤ 5个串口(内置3个,外扩2个);

⑥ 音频输入输出(本书没有介绍);

⑦ 2.5寸IDE接口;

⑧ 标准SD/MMC卡座;

⑨ 4个GPIO按键/4个GPIO按键;

⑩ 外接I2C接口的实时时钟(RTC)芯片。

硬件开发环境搭建很简单,将主机与目标板通过JTAG、串口线(接单板上的串口0)、网线(接单板上的网卡0)连接起来,将各类设备连接到目标板上去即可。

2.2 软件环境构建

2.2.1 主机Linux操作系统的安装

1.在Windows上安装虚拟机

本书基于Ubuntu7.10进行开发,它是一个很容易安装和使用的Linux发行版。光盘映象文件的下载地址为http://relenses.ubuntu.com/7.10。

安装方法有好几种:将映象文件刻录成光盘后安装,通过网络安装等。不熟悉Linux的读者可以通过VMware虚拟机软件使用映象文件安装,这样可以在Windows中使用Linux(反过来也是可以的),安装Linux后,再使用VMware安装windows,这样就可以在Linux中同时使用Windows。

这几种安装方法基本相同,下面介绍在Windows中通过VMware来安装Linux的方法。不管是哪种方法,都建议单独使用一个分区来存放本书所涉及的源码、编译结果,这样可以避免当系统出错、系统重装时破坏学习成果。

本书使用3个分区:1GB的交换分区(swap)、5GB的根分区(root)、15GB的工作分区(work)。swap分区被用来暂时存储数据,它可以提高系统性能;root分区被用来存放整个Linux系统;work分区的内容来自本书光盘,以后将在这个分区上编辑、编译、调试软件。

从VMware的官方网站http://www.vmware.com下载到VMware工具,安装后,参照以下方法安装、设置Linux。

建立一个虚拟机器需要指定硬盘、内存、网络。在VMware中可以使用实际的硬盘,也可以使用文件来模拟硬盘。本书使用文件来模拟硬盘:一个表示交换分区(swap),一个表示根分区(root),一个表示工作分区(work)。依照下面的一系列图形就能建立虚拟机。

① 启动VMware,如图2.2所示。

② 在后续界面中使用默认选项,直到出现如图2.3所示的界面,选择“Custom”自己定制虚拟机。

③ 选择虚拟机的格式,使用默认选项即可,如图2.4所示。

④ 在Windows中使用VMware安装Linux,Windows被称为“Host Operatins System”(主机操作系统),Linux被称为“Gest Operatins System”(客户操作系统)。选择Linux作为客户操作系统,版本为“Other Linux 2.6.x kernel”,如图2.5所示。

⑤ 设置虚拟机的名称及存储位置,如图2.6所示。

⑥ 指定虚拟机的内存容量,在图2.7所示的界面中有推荐值及取值范围。

⑦ 指定虚拟机的网络连接类型,一般使用桥接方式(bridged networking),如图2.8所示。安装完华后可以再进行修改。

⑧ 选择“I/O Adapter”,使用默认值,如图2.9所示。

⑨ 图2.10~图2.13所示为创建虚拟硬盘的过程,在创建完虚拟机后,还会重复这4个步骤创建另外两个虚拟硬盘。在图2.12中,“Split disk into 2GB files选项表示使用多个2GB的文件来表示一个很大的虚拟硬盘。如果Windows的碰盘格式为FAT32,因为它支持的最大文件只有4GB,所以要选择这个选项;如果是NTFS格式,则无需选择这个选项。

⑩ 单击“完成”按钮后,就创建了一个虚拟机,得到如图2.14所示的界面。

还要创建两个硬盘,单击图2.14中的“Edit virtual machine settings”进行设置。参照图2.14~图2.16及步骤⑨连续增加两个虚拟硬盘,一个容量为15GB,命名为work.vmdk(用来作为工作硬盘);另一个容量为1GB,命名为swap.vmdk(在上面创建交换分区)。

以后的步骤就和前面的步骤⑨一样了。

2.在虚拟机上安装Linux

本书使用Ubuntu 7.10的光盘文件ubuntu-7.10-desktop-i386.iso进行安装。下面简单介绍关键步骤,其他步骤可以参看安装时出现的说明。

(1)在虚拟机上使用光盘文件。

如图2.17所示,进入虚拟机的编辑界面,选中“CD-ROM”,在右边的界面中选择“Connect at power on”(表示开启虚拟机时就连接光盘);然后选择“Use ISO image”,如果有实际的光盘,可以选择“Use physical drive”(在安装随书光盘中的代码时就是这样设置的)。

(2)启动虚拟机,它使用前面设置的光盘文件启动,这时候即可开始安装Linux。

在虚拟机启动后,桌面有个名为“install”的图标,双击它进行安装。前面几个步骤是选择语言、键盘等,使用默认设置,先不要使用中文(以后远程登录时,中文不好显示)。当出现如图2.18所示的界面时,选择“Manual”。

注意

在VMware的操作系统中,要将鼠标光标释放出来(回到Windows中),按“Ctrl+Alt”键即可。

(3)在紧接着出现的界面中对硬盘进行分区、选择文件格式、选择挂载点。

本书设置的虚拟机使用3个虚拟硬盘,每个硬盘只划分一个分区。设置其中容量为5GB的分区的挂载点为“/”,在里面安装Linux系统;设置容量为15GB的分区的挂载点为“/work”,以后的代码、编译结果都放在/work目录下;设置容量为1GB的分区为swap分区,它不需要设置挂载点,也不需要设置文件格式。设置的结果如图2.19所示。

(4)然后在后续的界面中使用默认值,安装程序会进行格式化虚拟硬盘等操作。当出现如图2.20所示的界面时,在里面设置用户名及密码。

(5)开始安装系统,当安装完成时,出现如图2.21所示的界面。

如果从VMware的菜单“VM”→“Setting...”进入虚拟机的设置界面时,在“CD-ROM”的设置界面去掉“Connect at power on”选项(参考图2.17),此时单击图2.21所示的“Restart now”按钮即可(如果不能重启,直接关闭VMware后再启动)。

2.2.2 主机Linux操作系统上网络服务的配置与启动

下面配置Linux,启动FTP、SSH、NFS这3个服务。如果不是通过远程登录Linux,而是直接在Linux中进行开发,则FTP、SSH这两个服务不用开启。

1.设置网络

这涉及3方面的设置:主操作系统Windows、VMware、客户操作系统Linux。

本书假设:主操作系统Windows的IP为192.168.1.11,客户操作系统Linux的IP为192.168.1.57。

VMware提供4种网络连接方式:网桥网络(Bridged)、网络地址翻译网络(NAT)、仅为主机网络(Host-only)和客户网络。常用的方式是前两种,网桥网络需要接上网线才可使用,当主机与目标板间需要进行网络通信时使用这种方式,它相当于3台处于同一网段的计算机:主机(Windows)、虚拟机(Linux)、目标板。没有接网线时,可以使用NAT网络在主操作系统Windows与客户操作系统Linux间进行通信。

(1)设置客户操作系统Linux的IP地址。

选择Linux的启动栏执行“System”→“Administration”→“Network”命令,在对话框中选中“Connections”选项卡的“Wired connection”项,然后单击“Properties”按钮。设置eth0的IP为192.168.1.57,网关为192.168.1.2,然后重新启动即可,如图2.22所示。

(2)使用网桥网络时,设置主操作系统Windows和VMware。

使用网桥网络时,主操作系统Windows和Linux的IP必须属于同一个网段。

  将主操作系统Windows的网卡IP设为192.168.1.11。

  在VMware中,执行“VM”→“Setting”命令,然后参照图2.23设置以使用网桥网络(“Connect at power on”一定要选上)。

(3)使用NAT网络时,设置VMware。

使用NAT网络时,首先要确保主操作系统Windows的IP和Linux的IP不在同一个网段。由于Linux的IP已经设为192.168.1.57,需要修改Windows的IP让它不处于192.168.1.x网段。

然后分3步设置:修改虚拟机的设置使它使用NAT网络,修改NAT网络的IP地址范围,设置NAT网络的网关地址。VMware提供9个虚拟网卡:VMnet0~VMnet8,VMnet8用于NAT网络,其他的在本书中都不需要自己设置。

  设置虚拟机以使用NAT网络。

选择VMware的菜单“VM”→“Setting”,然后参照图2.24进行设置(“Connect at power on”一定要选上)。

  修改NAT网络的IP地址范围。

选择VMware的菜单“Edit”→“Virtual Network Setting...”,然后参照图2.25设置。

  设置NAT网络的网关地址。

选择VMware的菜单“Edit”→“Virtual Network Setting...”,然后参照图2.26进行设置。

2.安装、配置、启动FTP、SSH或NFS服务

(1)准备使用软件维护工具apt-get。

Ubuntu 7.10中没有安装FTP、SSH、NFS服务器软件,它提供了一个很方便的安装、升级、维护软件的工具apt-get。apt-get从光盘、网络上下载程序并安装。

第一次使用apt-get来安装程序之前,要先完成以下两件事。

① 修改/etc/apt/sources.list,将其中注释掉的网址打开。

在安装Ubuntu 7.10的时候,如果网络无法使用,它会自动将/etc/apt/sources.list中各项注释去掉。比如需要将以下两行开头的“#”号去掉:

#deb http://cn.archive.ubuntu.com/ubuntu/ gutsy main restricted
#deb-src http://cn.archive.ubuntu.com/ubuntu/ gutsy main restricted
……

注意

由于/etc/apt/sources.list属于root用户,而Ubuntu 7.10中屏蔽了root用户的使用,要修改它,需要使用sudo命令。比如可以使用“sudo vi /etc/apt/sources.list”来修改它,或者使用“sudo gedit&”命令启动图形化的文本编辑器,再打开、编辑它。

② 更新可用的程序列表。

执行如下命令即可,它只是更新内部的数据库以确定哪些程序已经安装、哪些没有安装、哪些有新版本。apt-get程序将使用这个数据库来确定怎样安装用户指定的程序,并找到和安装它所依赖的其他程序。示例程序如下。

$ sudo apt-get update

(2)安装、配置、启动服务。

首先说明,Ubuntu 7.10中隐藏了root用户,也就是说不能使用root用户登录,这可以避免不小心使用root权限而导致系统崩溃。当需要使用root权限时,使用“sudo”命令,比如要修改/etc/exports文件时,修改如下所示:

# sudo vi /etc/exports

现在可以使用apt-get来安装软件了,以下的安装、配置、启动方法在Ubuntu 7.10自带的帮助文档中都有说明。

① 安装、配置、启动FTP服务。

执行以下命令安装,安装后即会自动运行:

$ sudo apt-get install vsftpd

修改vsftpd的配置文件/etc/vsftpd.conf,将下面几行前面的“#”去掉。

#local_enable=YES
#write_enable=YES

上面第一行表示是否允许本地用户登录,第二行表示是否允许上传文件。

修改完华之后,执行以下命令重启FTP服务:

$ sudo /etc/init.d/vsftpd restart

② 安装、配置、启动ssh服务。

执行以下命令安装ssh服务,安装后即会自动运行:

$ sudo apt-get install openssh-server

它的配置文件为/etc/ssh/sshd_config,使用默认配置即可。

③ 安装、配置、启动NFS服务。

执行以下命令安装nfs服务,安装后即会自动运行:

$ sudo apt-get install nfs-kernel-server portmap

它的配置文件为/etc/exports,在里面增加以下内容,以后将通过网络文件系统访问/work/ nfs_root目录。

/work/nfs_root *(rw,sync,no_root_squash)

修改完华之后,执行以下命令重启NFS服务:

$ sudo /etc/init.d/nfs-kernel-server restart

以上3个服务使用apt-get安装后已经启动,并且以后每次开机都会自动启动。如果要取消某个服务,可以在Linux的启动栏菜单执行“System”→“系统管理”→“网络”命令,在对话框中取消。

2.2.3 在主机Linux操作系统中安装基本的开发环境

使用光盘安装的Ubuntu 7.10是一个比较精简的Linux发行版,它缺乏一些开发用的工具、文件,比如标准C库的头文件、g++编译器等。

先按照图2.17所示挂接上Ubuntu 7.10的安装光盘,然后使用以下命令安装基本的开发环境:

$ sudo apt-get install build-essential

还要安装工具bison、flex,它们分别是语法、词法分析器:

$ sudo apt-get install bison flex

安装C函数库的man手册,以后就可以通过类似“man read”的命令查看函数的用法了:

$ sudo apt-get install manpages-dev

2.2.4 光盘的内容结构及安装

1.光盘的内容结构

光盘内容分为8部分:硬件实验(hardware)、系统移植(system)、驱动和测试程序(drivers_and_test)、GUI、工具(tools)、scratchbox(这也是一个工具)、网络文件系统(nfs_root)、调试工具(debug),目录结构如图2.27所示。

注意

光盘中几乎所有文件都制作成压缩包,比如光盘根目录中有一个文件hardware.tar.bz2,它对应图2.27中的hardware目录,解压即得此目录。

hardware目录下是各个硬件部件的实验代码,进入子目录后执行make命令即可生成可执行二进制程序(名字为子目录名加上后缀“.bin”),烧入开发板的NAND Flash中即可运行。

U-Boot、Linux内核、根据busybox创建的文件系统这3部分构成了基本的、最小的嵌入式Linux系统,它们的代码在system目录下。本书中介绍的驱动也全部包含在system/linux-2.6.22内核代码中,drivers_and_test主要是测试程序。

本书介绍两种GUI系统:qtopia、X window。GUI/xwindow目录下有4个子目录。

  X目录中主要是Xorg的代码,它提供X server;

  matchbox是一个基于X的、用于嵌入式系统的小型GUI环境,它包括一个窗口管理器、一个面板、一个桌面、一个共享功能程序库和一些小的面板应用程序;

  GTK目录下是GTK+库,GTK+是一个用于创建图形用户界面的多平台工具,它包含有基本的控件和一些很复杂的控件,比如文件选择控件和颜色选择控件;

  apps目录下是几个基于X、GTK+的应用程序。

tools目录下是运行于主机上的工具,主要是交叉编译工具。arm-linux-gcc-3.4.5-glibc-2.3.6.tar.bz2和scratchbox-arm-linux-gcc-3.4.5-glibc-2.3.6.tar.bz2都是使用create_crosstools目录中的软件编译出来的交叉编译工具链,前一个是在主机上直接运行;后一个是当主机上启动scratchbox后,在scratchbox里面运行。这两个工具编译出来的代码是完全一样的。

scratchbox是一个交叉编译工具包,它的目的是使嵌入式Linux开发变得像开发PC Linux软件一样容易。在移植X window时将用到它。

nfs_root目录下是4个子目录:最小的根文件系统fs_mini、使用mdev机制的根文件系统fs_min_mdev、含有qtopia图形程序的根文件系统fs_qtopia、含有X window图形程序的根文件系统fs_xwindow。在开发阶段,单板上的内核启动后可以通过NFS挂接它们中的某一个,然后执行其中的程序;开发完成后,将所用的整个子目录制作为映象文件,烧入开发板。

2.安装光盘

安装光盘前先使用以下的命令改变/work目录的拥有者及所属组名:

$ sudo chown book:book /work -R

然后将光盘中所有内容复制到Linux的/work目录中,有以下3种方法:

① 在Windows下,可以通过cuteFTP等工具登录Linux,然后上传文件;

② 如果是通过VMware运行Linux,则在VMware中挂接光盘后(如图2.17所示),Linux中会自动弹出光盘的目录,将它的内容复制到/work目录下;

③ 如果是直接运行Linux,在光驱中放入光盘后,Linux中也会自动弹出光盘的目录,将它的内容复制到/work目录下。

2.2.5 安装交叉编译工具链

首先约定:在主机上执行的命令提示符为“$”;在主机中启动scratchbox,然后在scratchbox里执行的命令,提示符为“>”;在单板上执行的命令,提示符为“#”。比如同是执行“ls”命令,用下面3行表示:

$ ls
> ls
# ls

1.使用制作好的工具链

刚开始学习时,建议使用已经制作好工具链,使用以下命令解压得到gcc-3.4.5-glibc-2.3.6目录。

$ cd /work/tools
$ tar xjf arm-linux-gcc-3.4.5-glibc-2.3.6.tar.bz2

然后在环境变量PATH中增加路径,如下所示:

$ export PATH=$PATH:/work/tools/gcc-3.4.5-glibc-2.3.6/bin

这使得可以直接运行这个目录下的程序,而不需要指定目录位置。

为了不要每次使用时都手工设置PATH,可以在/etc/environment中修改PATH的值如下所示:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/
games: /work/tools/gcc-3.4.5-glibc-2.3.6/bin "

安装ncurses,ncurses是一个能提供功能键定义(快捷键)、屏幕绘制以及基于文本终端的图形互动功能的动态库。如果没有它,在执行“make menuconfig”命令配置程序时会出错。使用以下命令安装:

$ cd /work/tools/
$ tar xzf ncurses.tar.gz
$ cd ncurses-5.6
$ ./configure --with-shared --prefix=/usr
$ make
$ make install

2.自己制作工具链

用户也可以自己编译工具链。如果要基于gcc和glibc来制作工具链,可以使用crosstool来进行编译;如果要基于gcc和uClibc来制作工具链,可以使用buildroot来进行编译。如果不借助于这些工具,编译过程是非常繁锁的。uClibc比glibc小,在已有的接口上是兼容的,更适用于嵌入式系统。但是uClibc并没有包括glibc中的所有接口实现,因此有些应用可能在uClibc中不能编译。基于这个原因,本书使用glibc,当对系统很熟悉后,或是在开发资源很受限制的产品时,可以使用uClibc。

下面将使用/work/tools/create_crosstools目录下的crosstool-0.43.tar.gz工具来编译工具链,它运行时,会自动从网上下载源码,然后编译。也可以先自己下载源码,再运行crosstool。本书已经将源码放在src_gcc_glibc目录下。

crosstool官方网站为http://kegel.com/crosstool/,可以参考其中的crosstool-how to.html选择、配置、编译工具链。

下面分步讲解。

(1)修改crosstool脚本。

执行以下命令解压缩:

$ tar xzf crosstool-0.43.tar.gz

glibc-2.3.6-version-info.h_err.patch是一个补丁文件,它修改glibc-2.3.6/csu/Makefile,里面的一个小错误,导致自动生成的version-info.h文件编译出错。将它复制到crosstool的补丁目录下:

$ cp glibc-2.3.6-version-info.h_err.patch crosstool-0.43/patches/glibc-2.3.6/

注意

另一个补丁文件ld-2.15-scratchbox_NATIVE.patch在第26章制作运行在scratchbox上的交叉编译工具链时才用到。

后面将执行crosstool-0.43目录下的demo-arm-softfloat.sh脚本来进行编译,摘取它的部分内容如下:

07 TARBALLS_DIR=$HOME/downloads
08 RESULT_TOP=/opt/crosstool
09 export TARBALLS_DIR RESULT_TOP
10 GCC_LANGUAGES="c,c++"
……
26 #eval 'cat arm-softfloat.dat gcc-3.3.6-glibc-2.3.2-tls.dat' sh all.sh --notest
27 #eval 'cat arm-softfloat.dat gcc-3.4.5-glibc-2.2.5.dat' sh all.sh --notest
28 #eval 'cat arm-softfloat.dat gcc-3.4.5-glibc-2.3.5.dat' sh all.sh --notest
29 eval 'cat arm-softfloat.dat gcc-3.4.5-glibc-2.3.6.dat' sh all.sh --notest

第7行的TARBALLS_DIR表示源码存放的位置。

第8行的RESULT_TOP表示编译结果存放的位置。

第10行的GCC_LANGUAGES表示制作出来的工具链支持C、C++语言,如果要支持其他语言,可以在里面增加。比如下面一行表示支持Java:

GCC_LANGUAGES="c,c++,java"

从第26~29行可知,可以选择多种gcc、glibc版本,本书使用默认版本:gcc-3.4.5和glibc-2.3.6。执行demo-arm-softfloat.sh脚本后,它将根据arm-softfloat.dat、gcc-3.4.5-glibc-2.3.6.dat这两个文件中定义的环境变量调用all.sh脚本进行编译。gcc-3.4.5-glibc-2.3.6.dat文件指明了要下载或使用的文件。

需要修改demo-arm-softfloat.sh、arm-softfloat.dat、all.sh这3个文件。

① 修改demo-arm-softfloat.sh,修改后的内容如下:

07 TARBALLS_DIR=/work/tools/create_crosstools/src_gcc_glibc
08 RESULT_TOP=/work/tools

② 修改arm-softfloat.dat,修改如下:

02 TARGET=arm-softfloat-linux-gnu
改为:
02 TARGET=arm-linux

它表示编译出来的工具样式为arm-linux-gcc、arm-linux-ld等,这是常用的名字。

③ 修改all.sh。

如果现在就执行demo-arm-softfloat.sh,最终结果将存放在/work/tools/gcc-3.4.5-glibc-2.3.6/ arm-linux目录下。为简洁起见,修改all.sh,将结果存放在/work/tools/gcc-3.4.5-glibc-2.3.6目录下。

70 PREFIX=${PREFIX-$RESULT_TOP/$TOOLCOMBO/$TARGET}
改为:
70 PREFIX=${PREFIX-$RESULT_TOP/$TOOLCOMBO}

(2)编译、安装工具链。

执行以下命令:

$ cd crosstool-0.43/
$ ./demo-arm-softfloat.sh

编译2、3个小时后,将在/work/tools/目录下生成gcc-3.4.5-glibc-2.3.6子目录,交叉编译器、库、头文件都包含在里面。设置PATH环境变量即可使用。使用下面命令测评一下:

$ arm-linux-gcc –v

现在,基本的开发环境已经建立,在后续开发过程中,要使用到其他工具时,再进行安装。

2.2.6 书中写作风格的约定

2.2.5小节开头部分约定:使用“$”、“>”、“#”这3个提示符分别表示在主机、scratchbox、或者在开发板上执行命令。

另外一个约定是关于“函数调用”的。阅读Linux源代码最大的困难是各个函数之间的调用关系很复杂,内核中常常有这种调用方式:函数A调用函数B,不是在A的代码里直接调用B,而是通过某个函数指针(它在其他地方被赋值为B)间接调用。

编者在阅读代码时,常使用以下的方式标记函数调用关系,在书中也使用同样的方式。假设有A、B、C、D共4个函数,它们分别处于a.c、b.c、c.c、d.c这4个文件中,A调用B 和C,B调用D,则使用以下的缩进方式表示:

A(a.c) ->
B(b.c) //可以加一些注释->
D(d.c)
C(c.c)

B比A缩进一格,表示B在A中被调用;相同的缩进表示同处于一个函数中,比如B、C都是在A中被调用;“//”号后可以加一些注释;“->”起辅助作用,表示“调用”。

相关图书

嵌入式Linux与物联网软件开发:ARM处理器开发自学教程
嵌入式Linux与物联网软件开发:ARM处理器开发自学教程
嵌入式Linux软硬件开发详解——基于S5PV210处理器
嵌入式Linux软硬件开发详解——基于S5PV210处理器
嵌入式 Linux C 语言应用程序设计(修订版)
嵌入式 Linux C 语言应用程序设计(修订版)
嵌入式Linux开发实用教程
嵌入式Linux开发实用教程
嵌入式 Linux应用程序开发标准教程(第2版)
嵌入式 Linux应用程序开发标准教程(第2版)

相关文章

相关课程