• 沒有找到結果。

前言: 内容简介: ARM 嵌入式 Linux 系统开发从入门到精通

N/A
N/A
Protected

Academic year: 2022

Share "前言: 内容简介: ARM 嵌入式 Linux 系统开发从入门到精通"

Copied!
317
0
0

加載中.... (立即查看全文)

全文

(1)

ARM 嵌入式 Linux 系统开发从入门到精通

内容简介:

这是一本以实践为宗旨的嵌入式 ARM Linux 开发书籍,它不同于一般的教材重点讲述 理论而缺乏实践的部分,也不同于许多类似书籍只针对特定开发板讲述,这对于没有开发板 的读者来说很难掌握书中的内容。ARM 是当今最主流的嵌入式微处理器,本书以应用最广 泛的新一代 ARM9 处理器为讲述对象。此外,Linux 是一个成熟而稳定的开放源代码操作系 统,将 Linux 植入嵌入式设备具有众多的优点。本书分为三部分:第一部分讲述 ARM Linux 系统移植,其中包括嵌入式系统开发入门,交叉编译器的构建,BootLoader 的移植与实现以 及 Linux 2.6 内核的编译与下载;第二部分讲述 ARM Linux 的驱动程序开发,其中包括最常 见的字符设备驱动的分析,块设备驱动的分析以及网络设备驱动的分析。其中每一种类型的 驱动都是利用典型的实例来讲述,使读者充分了解驱动程序的实现思想;第三部分讲述 Qt GUI 开发,其中包括 Qt 的具体安装,Qt 的核心技术,以及最新的 Qtopia Core 开发环境,

最后利用实例来讲述 Qtopia Core 开发过程。总之,本书包括了嵌入式 Linux 系统移植,底 层驱动实例的讲解以及上层应用的实例讲述,针对那些想从事嵌入式开发或已经从事嵌入式 开发的读者来说无疑是一本难得的参考书籍。

前言:

嵌入式系统由于芯片、软件、网络和传感器等技术的不断发展,正在成为未来社会的“数 字基因”。如今,人类已经进入了后 PC 时代,嵌入式技术已被广泛应用于科学研究、工程 设计、军事技术以及文艺、商业等方方面面,成为后 PC 时代的主力军。与此同时,嵌入式 Linux 操作系统也在嵌入式领域蓬勃发展,它不仅继承了 Linux 源码开放,内核稳定性强,

软件丰富等特点,而且还支持几乎所有的主流处理器和硬件平台。嵌入式硬件系统和 Linux 系统的有机结合,成为后 PC 时代计算机最普遍的应用形式。嵌入式 Linux 技术在中国有巨 大的发展潜力和市场需求。有数据显示,未来两年里,在计算机、消费电子、通信、汽车电 子、工业控制和军事国防这六大主要应用领域,嵌入式 Linux 产品将达到 80 亿美元的市场 规模,可见这个行业的前景是非常乐观的。当然,Linux 嵌入式操作系统本身也有一定的局 限性,就是开发难度过高,对于企业需要很高的技术实力。这就要求 Linux 系统厂商们不光 要利用 Linux,更要掌握 Linux。此外,社会需要更多人加入到学习和使用 Linux 行业中来。

本书编写的目的:

嵌入式 Linux 属于一个交叉学科,并且也是一个高起点的学科,它涵盖了微电子技术、

电子信息技术、计算机软件和硬件等多项技术领域的应用。另外学习嵌入式 Linux 最好具备 相应的嵌入式开发板和软件,还需要有经验的人进行指导开发,目前国内大部分高校都很难 达到这种要求,这也造成了目前国内嵌入式 Linux 开发人才极其缺乏的局面。

很多希望学习嵌入式 Linux 的人已经具备了一定的硬件知识,并且对操作系统原理,数 据结构等都有相当的了解,但在 Linux 技术方面又是零起点。目前嵌入式 Linux 的书籍也是 非常之多,但大部分都是要求读者有一定的 Linux 使用基础,对于初学者来说真的非常困难。

写这本书的主要目的就是对那些没有 Linux 开发经验的初学者有个很好的指导参考作用,从 而让他们少走弯路。

其次,笔者希望通过写书来总结这几年在工作中的项目经验,与更多的读者分享自己的 技术,也是对自己的所做项目的一个巩固;通过写这本书,让笔者更加清楚了实践与理论之

(2)

间的联系,从而将自己的亲身经验和教训寄托在书中的每个章节。

本书的特点:

首先,本书涵盖了嵌入式 Linux 系统中最重要的三个部分:ARM Linux 系统移植,ARM Linux 驱动程序开发以及 Qt GUI 开发,这在同类书籍中比较少见。

其次,本书的讲述不依赖于具体某个厂家开发板,这样读者可以使用任意一款类似的开 发板就可以进行实践学习,同时对于没有开发板的读者也可以学到更多的知识。

另外,本书提供了书中出现的所有实例的源代码,便于读者参考使用,更重要的是读者 不用手动输入这些代码,从而节省时间。

本书的主要组成:

本书分为三个部分,共 12 章节,每一部分由 4 章内容组成。

第一部分讲述 ARM Linux 系统移植,首先第 1 章讲述嵌入式系统开发入门,主要针对 初学者,讲述嵌入式系统的概要,ARM 处理器,ADS 工具,Linux 开发环境,以及 Linux 内核源码等。接着第 2 章讲述交叉编译工具链的构建,主要讲述交叉工具链的作用,使用分 步法构建交叉工具链和使用 Crosstool 工具构建交叉工具链。第 3 章讲述嵌入式系统的 BootLoader,主要讲述嵌入式 BootLoader 的作用,基于 S3C2410 开发板的 U-Boot 分析与移 植以及自己设计 BootLoader 的方法。最后第 4 章讲述嵌入式 Linux 内核移植,主要讲述移 植的基本概念,内核配置、内核编译、内核下载以及构建根文件系统。

第二部分讲述 ARM Linux 驱动程序开发,首先第 5 章讲述 ARM Linux 驱动程序开发入 门,主要讲述嵌入式 Linux 驱动介绍,简单的内核模块程序分析,以及 Linux 驱动开发的基 本要点。接着第 6 章讲述字符设备驱动程序,主要讲述字符设备驱动相关的重要数据结构,

字符设备驱动开发实例——触摸屏设备驱动开发。第 7 章讲述块设备驱动程序,主要讲述块 设备相关的数据结构,块设备驱动开发实例——MMC/SD 设备驱动开发。最后第 8 章讲述 网络设备驱动程序,主要讲述网络设备驱动相关的重要数据结构,网络设备驱动开发实例—

—CS8900A 网卡驱动开发。

第三部分讲述 Qt GUI 开发,首先第 9 章介绍了 Qt 的概要知识,包括 Linux 桌面 GUI 系统,Qt/X11,Qtopia Core 等,使读者对 Qt 及其在 Linux GUI 系统中的作用有个大概了解。

紧接着第 10 章讲述了 Qt/X11 的安装以及非常详细的应用实例,使读者可以轻松的编写基本 的 Qt 程序。第 11 章深入讨论了一些 Qt 的核心技术,重点是以 Qt 对象模型为基础的信号和 槽等机制,我们通过剖析 Qt 的源代码来深入的学习 Qt 的这些核心技术,同时也为读者今后 对 Qt 源代码的自行研习打下基础。最后第 12 章重点讲述 Qtopia Core 和 Qt/X11 的一些不同 之处,包括轻量级的窗口系统,QCOP 进程间通信机制及调试工具 qvfb 等,使读者在熟悉 了 Qt/X11 的基础上能够很快过渡到 Qtopia Core 开发。

本书的读者对象:

本书通俗易懂,可作为高等院校电子类、电气类、控制类、计算机类等专业本科生、研 究生学习嵌入式 Linux 的参考书目或自学教材,也可供广大希望转入嵌入式领域的科研和工 程技术人员参考使用,还可作为广大嵌入式培训班的教材和教辅材料。

致谢:

(3)

首先要感谢这本书的另外一位作者欧文盛,书中 Qt GUI 部分(第 9 章到第 12 章)主要 由他来完成,由于他这几年一直在国际知名的通信公司从事 Qt 方面的开发工作,所以这部 分由他来完成,出版社和我都很放心。其次,我要感谢我的妻子,很特殊的是我写这本书的 时间正是我妻子怀孕的期间,其实在写这本书之前已经得知妻子怀孕,所以本想放弃编写这 本书,但是妻子却很坚定的支持我写这本书。所以,我认为这本书的完成离不开她对我的默 默支持。其次,要感谢我的岳父、岳母,是他们对我妻子这段时间的精心照顾,才使得我有 更多的时间投入到写书中。

最后,要感谢威盛电子的李松,易宏宇,周志勇,张磊等,他们为本书的完成也提供了 很多的帮助。

鉴于作者水平有限,加之时间仓促,本书一定有不少错误与不清楚之处,希望得到广大 读者批评与指正。有兴趣的读者可以发送 E-mail 到 [email protected] 或登录笔者的个 人 Blog 来做技术上的交流:http://mike2linus.blog.com.cn/。

作者

2007 年 3 月 28 日

(4)

第一部分 ARM LINUX 系统移植 ... 12

第 1 章 嵌入式系统开发入门... 13

1.1 嵌入式系统介绍 ... 13

1.1.1 嵌入式系统概述 ... 13

1.1.2 嵌入式系统组成 ... 15

1.2ARM 介绍... 16

1.2.1 ARM 处理器介绍 ... 17

1.2.2 ARM 处理器的选型 ... 18

1.2.3 S3C2410 微处理器介绍 ... 18

1.3ADS 集成开发环境介绍 ... 20

1.3.1 ADS 软件组成... 21

1.3.1.1 命令行开发工具...21

1.3.1.2 GUI 开发环境...23

1.3.1.3 实用程序 ...23

1.3.1.4 支持的软件 ...24

1.3.2 使用 Code Warrior IDE ... 24

1.3.2.1 创建项目工程...24

1.3.2.2 编译和链接项目工程...27

1.3.3 使用 AXD IDE... 29

1.3.3.1 打开调试文件...29

1.3.3.2 设置断点 ...30

1.3.3.3 查看寄存器内容...30

1.3.3.4 查看变量值 ...31

1.4 嵌入式 LINUX开发介绍 ... 32

1.4.1 Linux 历史... 32

1.4.2 Linux 开发环境 ... 33

1.4.2.1 GCC 介绍 ...35

1.4.2.2 GNU Make 介绍 ...36

1.4.2.3 GDB 介绍...38

1.4.3 ARM Linux 系统开发流程... 41

1.5LINUX内核介绍 ... 43

1.5.1 Linux 内核目录结构 ... 44

1.5.2 如何阅读 Linux 内核源代码 ... 45

1.6 本章小节... 47

1.7 常见问题 ... 48

第 2 章 交叉编译工具链的构建... 49

2.1 交叉编译工具链介绍... 49

2.2ARMLINUX交叉编译工具链的构建... 49

2.2.1 分步构建交叉编译链... 50

2.2.1.1 建立工作目录...50

2.2.1.2 建立环境变量...51

(5)

2.2.1.3 编译、安装 Binutils...51

2.2.1.4 获得内核头文件...52

2.2.1.5 编译安装 boot-trap gcc ...53

2.2.1.6 建立 glibc 库...54

2.2.1.7 编译安装完整的 gcc...55

2.2.1.8 测试交叉编译工具链 ...55

2.2.2 用 Crosstool 工具构建交叉工具链 ... 55

2.2.2.1 准备资源文件...56

2.2.2.2 建立脚本文件...56

2.2.2.3 建立配置文件...57

2.2.2.4 执行脚本 ...57

2.2.2.5 添加环境变量...57

2.3 本章小节 ... 58

2.4 常见问题 ... 58

第 3 章 嵌入式系统的 BOOTLOADER ... 60

3.1BOOTLOADER概述 ... 60

3.2 常用的嵌入式 LINUX BOOTLOADER... 61

3.2.1 U-Boot... 61

3.2.2 VIVI... 61

3.2.3 Blob... 62

3.2.4 RedBoot... 62

3.2.5 ARMboot ... 63

3.2.6 DIY... 63

3.3 基于 S3C2410 开发板的 BOOTLOADER实现 ... 63

3.3.1 S3C2410 开发板介绍 ... 63

3.3.2 U-Boot 分析与移植... 66

3.3.2.1 U-Boot Stage1 分析 ...66

3.3.2.2 U-Boot Stage2 分析 ...71

3.3.2.3 U-Boot 的移植过程 ...72

3.4 基于 S3C2410 开发板自己编写 BOOTLOADER... 88

3.4.1 设计系统的启动流程... 88

3.4.2 BootLoader 的具体实现... 90

3.4.2.1 设置异常向量表 ...91

3.4.2.2 初始化看门狗和外围电路...92

3.4.2.3 初始化存储器...92

3.4.2.4 初始化堆栈 ...93

3.4.2.5 初始化数据区...94

3.4.2.6 跳转到 C 程序 Main 函数...96

3.4.2.7 Main 函数的具体实现 ...96

3.5 本章小节 ... 97

3.6 常见问题 ... 97

第 4 章 嵌入式 LINUX 内核移植 ... 98

4.1 移植的基本概念 ... 98

(6)

4.2 内核移植的准备 ... 99

4.3 内核移植 ... 100

4.3.1 内核配置... 100

4.3.1.1 修改 Makefile ...100

4.3.1.2 设置 NAND Flash 分区 ...101

4.3.1.3 配置内核选项...104

4.3.2 内核编译... 108

4.3.2.1 清除冗余文件...108

4.3.2.2 编译内核映像和模块 ...108

4.3.2.3 安装模块 ...109

4.3.3 内核下载... 109

4.4 建立 LINUX根文件系统... 110

4.4.1 根文件系统的基本介绍... 110

4.4.1.1 根文件系统的基本目录结构 ...110

4.4.1.2 常见的根文件系统 ... 111

4.4.1.3 选择根文件系统...112

4.4.2 建立根文件系统 ... 113

4.4.2.1Cramfs 工具包的使用...113

4.2.2.2 构建 Cramfs 根文件系统 ...114

4.5 本章小节 ... 117

4.6 常见问题 ... 117

第二部分 ARM LINUX 设备驱动程序开发... 119

第 5 章 ARM LINUX 驱动程序开发入门 ... 120

5.1 嵌入式 LINUX驱动程序介绍... 120

5.1.1 驱动程序的作用 ... 120

5.1.2 Linux 设备驱动程序分类... 121

5.2 最简单的内核模块举例... 122

5.2.1 编写 Hello World 模块 ... 122

5.2.2 编写 Hello World 模块的 Makefile ... 124

5.2.3 加载和卸载 Hello World 模块... 125

5.3LINUX驱动程序开发要点... 125

5.3.1 内存与 I/O 端口... 125

5.3.1.1 内存...126

5.3.1.2 I/O 端口...129

5.3.2 并发控制... 130

5.3.2.1 自旋锁(Spinlocks)...131

5.3.2.2 信号量(Semaphores) ...133

5.3.3 阻塞(Blocking)与非阻塞(Nonblocking) ... 135

5.3.3.1 阻塞(Blocking)与非阻塞(Nonblocking)操作...135

5.3.3.2 异步通知(Asynchronous Notification)...135

5.3.4 中断处理... 136

5.3.4.1 Linux 中断及其相关函数 ...136

5.3.4.2 ARM 中断处理...137

(7)

5.3.4.3 一个 Linux 中断相关的实例...139

5.3.5 内核调试... 143

5.3.5.1 准备内核调试环境 ...143

5.3.5.2 KDB 的基本用法...144

5.4 本章小结 ... 146

5.5 常见问题 ... 147

第 6 章 字符设备驱动程序... 148

6.1 字符设备驱动介绍... 148

6.1.1 字符设备驱动相关的重要结构... 148

6.1.1.1 file_operations(文件操作)结构...148

6.1.1.2 file(文件)结构...151

6.1.1.3 inode(节点)结构 ...152

6.1.2 主、次设备号 ... 154

6.1.2.1 主、次设备号的内部表示...155

6.1.2.2 静态分配和释放主设备号...155

6.1.2.3 动态分配主设备号 ...156

6.2 字符设备驱动开发实例 ... 157

6.2.1 四线电阻式触摸屏原理... 157

6.2.2 S3C2410 触摸屏工作原理 ... 158

6.2.3 S3C2410 的 ADC 和触摸屏接口特殊寄存器 ... 159

6.2.3.1 ADC 控制(ADCCON)寄存器 ...159

6.2.3.2 ADC 触摸屏控制(ADCTSC)寄存器 ...160

6.2.3.3 ADC 开始延迟(ADCDLY)寄存器 ...161

6.2.3.4 ADC 转化数据 (ADCDAT0) 寄存器 ...161

6.2.3.5 ADC 转化数据(ADCDAT1)寄存器...162

6.2.4 触摸屏驱动概要设计... 162

6.2.4.1 触摸屏硬件接口...162

6.2.4.2 触摸屏驱动程序流程设计...163

6.2.5 触摸屏驱动程序分析... 164

6.2.5.1 触摸屏设备初始化 ...165

6.2.5.2 触摸屏设备文件操作 ...168

6.2.5.3 open 和 release 方法 ...168

6.2.5.4 read 和 poll 方法...169

6.2.5.5 触摸屏中断和 ADC 中断的实现 ...170

6.2.6 配置和编译驱动程序... 172

6.2.7 测试触摸屏驱动程序... 173

6.2.8 触摸屏的校准 ... 174

6.3 本章小节 ... 175

6.4 常见问题 ... 176

第 7 章 块设备驱动程序 ... 177

7.1 块设备驱动介绍 ... 177

7.1.1 块设备驱动相关的重要结构 ... 177

7.1.1.1block_device_operations(块设备操作)结构...177

(8)

7.1.1.2 gendisk 结构 ...178

7.1.1.3 request 结构...180

7.1.2 请求处理... 182

7.1.2.1 request 函数...182

7.1.2.2 request 函数实例 ...182

7.2 块设备驱动开发实例... 183

7.2.1 MMC/SD 介绍... 184

7.2.2 S3C2410 提供的 SDI 接口 ... 186

7.2.3 SDI 相关的寄存器 ... 187

7.2.3.1 SDI 控制(SDICON)寄存器 ...188

7.2.3.2 SDI 波特率预定标(SDIPRE)寄存器 ...188

7.2.3.3 SDI 命令参数(SDICARG)寄存器 ...188

7.2.3.4 SDI 命令控制(SDICCON)寄存器 ...189

7.2.3.5 SDI 命令状态(SDICSTA)寄存器 ...189

7.2.3.6 SDI 响应(SDIRSP)寄存器 ...189

7.2.3.7 SDI 数据/占用定时器(SDIDTIMER)寄存器...190

7.2.3.8 SDI 块大小(SDIBSIZE)寄存器...190

7.2.4 MMC/SD 驱动概要设计... 191

7.2.4.1 MMC/SD 与主机的接口连接 ...191

7.2.4.2 MMC/SD 驱动框架 ...191

7.2.4.3 MMC 驱动的核心设计...193

7.2.5 MMC 驱动程序分析 ... 193

7.2.5.1 MMC 初始化...193

7.2.5.2 open 和 release 方法 ...195

7.2.5.3 ioctl 方法 ...196

7.2.5.4 MMC 驱动的 request 方法...196

7.2.6 S3C2410 SDI 接口驱动分析 ... 198

7.2.6.1 SDI 初始化 ...199

7.2.6.2 SDI 接口驱动方法...199

7.2.7 配置和编译驱动程序... 200

7.3 本章小结 ... 200

7.4 常见问题 ... 200

第 8 章 网络设备驱动程序... 202

8.1 网络设备驱动介绍 ... 202

8.1.1 网络设备驱动相关的重要结构... 202

8.1.1.1 net_device 结构...202

8.1.1.2 sk_buff 结构 ...204

8.1.2 常见的网络术语 ... 205

8.1.2.1 常见的网络协议...205

8.1.2.2 以太网介绍 ...206

8.2 网络设备驱动开发实例... 207

8.2.1CS8900A 介绍... 207

8.2.1.1CS8900A 的组成部分介绍 ...207

8.2.1.2 CS8900A 的系统应用...208

(9)

8.2.2CS8900A 网卡驱动概要设计 ... 209

8.2.2.1 CS8900A 网卡接口 ...209

8.2.2.2 网络驱动程序的体系结构...209

8.2.2.3 网络驱动程序的主要功能...210

8.2.3 CS8900A 适配器驱动程序分析 ... 211

8.2.3.1 初始化...211

8.2.3.2 open 和 stop 方法...214

8.2.3.3 数据发送 ...216

8.2.3.4 数据接收 ...217

8.3 本章小结 ... 220

8.4 常见问题 ... 220

第三部分 QT GUI 开发 ... 221

第 9 章 QT 概述... 222

9.1LINUX下 GUI 介绍 ... 222

9.1.1 Linux 桌面 GUI 系统 ... 222

9.1.1.1 X Window 系统 ...223

9.1.1.2 GNOME/Gtk+和 KDE/Qt ...224

9.1.2 嵌入式 Linux 下的 GUI 系统 ... 226

9.2QT/X11 介绍 ... 227

9.2.1 Qt 的历史和 Qt/X11 的由来... 227

9.2.2 Qt/X11 的版权问题 ... 228

9.2.3 Qt/X11 及 Qt/Windows 的系统架构图对比... 228

9.2.4 Qt 的特性简介 ... 228

9.3QTOPIA CORE 介绍... 229

9.3.1 Qtopia Core 与 Qt/Embedded ... 229

9.3.2 Qtopia Core 的体系结构 ... 230

9.3.2.1 Frame Buffer(帧缓存)简介...230

9.3.2.2 Qtopia Core 的窗口系统 ...231

9.4 本章小结... 231

9.5 常见问题 ... 231

第 10 章 QT/X11 初步... 233

10.1QT/X11 的安装... 233

10.1.1 Qt/X11 的下载及双重授权问题的说明 ... 233

10.1.2 Qt/X11 的安装详解 ... 234

10.2QT下的 HELLO WORLD... 235

10.3温度转换的小例子... 237

10.3.1 背景知识... 237

10.3.2 Quit 按钮... 237

10.3.3 摄氏温度的显示 ... 241

10.3.4 华氏温度的显示 ... 243

10.3.5 华氏温度和摄氏温度之间的转换... 247

10.3.6 保存当前的数值 ... 251

(10)

10.4本章小结... 256

10.5常见问题... 257

第 11 章 QT 核心技术... 258

11.1 信号(SIGNALS)和槽(SLOTS)... 258

11.1.1 常见的 GUI 组件通信方式 ... 258

11.1.1.1 回调函数...258

11.1.1.2 面向对象的回调 ...260

11.1.2 Qt 中的信号和槽(Signals and Slots) ... 261

11.1.2.1 信号和槽历史和所带来的优点...261

11.1.2.2 信号 ...261

11.1.2.3 槽...262

11.1.2.4 信号和槽的效率 ...262

11.1.3 自定义信号和槽的小例子... 263

11.2QT对象模型... 266

11.2.1 元对象系统(Meta-Object System) ... 266

11.2.2 信号和槽机制的实现 ... 272

11.2.2.1 用 connection()建立连接...272

11.2.2.2 信号的发射和槽的执行 ...278

11.2.3 元对象编译器 moc ... 282

11.2.3.1 在 Makefile 中使用 moc...282

11.2.3.2 moc 用法详解 ...282

11.2.3.3 moc 及信号和槽机制的局限性...283

11.3QT的窗口系统... 285

11.3.1 窗口部件之间的树型结构... 285

11.3.2 窗口部件的布局管理(Layout) ... 288

11.4 国际化... 291

11.4.1 Qt 国际化的基本步骤 ... 291

11.4.1.1 程序员的工作 ...291

11.4.1.2 语言资源管理者和翻译工作者的工作...292

11.4.2 动态改变语言的小例子 ... 292

11.4.3 一些注意事项 ... 298

11.5 本章小结 ... 299

11.6 常见问题 ... 299

第 12 章 QTOPIA CORE ... 301

12.1QTOPIA CORE的安装 ... 301

12.2FRAME BUFFERQVFB... 302

12.2.1 Frame Buffer ... 302

12.2.2 编译 qvfb... 304

12.2.3 在 qvfb 上运行 Qtopia Core 程序 ... 305

# ./ DIGITALCLOCK –QWS –DISPLAY QVFB:0 ... 306

12.3移植 QT/X11 程序到 QTOPIA CORE中 ... 307

12.4 轻量级的窗口系统 ... 309

(11)

12.5进程间通信 ... 312

12.6本章小结... 315

12.7常见问题... 316

附录 A:光盘内容 ... 317

附录 B:参考文献 ... 317

(12)

第一部分 ARM Linux 系统移植

为了能让读者快速的了解嵌入式 ARM Linux 系统的开发过程,本书第一部分讲述 ARM Linux 的系统移植,这部分内容在实际工作中比较常见,是嵌入式 Linux 开发人员应该掌握 的技能。该部分由四章组成:第一章介绍 ARM 嵌入式 Linux 系统概述,作为嵌入式开发入 门的一章,非常适合初学者阅读,它包括嵌入式系统介绍,ARM 介绍,ADS 集成开发工具 介绍,嵌入式 Linux 开发介绍以及 Linux 内核介绍,对那些刚接触嵌入式 Linux 开发的读者 来说,通过本章学习将会对嵌入式 Linux 开发有个大概的了解和认识;第二章介绍交叉编译 工具链的制作,对于非 X86 硬件平台的设备开发通常使用交叉编译工具链在 X86 机器上进 行,该章内容是编译目标内核和程序的基础,它包括对交叉工具链的介绍,使用分步法构建 交叉工具链和使用 Crosstool 构建交叉工具链,通过本章学习,读者将会对交叉工具链有深 刻的认识以及可以构建自己的交叉工具链;第三章讲述 ARM Linux 的引导程序——

BootLoader,这是内核移植的关键,没有一个良好的 BootLoader 来引导内核工作,再强大、

稳定的内核也不能正常工作,它包括对 BootLoader 的介绍,U-boot 移植与分析以及讲述如 何自己设计 BootLoader。通过本章学习,读者将会对 BootLoader 的作用有更清楚的认识,

以及学会如何移植和设计 BootLoader;第四章讲述嵌入式 Linux 内核移植,也是实际工作中 非常重要的内容,它包括移植的基本概念,内核配置,内核编译,以及根文件系统的构建。

通过本章学习,读者将会对内核移植以及构建根文件系统有更深入的理解。

总之,读者通过对这部分内容的学习,将会了解构建嵌入式 Linux 系统所需要的一些工 作,比如交叉工具链,BootLoader,内核配置,内核编译等。

(13)

第 1 章 嵌入式系统开发入门

本章学习目标:

l 了解嵌入式系统基本概念 l 了解嵌入式系统的基本组成 l 了解 ARM 处理器的特点

l 学会使用 ADS 集成开发工具(Code Warrior 和 AXD)

l 熟悉 Linux 开发环境

l 学会如何有效阅读 Linux 内核代码

1.1 嵌入式系统介绍

本章作为 ARM Linux 系统移植的第一章,也是本书的第一章。俗话说说的好“良好的 开始是成功的一半”,虽然这句话并不是真理,但是希望读者在学习任何东西之前都应该有 坚定的学习态度和持之以恒的信念,同样学习本书也要有个良好的开端。首先介绍嵌入式系 统的概述。

1.1.1 嵌入式系统概述

随着嵌入式系统在消费类电子、工业控制、航空航天、汽车电子、医疗保健、网络通信 等各个领域的广泛应用,嵌入式系统这个名词已经被各行各业的人所熟悉, 嵌入式系统已 经走进了人们的生活。它正在以各种不同的形式悄悄地改变着人们的生产、生活方式。无庸 质疑,社会对嵌入式系统开发人员的需求也越来越大,所以现在越来越多的人已经加入到这 个行业中来。嵌入式系统,英文为 Embedded System,从广义上讲,凡是带有微处理器的专 用软、硬件系统都可称为嵌入式系统。如各类单片机和 DSP 系统,这些系统在完成较为单 一的专业功能时具有简洁高效的特点。但是由于他们没有使用操作系统,所以管理系统硬件 和软件的能力有限,在实现复杂的多任务功能时往往困难重重,甚至无法实现。从狭义上讲,

那些使用嵌入式微处理器构成的独立系统,并且有自己的操作系统,具有特定功能,用于特 定场合的系统。本书中所说的嵌入式系统是指狭义上的嵌入式系统。到目前为止,对于嵌入 式系统还没有一个明确的定义。嵌入式系统的核心是嵌入式微处理器,该处理器都是 RISC

(Reduce Instruction Set Computing,精简指令集计算机)*(注 1)的处理器内核。

*注 1:RISC 和 CISC(Complex Instruction Set Computing,复杂指令集计算机)是当前 CPU 的两种架构。它 们的区别在于不同的 CPU 设计理念和方法。早期的 CPU 全部是 CISC 架构,它的设计目的是要用最少的机 器语言指令来完成所需的计算任务。比如对于乘法运算,在 CISC 架构的 CPU 上,您可能需要这样一条指 令:MUL ADDRA, ADDRB 就可以将 ADDRA 和 ADDRB 中的数相乘并将结果储存在 ADDRA 中。将 ADDRA, ADDRB 中的数据读入寄存器,相乘和将结果写回内存的操作全部依赖于 CPU 中设计的逻辑来实 现。这种架构会增加 CPU 结构的复杂性和对 CPU 工艺的要求,但对于编译器的开发十分有利。比如 C 程 序中的 a*=b 就可以直接编译为一条乘法指令。今天只有 Intel 及其兼容 CPU 还在使用 CISC 架构。RISC 架 构要求软件来指定各个操作步骤。上面的例子如果要在 RISC 架构上实现,将 ADDRA, ADDRB 中的数据 读入寄存器,相乘和将结果写回内存的操作都必须由软件来实现,比如:MOV A, ADDRA; MOV B, ADDRB;

(14)

MUL A, B; STR ADDRA, A。这种架构可以降低 CPU 的复杂性以及允许在同样的工艺水平下生产出功能更 强大的 CPU,但对于编译器的设计有更高的要求。

嵌入式微处理器一般具备以下 4 个主要特点:

1. 对实时多任务有很强的支持能力,能完成多任务并且有较短的中断响应时间,从而 使内部的代码和实时内核的执行时间减少到最低限度。

2. 具有功能很强的存储区保护功能。这是由于嵌入式系统的软件结构已模块化,而为 了避免在软件模块之间出现错误的交叉作用,需要设计强大的存储区保护功能,同 时也有利于软件诊断。

3. 可扩展的处理器结构,以能最迅速地开展出满足应用的最高性能的嵌入式微处理 器。

4. 嵌入式微处理器必须功耗很低,尤其是用于便携式的无线及移动的计算和通信设备 中靠电池供电的嵌入式系统更是如此。

嵌入式处理器内核按照体系结构分类:

1. MIPS 处理器

MIPS 处理器是由美国 MIPS 公司研发出来的一套处理器体系,MIPS 公司是一家设 计制造高性能、高档次及嵌入式 32 位和 64 位处理器的厂商,在 RISC 处理器方面 占有重要地位。1984 年,MIPS 计算机公司成立。1992 年,SGI 收购了 MIPS 计算 机公司。1998 年,MIPS 脱离 SGI,成为 MIPS 技术公司。MIPS 公司设计 RISC 处 理器始于二十世纪八十年代初,1986 年推出 R2000 处理器,1988 年推 R3000 处理 器,1991 年推出第一款 64 位商用微处器 R4000。之后又陆续推出 R8000(于 1994 年)、R10000(于 1996 年)和 R12000(于 1997 年)等型号。随后,MIPS 公司的 战略发生变化,把重点放在嵌入式系统。1999 年,MIPS 公司发布 MIPS32 和 MIPS64 架构标准,为未来 MIPS 处理器的开发奠定了基础。新的架构集成了所有原来 NIPS 指令集,并且增加了许多更强大的功能。MIPS 公司陆续开发了高性能、低功耗的 32 位处理器内核(core)MIPS324Kc 与高性能 64 位处理器内核 MIPS64 5Kc。2000 年,MIPS 公司发布了针对 MIPS32 4Kc 的版本以及 64 位 MIPS 64 20Kc 处理器内核。

2. ARM 处理器

ARM(Advanced RISC Machines)处理器是由只设计内核的英国 ARM 公司研发出 来的一套处理器体系,ARM公司成立于 1990 年 11 月,其前身是 Acorn 计算机公司。

ARM 是微处理器行业的一家知名企业,设计了大量高性能、廉价、耗能低的 RISC 处理器、相关技术及软件。技术具有性能高、成本低和能耗省的特点。适用于多种 领域,比如嵌入控制、消费/教育类多媒体、DSP 和移动式应用等。ARM 将其技术 授权给世界上许多著名的半导体、软件和 OEM 厂商,每个厂商得到的都是一套独 一无二的 ARM 相关技术及服务。利用这种合伙关系,ARM 很快成为许多全球性 RISC 标准的缔造者。目前,总共有 30 家半导体公司与 ARM 签订了硬件技术使用 许可协议,其中包括 Intel、IBM、三星电子、LG 半导体、NEC、SONY、菲利浦和 国民半导体这样的大公司。至于软件系统的合伙人,则包括微软、升阳和 MRI 等 一系列知名公司。ARM 架构是面向低预算市场设计的第一款 RISC 微处理器。

3. PowerPC 处理器

二十世纪九十年代,IBM(国际商用机器公司)、Apple(苹果公司)和 Motorola(摩 托罗拉)公司开发 PowerPC 芯片成功,并制造出基于 PowerPC 的多处理器计算机。

PowerPC 架构的特点是可伸缩性好、方便灵活。第一代 PowerPC 采用 0.6 微米的生 产工艺,晶体管的集成度达到单芯片 300 万个。MPC860 和 MPC8260 是其最经典 的两款 PowerPC 内核的嵌入式处理器。

(15)

4. 68K/ColdFire 处理器

68K/ColdFire 处理器是 Motorola 公司独有的处理器体系。68K 内核是最早在嵌入式 领域广泛应用的内核。其最著名的代表芯片是 68360。Coldfire 继承了 68K 的特点 并继续兼容它。

由于嵌入式系统一般具有芯片集成度高,软件代码小,高度自动化,响应速度快等特点,

特别适合于要求实时性和多任务的体系。RTOS(Real-Time Operating System,实时操作系 统)是根据操作系统的工作特性而言的。实时是指物理进程的真实时间。实时操作系统是指 具有实时性,能支持实时控制系统工作的操作系统。首要任务是调度一切可利用的资源完成 实时控制任务,其次才着眼于提高计算机系统的使用效率,重要特点是要满足对时间的限制 和要求。一般 Windows、Unix、Linux 等桌面系统都属于分时操作系统,在此有必要说明一 下实时操作系统与分时操作系统的区别:具体的说,对于分时操作系统,软件的执行在时间 上的要求并不严格,时间上的错误,一般不会造成灾难性的后果。而对于实时操作系统,主 要任务是对事件进行实时的处理,虽然事件可能在无法预知的时刻到达,但是软件上必须在 事件发生时能够在严格的时限内作出响应,即使是在尖峰负荷下,也应该如此,系统时间响 应的超时就意味着致命的失败。另外,实时操作系统的重要特点是具有系统的可确定性,即 系统能对运行情况的最好和最坏等的情况能做出精确的估计。

到此为止,读者应该对嵌入式系统有了大概的了解,下面将介绍嵌入式系统的一般组成。

1.1.2 嵌入式系统组成

嵌入式系统一般由硬件平台和软件平台两部分组成,如下图 1.1 所示。其中硬件平台由 嵌入式微处理器和外围硬件设备组成,而软件平台由嵌入式操作系统和应用软件组成。

图 1.1 嵌入式系统的一般架构 应用程序

操作系统

存储器

处理器

输入 输出

软件平台

硬件平台

(16)

随着芯片技术的不断发展,嵌入式处理器的主频也越来越高,通常主频都在 40M Hz 以 上,有的甚至高达 500MHz。多处理器、多核处理器平台也逐渐应用在嵌入式领域,不过现 在大量使用的还是 32 位单处理器组成的平台。一个典型的硬件平台如图 1.2 所示[2]。

图 1.2 嵌入式硬件平台基本组成结构

嵌入式软件平台主要由嵌入式操作系统与应用软件组成。目前流行的嵌入式操作系统可 以分为两类:一类是从运行在个人电脑上的操作系统向下移植到嵌入式系统中,形成的嵌入 式操作系统,如微软公司的 Windows CE,SUN 公司的 Java 系统,朗讯科技公司的 Inferno,

嵌入式 Linux 等。这类系统经过个人电脑或高性能计算机等产品的长期运行考验,技术日 趋成熟,其相关的标准和软件开发方式已被用户普遍接受,同时积累了丰富的开发工具和应 用软件资源。另一类是实时操作系统,如 WindRiver 公司的 VxWorks,ISI 的 pSOS,QNX 系统软件公司的 QNX,ATI 的 Nucleus,中国科学院凯思集团的 Hopen 嵌入式操作系统等,

这类产品在操作系统的结构和实现上都针对所面向的应用领域,对实时性高可靠性等进行了 精巧的设计,而且提供了独立而完备的系统开发和测试工具,较多地应用在军用产品和工业 控制等领域中。目前常见的嵌入式系统有:Linux、uClinux、WinCE、PalmOS、Symbian、eCos、

uCOS-II、VxWorks、pSOS、Nucleus、ThreadX 、Rtems 、QNX、INTEGRITY、OSE、C Executive 等。嵌入式操作系统的发展也必将带动新一轮科技竞争。

应用程序运行在嵌入式操作系统之上,一般情况下应用程序和操作系统是分开的。当处 理器上带有 MMU(Memory Management Unit,存储器管理单元),它可以从硬件上将应用程 序和操作系统分开编译和管理,Linux、WinCE 就是这种分离机制。这样做的好处就是系统 安全性更高,可维护性更强,更有利于各功能模块的划分。很多情况下在没有 MMU 的处理 器,如 ARM7TDMI,经常应用程序和操作系统是编译在一起运行的,对于开发人员来说,

操作系统更像一个函数库。

1.2 ARM 介绍

ARM 是 Advanced RISC Machines(高级精简指令系统处理器)的缩写,它既是一种微 时钟

复位

中断控 制器

处理器 核

SDRAM 控制器

外部总线 控制器

SDRAM

其他外设

Flash

(17)

处理器知识产权(IP)核,也是一个公司的名称。在上节中对 ARM 公司有了大概的介绍,

这里就不再赘述,以下将介绍 ARM 处理器。

1.2.1 ARM 处理器介绍

ARM 处理器已经成功广泛地应用于无线通信、工业控制、消费类电子、网络产品等领 域,并且保持持续增长的势头。目前,基于 ARM 技术的微处理器应用约占据了 32 位 RISC 微处理器 75%以上的市场份额。采用 RISC 架构的 ARM 微处理器一般具有如下特点:

1. 体积小、低功耗、低成本、高性能;

2. 支持 Thumb(16 位)/ARM(32 位)双指令集,能很好的兼容 8 位/16 位器件;

3. 大量使用寄存器,指令执行速度更快;

4. 大多数数据操作都在寄存器中完成;

5. 寻址方式灵活简单,执行效率高;

6. 指令长度固定。

ARM 微处理器目前包括下面几个系列,每一个系列的 ARM 微处理器都有各自的特点 和应用领域。

² ARM7 系列:一般包括 ARM7TDMI、ARM7TDMI-S、ARM720T、ARM7EJ 几种内核。ARM7TDMI 是目前使用最广泛的 32 位嵌入式 RISC 处理器之一,

主要应用工业控制、Internet 设备、网络和调制解调器设备、移动电话等多种 多媒体和嵌入式应用。TDMI 的基本含义为:

T: 支持 16 为压缩指令集 Thumb;

D: 支持片上 Debug;

M:内嵌硬件乘法器(Multiplier)

I: 嵌入式 ICE,支持片上断点和调试点

² ARM9 系列:包含 ARM920T、ARM922T 和 ARM940T 三种类型,主要应用 于无线设备、仪器仪表、安全系统、机顶盒、高端打印机、数字照相机和数字 摄像机等。其中本书中介绍的 S3C2410 就是 ARM9 系列的 ARM920T 类型。

ARM9 具有以下特点:

l 5 级流水线,指令执行效率更高。

l 提供 1.1MIPS/MHz 的哈佛结构。

l 支持 32 位元 ARM 指令集和 16 位元 Thumb 指令集。

l 支持 32 位元的高速 AMBA 汇流排界面。

l 全性能的 MMU,支持 Windows CE、Linux、Palm OS 等多种主流嵌 入式操作系统。

l 支持数据 Cache 和指令 Cache,具有更高的指令和数据处理能力。

² ARM9E 系列:包含 ARM926EJ-S、ARM946E-S 和 ARM966E-S 三种类型。主 要应用于下一代无线设备、数字消费品、成像设备、工业控制、存储设备和网 络设备等领域。

² ARM10E 系列:包含 ARM1020E、ARM1022E 和 ARM1026EJ-S 三种类型。

主要应用于下一代无线设备、数字消费品、成像设备、工业控制、通信和信息 系统等领域。

² SecurCore 系列:包含 SecurCore SC100、SecurCore SC110、SecurCore SC200 和 SecurCore SC210 四种类型,主要应用于一些对安全性要求较高的应用产品 及应用系统,如电子商务、电子政务、电子银行业务、网络和认证系统等领域。

(18)

² Intel 的 Xscale:Xscale 处理器是基于 ARMv5TE 架构的解決方案,是一款全 性能、高成本效益比、低功耗的处理器。它支持 16 位的 Thumb 指令和 DSP 指令集,已使用在许多移动电话、个人数字助理和网络产品等场合。

² Intel 的 StrongARM:StrongARM SA-1100 处理器是采用 ARM 架构高度整合的 32 位元 RISC 微处理器。它融合了 Intel 公司的设计和处理技术以及 ARM 架 构的电源效率,采用在软件上相容 ARMv4 架构、同時采用具有 Intel 技术优 点的架构。Intel StrongARM 处理器是便携型通讯产品和消費类电子产品的理 想选择,已成功应用于多家公司的掌上电脑系列[3]。

其中,ARM7、ARM9、ARM9E 和 ARM10 为 4 个通用处理器系列,每一个系列提供一 套相对独特的性能来满足不同应用领域的需求。SecurCore 系列专门为安全要求较高的应用 而设计。Intel 的 Xscale 和 StrongARM 也是应用非常广泛的嵌入式处理器系列。

1.2.2 ARM 处理器的选型

基于 ARM 为内核的处理器已经越来越多,并且种类繁多,在选择开发基于 ARM 的嵌 入式系统时,首要任务就是选择 ARM 微处理器。下面讲述在选择 ARM 微处理器的一般准 则[3]。

1. ARM 微处理器内核的选择

Ø 如果使用 Windows CE 或标准 Linux 等操作系统,就需要选择 ARM720T 以上 带有 MMU 功能的 ARM 晶片。

Ø ARM720T、ARM920T、ARM922T、ARM946T、Strong-ARM 都带有 MMU 功能。

Ø 而 ARM7TDMI 则沒有 MMU,不支持 Windows CE 和标准 Linux,但目前有 uCLinux 等不需要 MMU 支持的操作系统可执行 ARM7TDMI 硬件平台。

2. 系统的工作频率

Ø 系统的工作频率在很大程度上決定了 ARM 微处理器的处理能力。

Ø ARM7 系列微处理器的典型处理速度为 0.9MIPS/MHz,常见的 ARM7 晶片系 统主时钟为 20MHz-133MHz。

Ø ARM9 系列微处理器的典型处理速度为 1.1MIPS/MHz,常见的 ARM9 的系统 主时钟为 100MHz-233MHz,ARM10 最高可以达到 700MHz。

3. 晶片內部存储体的容量

Ø 大多数的 ARM 微处理器晶片內部存储体的容量都不太大。

Ø 如 ATMEL 的 AT91F40162 就具有最高 2MB 的晶片內部存储空间。

4. 晶片內部周围电路选择

Ø 如 USB 接口、IIS 接口、IIC 接口、LCD 控制器、键盘接口、RTC、ADC 和 DAC、DSP 等,设计者应该分析系统的需求,尽可能采用晶片內部周围电路 完成所需的功能,这样既可以简化系统的设计,同时提高系统的可靠性。

除了上面介绍的四个方面准则之外,还有许多其它的因素考虑,比如价格、兼容性等等。

总之,根据设计的需求选择一款适合自己系统的 ARM 处理器是非常重要的。

1.2.3 S3C2410 微处理器介绍

S3C2410 是三星电子开发的一种 32 位 RISC 微处理器,它是基于 ARM920T 内核开发

(19)

的。S3C2410 是面向低价格、低功耗和高性能的手持设备和小型设备而设计。S3C2410 的具 体特点有以下[4]:

l 系统管理

Ø 支持小端/大端方式

Ø 地址空间:128M 字节每一个 Bank(总共 1G 字节)

Ø 每个 BANK 可编程为 8/16/32 位数据总线 Ø BANK0 到 BANK6 采用固定起始地址和大小 Ø BANK7 具有可编程的 BANK 起始地址和大小 Ø 共 8 个存储器 BANK

Ø 前 6 个存储器 BANK 用于 ROM、SRAM 和其他

Ø 另外两个存储器 BANK 用于 ROM、SRAM 和同步 DRAM Ø 支持等待信号用以延长总线周期

Ø 支持掉电时的 SDRAM 自刷新模式

Ø 支持不同类型的 ROM 引导(NOR/NAND Flash、EEPROM 和其他)。

l S3C2410 的 SoC 芯片集成单元

Ø 内部 1.8V,存储器 3.3V,外部 I/O3.3V,16KB 数据 CACHE,16KB 指令 CACHE,

MMU

Ø 内置外部存储器控制器(SDRAM 控制和芯片选择逻辑)

Ø LCD 控制器,一个 LCD 专用 DMA Ø 4 个带外部请求线的 DMA

Ø 3 个通用异步串行端口(IrDA1.0, 16-Byte Tx FIFO, and 16-Byte Rx FIFO),2 通道 SPI

Ø 一个多主 I2C 总线,一个 I2S 总线控制器

Ø SD 主接口版本 1.0 和多媒体卡协议版本 2.11 兼容 Ø 两个 USB HOST,一个 USB DEVICE(VER1.1)

Ø 4 个 PWM 定时器和一个内部定时器 Ø 看门狗定时器

Ø 117 个通用 I/O Ø 24 个外部中断

Ø 电源控制模式:标准、慢速、休眠、掉电 Ø 8 通道 10 位 ADC 和触摸屏接口

Ø 带日历功能的实时时钟 Ø 芯片内置 PLL

Ø 设计用于手持设备和通用嵌入式系统

Ø 16/32 位 RISC 体系结构,使用 ARM920T CPU 核的强大指令集 Ø 带 MMU 的先进的体系结构支持 WinCE、EPOC32、Linux

Ø 指令缓存(CACHE)、数据缓存、写缓冲和物理地址 TAG RAM,减小了对主存储 器带宽和性能的影响

Ø ARM920T CPU 核支持 ARM 调试的体系结构

Ø 内部先进的位控制器总线(AMBA)(AMBA2.0,AHB/APB)

其中,S3C2410 的芯片结构图 1.3 所示:

(20)

图 1.3 S3C2410 芯片结构

1.3 ADS 集成开发环境介绍

ADS 全称为 ARM Developer Suite,是 ARM 公司推出的新一代 ARM 集成开发工具。

现在 ADS 的最新版本是 1.2,它取代了早期的 ADS1.1 和 ADS1.0。在 ADS 工具诞生之前,

一直使用的是 ARM SDT 工具,目前 ARM SDT 工具已经慢慢被淘汰。ADS 除了可以安装 在 Windows NT4,Windows 2000,Windows 98 和 Windows 95 操作系统下,还支持 Windows XP 和 Windows Me 操作系统。

(21)

1.3.1 ADS 软件组成

ADS 由命令行开发工具,GUI(Graphics User Interface,图形用户界面)开发环境(Code Warrior 和 AXD),实用程序和支持软件组成。有了这些部件,用户就可以为 ARM 系列的 RISC 处理器编写和调试自己的开发应用程序了。下面将分别介绍这四个组成部分。

1.3.1.1 命令行开发工具

命令行开发工具在实际应用中相对比较广泛,用其最大的好处就是可以将许多编译命令 写在一个脚本文件中,然后只执行该脚本文件就可以让工具自动完成所有编译的工作。命令 行中常用的命令如下:

Ø armcc

armcc 是 ARM C 编译器。这个编译器通过了 Plum Hall C Validation Suite 为 ANSI C 的一致性测试。armcc 用于将用 ANSI C 编写的程序编译成 32 位 ARM 指令代码。

在命令控制台环境下,输入以下命令:

> armcc –help

将可以查看 armcc 的语法格式以及最常用的一些操作选项 armcc 最基本的用法为:

> armcc [options] file1 file2 ... filen

这里的 option 是编译器所需要的选项,fiel1,file2…filen 是相关的文件名。

以下简单介绍一些最常用的操作选项:

-c:表示只进行编译不链接文件;

-C:(注意:这是大写的 C)禁止预编译器将注释行移走;

-D<symbol>:定义预处理宏,相当于在源程序开头使用了宏定义语句 -E:仅仅是对 C 源代码进行预处理就停止;

-g<options>:指定是否在生成的目标文件中包含调试信息表;

-I<directory> : 将 directory 所 指 的 路 径 添 加 到 #include 的 搜 索 路 径 列 表 中 去 ; -J<directory>:用 directory 所指的路径代替默认的对#include 的搜索路径;

-o<file>:指定编译器最终生成的输出文件名。

-O0:不优化;

-O1:这是控制代码优化的编译选项,大写字母 O 后面跟的数字不同,表示的优化级别 就不同,-O1 关闭了影响调试结果的优化功能;

-O2:该优化级别提供了最大的优化功能;

-S:对源程序进行预处理和编译,自动生成汇编文件而不是目标文件;

-U<symbol>:取消预处理宏名,相当于在源文件开头,使用语句#undef symbol;

-W<options>:关闭所有的或被选择的警告信息;

有关更详细的选项说明,读者可查看 ADS 软件的在线帮助文件。

Ø armcpp

armcpp 是 ARM C++编译器。它将 ISO C++ 或 EC++ 编译成 32 位 ARM 指令代码。该 编译器的命令选项和 armcc 的选项基本一样,这里就不再重复。

Ø tcc

tcc 是 Thumb C 编译器。该编译器通过了 Plum Hall C Validation Suite 为 ANSI 一致性 的测试。tcc 将 ANSI C 源代码编译成 16 位的 Thumb 指令代码。同时它的编译选项和用法

(22)

类似 armcc,具体使用请参考 ADS 软件的在线帮助文件。

Ø tcpp

tcpp 是 Thumb C++ 编译器。它将 ISO C++ 和 EC++ 源码编译成 16 位 Thumb 指令代 码。同时它的编译选项和用法类似 armcc,具体使用请参考 ADS 软件的在线帮助文件。

Ø armasm

armasm 是 ARM 和 Thumb 的汇编器。它对用 ARM 汇编语言和 Thumb 汇编语言写的 源代码进行汇编。在命令行输入:armasm –help 将会看到 armasm 汇编器的用法以及它的编 译选项。

> armasm [options] sourcefile objectfile

> armasm [options] -o objectfile sourcefile

上述是关于 armasm 两种基本用法,其中 options 为它的选项,常用的选项如下:

-LIST:写一个列表文件在指定的文件 -Depend:保存编译后的依赖源文件

-Errors:将标准出错的诊断信息放到指定的文件中 -I:添加目录到源文件的搜索路径

-PreDefine:预执行一个 SET{L,A,S}指令 -NOCache:源缓冲关(默认是开)

-MaxCache:定义最大缓冲的大小(默认是 8M)

-NOWarn:关闭打印告警信息 -G:输出调试表

-APCS:使预定义匹配已选择 proc-call 标准 -Help:打印帮助信息 -LIttleend: Little-endian ARM

-BIgend:Big-endian ARM

-MEMACCESS:说明目标内存系统的属性

-M:写源文件依赖性列表到标准输出 -MD:写源文件依赖性列表到标准输入

-CPU:设置目标 ARM 内核类型

-FPU:设置目标 FP 体系版本,SOFTVFP, SOFTFPA, VFP, FPA, NONE 之一 -16:汇编 16 位 Thumb 指令

-32:汇编 32 位 ARM 指令 Ø armlink

armlink 是 ARM 链接器。该命令既可以将编译得到的一个或多个目标文件和相关的一 个或多个库文件进行链接,生成一个可执行文件,也可以将多个目标文件部分链接成一个目 标文件,以供进一步的链接。ARM 链接器生成的是 ELF 格式的可执行映像文件。armlink 的一般用法如下:

> armlink option-list input-file-list

其中,option-list:是一个区分大小写的选项表;input-file-list:是一系列库和对象文件。关 于 armlink 的具体使用请参考 ADS 软件的在线帮助文件。

Ø armsd

armsd 是 ARM 和 Thumb 的符号调试器。它能够进行源码级的程序调试。用户可以在 用 C 或汇编语言写的代码中进行单步调试,设置断点,查看变量值和内存单元的内容。armsd 的一般用法如下:

> armsd [options] [<imagefile> [<arguments>]]

(23)

其中,options:是一系列调试选项;imagefile:定义一个 AIF 或 ELF 文件的名字;arguments:

是被 imagefile 接受的命令行参数。关于 armsd 的具体使用请参考 ADS 软件的在线帮助文件。

讲到这里我们可以举一个简单的应用实例,来看看关于常用的 ARM 命令行是如何使用 的。以附件光盘中的 SWI(Sotfware Interrupter)参考项目为例,它的编译命令如下:

armasm -g a_swi.s armcc -c -g -O1 main.c armcc -c -g -O1 c_swi.c

armlink a_swi.o main.o c_swi.o -o swi.axf

其中,armasm 命令用来编译 ARM 汇编代码,armcc 用来编译 C 代码,armlink 用来最 终链接目标文件为 ELF 格式的可执行映像文件。

1.3.1.2 GUI 开发环境

ADS GUI 开发环境包含 Code Warrior 和 AXD 两种,其中 Code Warrior 是集成开发工具,

而 AXD 是调试工具。下面将分别介绍这两个工具。

CodeWarrior for ARM 是一套完整的集成开发工具,充分发挥了 ARM RISC 的优势, 使 产品开发人员能够很好的应用尖端的片上系统技术。该工具是专为基于 ARM RISC 的处理 器而设计的,它可加速并简化嵌入式开发过程中的每一个环节,使得开发人员只需通过一个 集成软件开发环境就能研制出 ARM 产品,在整 个开发周期中,开发人员无需离开 CodeWarrior 开发环境,因此节省了在操做工具上花的时间,使得开发人员有更多的精力投 入到代码编写上来,CodeWarrior 集成开发环境(IDE)为管理和开发项目提供了简单多样化的 图形用户界面。用户可以使用 ADS 的 CodeWarrior IDE 为 ARM 和 Thumb 处理器开发用 C,

C++,或 ARM 汇编语言的程序代码。CodeWarrior IDE 缩短了用户开发项目代码的周期,主 要是由于:一是全面的项目管理功能,二是子函数的代码导航功能,使得用户迅速找到程序 中的子函数。关于 CodeWarrior 的具体使用将在下一节中具体介绍。

AXD(ARM eXtended Debugger),即 ARM 扩展调试器。调试器本身是一个软件,用户 通过这个软件使用调试代理可以对包含有调试信息的,正在运行的可执行代码进行比如变量 的查看,断点的控制等调试操作。调试代理既不是被调试的程序,也不是调试器。在 ARM 体系中,它有这几种方式:Multi-ICE(Multi-processor in-circuit emulator),ARMulator 和 Angel。

其中 Multi-ICE 是一个独立的产品,是 ARM 公司自己的 JTAG 在线仿真器,不是由 ADS 提 供的。AXD 可以在 Windows 和 UNIX 下,进行程序的调试。它为用 C,C++,和汇编语言 编写的源代码提供了一个全面的 Windows 和 UNIX 环境。后面的章节会具体介绍 AXD 工 具的使用方法。

1.3.1.3 实用程序

ADS 除了提供上述工具外,它还提供以下的实用工具来配合前面介绍的命令行开发工 具的使用。

Ø Flash downloader

用于把二进制映像文件下载到 ARM 开发板上的 Flash 存储器的工具 Ø fromELF

这是 ARM 映像文件转换工具。该命令将 ELF 格式的文件作为输入文件,将该格式转 换为各种输出格式的文件,包括 plain binary(BIN 格式映像文件), Motorola 32-bit S-record

(24)

format(Motorola 32 位 S 格式映像文件),Intel Hex 32 format(Intel 32 位格式映像文件),和 Verilog-like hex format(Verilog 16 进制文件)。fromELF 命令也能够为输入映像文件产生文本 信息,例如代码和数据长度。

Ø armar

ARM 库函数生成器将一系列 ELF 格式的目标文件以库函数的形式集合在一起,用户可 以把一个库传递给一个链接器以代替几个 ELF 文件。

1.3.1.4 支持的软件

ADS 为用户提供 ARMulator 软件,使用户可以在软件仿真的环境下或者在基于 ARM 的硬件环境调试用户应用程序。ARMulator 是一个 ARM 指令集仿真器,集成在 ARM 的调 试器 AXD 中,它提供对 ARM 处理器的指令集的仿真,为 ARM 和 Thumb 提供精确的模拟。

用户可以在硬件尚未做好的情况下,开发程序代码。

关于 ADS 软件主要由上述四个部分组成,下面将介绍在实际工作中经常用到的 Code Warrior 和 AXD 工具的基本使用。

1.3.2 使用 Code Warrior IDE

Code Warrior IDE 提供一个简单通用的图形化用户界面用于管理软件开发项目。可以利 用 Code Warrior IDE 开发 C,C++和 ARM 汇编代码以 ARM 和 Thumb 处理器为对象。下面 将通过一个实例来讲述 Code Warrior IDE 的具体使用,为了使读者容易理解,这里还是以附 件光盘中提供的 SWI 项目为例,讲述 Code Warrior IDE 工具的使用。

1.3.2.1 创建项目工程

建立项目工程是嵌入式实际开发中必不可少的一部分,因为工程将所有的源码文件组织 在一起,并能够决定最终生成文件存放的路径,输出的格式等。在 CodeWarrior 中新建一个 工程的方法有两种,可以在工具栏中单击“New”按钮,也可以在“File”菜单中选择“New…”

菜单。这样就会打开一个如图 1.4 所示的对话框。

(25)

图 1.4 新建工程对话框

在 Project 可选框中为用户提供了 7 种可选择的工程类型,分别是:

Ø ARM Executable Image:用于由 ARM 指令的代码生成一个 ELF 格式的可执行映像文件;

Ø ARM Object Library:用于由 ARM 指令的代码生成一个 armar 格式的目标文件库;

Ø Empty Project:用于创建一个不包含任何库或源文件的工程;

Ø Makefile Importer Wizard:用于将 Visual C 的 nmake 或 GNU make 文件转入到 CodeWarrior IDE 工程文件;

Ø Thumb ARM Interworking Image:用于由 ARM 指令和 Thumb 指令的混和代码生成一个 可执行的 ELF 格式的映像文件;

Ø Thumb Executable image:用于由 Thumb 指令创建一个可执行的 ELF 格式的映像文件;

Ø Thumb Object Library:用于由 Thumb 指令的代码生成一个 armar 格式的目标文件库。

在这里选择 ARM Executable Image,然后在“Project name:”里输入名为 swi 的工程文 件名。接着在“Location:”项中点击“Set…”按钮选择项目工程存放的位置,这里存放的 位置为 C:\TestCode。最后点击“确定”,即可建立一个新的名为 swi 的工程。

这个时候会出现 swi.mcp 的窗口,如图 1.5 所示,有三个标签页,分别为 files,link order,

target 默认的是显示第一个标签页 files。通过在该标签页点击鼠标右键,选中“Add Files…”

可以把要用到的源程序添加到工程中。

(26)

图 1.5 添加源文件到工程中

为工程添加源码常用的方法有两种,既可以使用入图 1.5 所示方法,也可以在“Project”

菜单项中,选择“Add Files…”,这两种方法都会打开文件浏览框,用户可以把已经存在的 文件添加到工程中来。当选中要添加的文件时,会出现一个对话框,如图 1.6 所示,询问用 户把文件添加到何类目标中,在这里,我们选择 DebugRel 目标。这里我们添加了 swi.h,a_swi.s c_swi.s 和 main.c 文件。

在建立好一个工程时,默认的 target 是 DebugRel,还有另外两个可用的 target,分别为 Realse 和 Debug,这三个 target 的含义分别为:

DebugRel:使用该目标,在生成目标的时候,会为每一个源文件生成调试信息;

Debug:使用该目标为每一个源文件生成最完整的调试信息;

Release:使用该目标不会生成任何调试信息。

(27)

图 1.6 选择生成目标类型

到目前为止,一个完整的名为 swi 的项目工程已经建立,下面该对工程进行编译和链接 工作。

1.3.2.2 编译和链接项目工程

在编译 swi 项目之前,先进行设置,点击 Edit 菜单,选择“DebugRel Settings…”,或 者按 Alt + F7 快捷键,显示如图 1.7 对话框。

图 1.7 DebugRel 设置对话框

图 1.7 的最左边部分是目标设置面板,它包括如下几个大的设置对象:

Ø Target 设置选项

Target Settings:包括 Target Name,Linker,Pre-linker 和 Post-linker 等设置。

(28)

Access Paths:主要是用于项目的路径设置。

Build Extras:主要用于 Build 附加的选项设置。

Runtime Settings:包括一般设置、环境设置等。

File Mappings:包含映射信息,文件类型,编辑语言等。

Source Trees:包含源代码树结构信息,以及路径选择等。

ARM Target:定义输出 image 文件名和类型等。

Ø Language Settings 设置选项

ARM Assembler:对 ARM 汇编语言的支持选项设置。

ARM C Compiler:对 C 语言的支持选项设置。

ARM C++ Compiler:对 C++语言的支持选项设置。

Thumb C Compiler:对 Thumb C 语言的支持选项设置。

Thumb C++ Compiler:对 Thumb C++语言的支持选项设置。

Ø Linker 设置选项

ARM Linker:对输出的链接类型、RO、RW Base 地址设置等选项。

ARM fromELF:定义输出文件格式以及路径等。

Ø Edit 设置选项

Custom Keywords:对客户化关键字高亮颜色的设置。

Ø Debugger 设置选项

Other Executables:制定其他的可执行文件来调试当调试该目标板时。

Debugger Settings:对调试器的一些基本设置。

ARM Debugger:选择调试时调试器(AXD,Armsd 和其他等)的选择。

ARM Runner:选择运行时的调试器(AXD,Armsd 和其他等)的选择。

Ø Miscellaneous 设置选项

ARM Features:设置一些受限制的特性。

接下来点击 CodeWarrior IDE 的菜单 Project 下的 make 菜单,就可以对 swi 工程进行编 译和链接了。整个编译链接之后生成如图 1.8 所示:

图 1.8 编译和链接的之后

(29)

在工程 swi 所在的目录下,会生成一个名为:工程名_data 的目录,即 swi_data 的目录,

在这个目录下不同类别的目标对应不同的目录。在本例中由于我们使用的是 DebugRe 目标,

所以生成的最终文件都应该在该目录下。进入到 DebugRel 目录中去,读者会看到 make 后 生成的映像文件和二进制文件,映像文件用于调试,二进制文件可以烧写到目标板的 Flash 中运行。关于 Code Warrior IDE 的具体使用请参考 ADS 软件的在线帮助文件。

1.3.3 使用 AXD IDE

AXD 是 ADS 软件中独立于 CodeWarrior IDE 的图形软件,打开 AXD 软件,默认是打 开的目标是 ARMulator。ARMulator 也是调试的时候最常用的一种调试工具,本节主要是结 合 ARMulator 介绍在 AXD 中进行代码调试的方法和过程,使读者对 AXD 的调试有初步的 了解。要使用 AXD 必须首先要生成包含有调试信息的程序,在上节中,已经生成的 swi.axf 文件就是含有调试信息的可执行 ELF 格式的映像文件。这一节还是以 swi 工程为例讲述 AXD 调试工具的基本用法。

1.3.3.1 打开调试文件

在菜单 File 中选择“Load image…”选项,打开 Load Image 对话框,找到要装载的.axf 映像文件,点击“打开”按钮,就把映像文件装载到目标内存中了。在所打开的映像文件中 会有一个蓝色的箭头指示当前执行的位置。如图 1.9 所示:

图 1.9 打开 swi 调试文件

此外,在菜单 File 中还有一个“Load Debug Symbols.…”选项,该选项是用来调式那些 调试器不能访问调试符号的情况,比如调试装载在 ROM 中的 image。通常“Load image…”

(30)

选项用来调试装载在 RAM 中的代码。

在菜单 Execute 中选择“Go”,将运行代码。要想进行单步的代码调试,在 Execute 菜 单中选择“Step”选项,或用 F10 即可以单步执行代码,窗口中蓝色箭头会发生相应的移动。

1.3.3.2 设置断点

有时候,用户可能希望程序在执行到某处时,查看一些所关心的变量值,此时可以通过 设置断点达到此要求。将光标移动到要进行断点设置的代码处,在 Execute 菜单中,选择

“Toggle Breakpoint”或按 F9,就会在光标所在行的起始位置出现一个红色实心圆点,表明 该处为已设为断点。假设本例中给 62 行代码设置断点,首先将光标移至 62 行,然后按 F9 或点击“Toggle Breakpoint”按钮,此时如图 1.10 所示:

图 1.10 设置断点

1.3.3.3 查看寄存器内容

查看寄存器的值在实际嵌入式开发调试中经常使用,使用方法:从 Processor Views 菜 单中选择“Memory”选项,如图 1.11 所示。在 Memory Start address 选择框中,用户可以根 据要查看的存储器的地址输入起始地址,在下面的表格中会列出连续的 64 个地址。从图 1.11 中可以看出地址为 0x0 的存储器中的初始值为 0x E7FF0010,注意因为用的是 little-endian*

(注 2),所以读数据的时候注意高地址中存放的是高字节,低地址存放的是低字节。

*注 2:Big-endian 和 Little-endian 是用来表述一组有序的字节数存放在计算机内存中时的顺序的术语。

Big-endian 是将高位字节(序列中最重要的值)先存放在低地址处的顺序,而 Little-endian 是将低位字

(31)

节(序列中最不重要的值)先存放在低地址处的顺序。举例来说,在使用 Big-endian 顺序的计算机中,要 存储一个十六进制数 5F48 所需要的字节将会以 5F48 的形式存储(比如 5F 存放在内存的 1000 位置,而 48 将会被存储在 1001 位置)。而在使用 Little-endian 顺序的系统中,存储的形式将会是 485F(48 在地址 1000 处,5F 在地址 1001 处)。如果将 0x5F48 写到以 0x0000 开始的地址中,则存放的顺序如下:

地址 Big-endian Little-endian 0x0000 5F 48 0x0001 48 5F

IBM 的 370 种大型机、大多数基于 RISC 的计算机以及 Motorola 的微处理器使用的是 Big-endian 顺序,TCP/IP

协议也是。而 Intel 的处理器和 DEC 公司的一些程序则使用的 Little-endian 方式。

图 1.11 查看寄存器值

1.3.3.4 查看变量值

在调试过程中,经常需要查看某个变量的值,在 AXD 工具中,查看变量值的方法是:

先用鼠标选中要查看的变量,然后鼠标右击,在探出的对话框中选择“Watch..”,将会显示 指定变量的详细信息。此处以 62 行的 res_3 为要查看的变量,先选中 res_3 变量,然后鼠标 右击,选择“Watch..”项,将弹出如图 1.12 的对话框,该对话框显示了 res_3 变量的地址和 值等详细信息。

(32)

图 1.12 查看变量对话框

总之,AXD 工具的使用方法还有很多,关于 AXD IDE 的具体使用请参考 ADS 软件的 在线帮助文件,这里不再赘述。

1.4 嵌入式 Linux 开发介绍

在这一节中主要讲述 Linux 开发的基础知识,其中包括 Linux 的发展历史,Linux 的开 发环境和 ARM Linux 系统的开发流程,首先让我们来看一下 Linux 的发展历史。

1.4.1 Linux 历史

Linux 是 Unix 操作系统的一个克隆,由名叫 Linus Torvalds 的大学生在 1991 年开发诞 生的。Linus Torvalds 将他写的操作系统源代码放在了 Internet 上,受到很多计算机爱好者的 热烈欢迎,并且这些计算机爱好者不断地添加新的功能和特性,并不断的提高它的稳定性。

在 1994 年,Linux 1.0 正式发布。现在,Linux 已经成为一个功能超强的 32 位操作系统。Linux 为嵌入操作系统提供了一个极有吸引力的选择,它是个和 Unix 相似、以核心为基础的、完 全内存保护、多任务多进程的操作系统。支持广泛的计算机硬件,包括 X86,Alpha,Sparc,

MIPS,PPC,ARM,NEC,MOTOROLA 等现有的大部分芯片。源代码全部公开,任何人 可以修改并在 GNU 通用公共许可证(GNU General Public License)下发行,这样开发人员可 以对操作系统进行定制。同时由于有 GPL 的控制,大家开发的东西大都相互兼容,不会走 向分裂之路。Linux 用户遇到问题时可以通过 Internet 向网上成千上万的 Linux 开发者请教,

这使得最困难的问题也有办法解决。Linux 带有 Unix 用户熟悉的完善的开发工具,几乎所 有的 Unix 系统的应用软件都已移植到了 Linux 上。Linux 还提供了强大的网络功能,有多种 可选择窗口管理器(X windows)。其强大的语言编译器 gcc、g++等也可以很容易得到。不 但成熟完善、而且使用方便。

关于嵌入式 Linux 的发展也如同 Linux 发展一样非常迅速,在 1999 年,Linux 开始根植

數據

表 7-1MMC 总线信号连接说明  MMC模式  SPI模式 管 脚 号  名字  类型  *(注1)  描述  名字  类型    描述  1  RSV  NC  保留  CS  I  芯片选择  2  CMD  I/O/PP/OD  命令/响应  DI  I/PP  数据输入  3  V SS1  S  供电接地  V SS S  供电接地  4  V DD  S  供电  V DD  S  供电  5  CLK  I  时钟  SCLK  I  时钟  6  V SS2  S  供电接地  V SS
表 7-4SD 卡寄存器

參考文獻

相關文件

GBytes 1024 MBytes P9-編號 2 資料磁區在 Linux 之作業系統

在現行的 99

使用 BibTEX 的 L A TEX 文件, 編譯過程有時有點讓人困惑。我們這裡假設以 foo.tex 為我們的 L A TEX 檔 (BibTEX 檔叫什麼無妨, 只要我們在文中引用

本書立足中華文化大背景,較為深入系統地分析研究了回族傳統法文化的形成基礎、發展歷

命令解釋程式 作業系統 (MS-DOS,UNIX, WINDOWS 98/NT, 2000, XP, LINUX).

 中国的高速铁路,是目前世界上最长、以及最快的高 速铁路系统 。现已建成四条横贯东西和四条纵贯南 北的高铁线路

智慧型手機是一種運算能力及功能比傳統手機更強的手機。 通常使用的作 業系統有: Symbian 、 Windows Mobile 、 iOS 、 Linux (含 Android 、 Maemo 和 WebOS) 、.. Palm

由於 Android 作業系統的開放性和可移植性,它可以被用在大部分電子產品 上,Android 作業系統大多搭載在使用了 ARM 架構的硬體設備上使裝置更加省電