嵌入式 Linux 起步

130
嵌嵌嵌 嵌嵌嵌 Linux Linux 嵌嵌 嵌嵌 嵌嵌嵌 嵌嵌嵌 嵌嵌嵌 嵌嵌嵌 www.farsight. www.farsight. com.cn com.cn

description

嵌入式 Linux 起步. 主讲人:孙天泽 www.farsight.com.cn. Outline. 认识并熟练使用 Linux 操作系统 了解并搭建嵌入式 Linux 初识 BootLoader 了解并编译 Linux 内核 编写和调试嵌入式 Linux 程序 编写 Linux 设备驱动程序. 体会. 享受. 回味. Outline of Lab. 安装 Linux 操作系统 交叉编译 编译并下载 U-Boot 编译并下载 Linux 内核 挂载 NFS 文件系统 编写 Linux 驱动程序. PART 1. - PowerPoint PPT Presentation

Transcript of 嵌入式 Linux 起步

Page 1: 嵌入式 Linux 起步

嵌入式嵌入式 LinuxLinux 起步起步

主讲人:孙天泽主讲人:孙天泽 www.farsiwww.farsight.com.cnght.com.cn

Page 2: 嵌入式 Linux 起步

远见品质 Outline1. 认识并熟练使用 Linux 操作系统2. 了解并搭建嵌入式 Linux

3. 初识 BootLoader

4. 了解并编译 Linux 内核5. 编写和调试嵌入式 Linux 程序6. 编写 Linux 设备驱动程序

•体会

•享受•回味

Page 3: 嵌入式 Linux 起步

远见品质 Outline of Lab

1. 安装 Linux 操作系统2. 交叉编译3. 编译并下载 U-Boot

4. 编译并下载 Linux 内核5. 挂载 NFS 文件系统6. 编写 Linux 驱动程序

Page 4: 嵌入式 Linux 起步

远见品质 PART 1

认识并熟练使用 Linux 操作系统

Page 5: 嵌入式 Linux 起步

远见品质 Linux 简介姓名: Linux生日: 1991 年 10 月父亲: Linus Torvalds 堂兄: UNIX国别: 芬兰家庭住址: http://www.linux.org/吉祥物 :

Page 6: 嵌入式 Linux 起步

远见品质 Linux 关键字点击社团( Community )免费( Free )开放( open )易获得( available )稳定( stable )健壮( robust ) GPL ( General Public License )软件( software )

Page 7: 嵌入式 Linux 起步

远见品质 常用网址

Page 8: 嵌入式 Linux 起步

远见品质 Linux 的安装

•FOLLOW ME…

Page 9: 嵌入式 Linux 起步

远见品质 Linux 的启动过程

Page 10: 嵌入式 Linux 起步

远见品质 Linux 的基本命令ls 列出目录和文件cd 转换目录cp 复制文件rm 删除文件mkdir 创建目录rmdir 删除目录mv 移动文件man 获得帮助

Page 11: 嵌入式 Linux 起步

远见品质 Linux 的基本命令 (2)ps 列出进程df 检查文件系统空间占用情况 du 显示磁盘空间的使用情况 kill 杀死进程chmod 改变文件或目录的访问权限 chown 改变文件或目录的属主和组 chgrp 改变文件或目录所属的组 info 获得帮助

Page 12: 嵌入式 Linux 起步

远见品质 Linux 的基本命令 (3)pwd 显示当前工作目录的绝对路径rpm 文件包管理tar 为文件和目录创建档案 gzip 文件压缩clear 清屏grep 指定文件中搜索特定的内容 cat 连接并显示指定的文件信息 ln 创建文件链接

Page 13: 嵌入式 Linux 起步

远见品质 Linux 的目录结构/binbin 该目录中存放 Linux 的常用命令

/bootboot 该目录下存放的都是系统启动时要用到的程序

/devdev 该目录包含了 Linux 系统中使用的所有外部设备,它实际上是访问这些外部设备的端口,你可以访问这些外部设备,与访问一个文件或一个目录没有区别。

/sbinsbin 该目录用来存放系统管理员的系统管理程序。

Page 14: 嵌入式 Linux 起步

远见品质 Linux 的目录结构 (2)/etcetc 该目录存放了系统管理时要用到的各种配置文件和子目录,例如网络配置文件、文件系统等。

/homehome 如果建立一个名为“ xx” 的用户,那么在 /home 目录下就有一个对应的“ /home/xx” 路径,用来存放该用户的主目录。

/liblib 该目录用来存放系统动态连接共享库,几乎所有的应用程序都会用到该目录下的共享库。

Page 15: 嵌入式 Linux 起步

远见品质 Linux 的目录结构 (3)/lost+foundlost+found 该目录在大多数情况下都是空的。但当突然停电、或者非正常关机后,有些文件就临时存放在这里。

/mntmnt 该目录在一般情况下也是空的,你可以临时将别的文件系统挂在该目录下。

/procproc 可以在该目录下获取系统信息,这些信息是在内存中由系统自己产生的。

Page 16: 嵌入式 Linux 起步

远见品质 Linux 的目录结构 (4)/rootroot 超级用户的主目录 /tmptmp 用来存放不同程序执行时产生的临时文件

/usrusr 用户应用程序和文件都存放在该目录下

Page 17: 嵌入式 Linux 起步

远见品质 Linux 的编辑器 --vivi 的基本使用方法

•输入模式输入模式 •命令模式命令模式

Page 18: 嵌入式 Linux 起步

远见品质 vi-- 开始编辑 新增 (append)

-- aa 从 光 标 所 在 位 置 後 面 开 始 新 增 资 料, 光 标 後 的 资 料 随 新 增 资 料 向 後 移 动。-- AA 从 光 标 所 在 列 最 後 面 的 地 方 开 始 新 增 资 料。

插 入 (insert) -- ii 从 光 标 所 在 位 置 前 面 开 始 插 入 资 料, 光 标 後 的 资 料 随 新 增 资 料 向 後 移 动。-- II 从 光 标列 的 第 一 个 非 空 白 字 符 前 面 开 始 插 入 资 料。

开 始 (open)-- oo 在 光 标 所 在 列 下 新 增 一 列 并 进 入 输 入 模 式。-- OO 在 光 标 所 在 列 上 方 新 增 一 列 并 进 入 输 入 模 式。

Page 19: 嵌入式 Linux 起步

远见品质 vi-- 删除与修改

xx 删除光标所在字符。dddd 删除光标所在的列。r r 修改光标所在字符, r 後接著要修正的字符

RR 进入取代状态,新增资料会覆改原先资料, 直到按 [ESC]回到指令模式下为止。

ss 删除光标所在字符,并进入输入模式。SS 删除光标所在的列,并进入输入模式。

Page 20: 嵌入式 Linux 起步

远见品质 vi-- 退出命令

<:q> 不包存退出<:q!> 不保存强制性退出<:w>保存编辑<:w filename> 存入文件 filename 中<:w! filename>强制性存入文件 filename 中<:wq>(<:x>)保存并退出

Page 21: 嵌入式 Linux 起步

远见品质 vi-- 光标移动命令

<b> 移动到当前单词的开始<e> 移动到当前单词的结尾<w>向前移动一个单词<h>向前移动一个字符<j>向上移动一行<k>向下移动一行<l>向后移动一个字符

Page 22: 嵌入式 Linux 起步

远见品质 vi-- 改变与替换操作命令

<r>替换光标所在的字符<R>替换字符序列<cw>替换一个单词<ce> 同 <cw><cb>替换光标所在的前一字符<c$>替换自光标位置至行尾的所有字符<C> 同 <c$><cc>替换当前行

Page 23: 嵌入式 Linux 起步

远见品质 vi-- 拷贝与粘贴命令

</yw> 将光标所在单词拷入剪贴板<y$> 将光标至行尾的字符拷入剪贴板<Y> 同 <y$><yy> 将当前行拷入剪贴板<p> 将剪贴板中的内容粘贴在光标后<P> 将剪贴板中的内容粘贴在光标前

Page 24: 嵌入式 Linux 起步

远见品质 PART 2

了解 & 搭建嵌入式 Linux 系统

Page 25: 嵌入式 Linux 起步

远见品质 嵌入式 Linux 系统简介

嵌入式系统开发已经进入 32 位时代,在当前的数字信息技术和网络技术高速发展的后 PC Post-PC 时代,嵌入式系统已经广泛的渗透到科学研究、工程设计、军事技术、各类产业和商业文化艺术、娱乐业以及人们的日常生活等方方面面中。随着国内外嵌入式产品的进一步开发和推广,嵌入式技术越来越和人们的生活紧密结合。

Page 26: 嵌入式 Linux 起步

远见品质 什么是嵌入式系统?

•无处不在,融入生活

Page 27: 嵌入式 Linux 起步

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

MP3 、 PDA 、手机;DVD 机、机顶盒;车载 GPS 系统、探测火星的机器人。

Page 28: 嵌入式 Linux 起步

远见品质 嵌入式系统与 PC 机

•处理器•处理器

•存储器•存储器

•输入 •输出

•软件(操作系统 / 驱动程序 / 应用程序)•软件(操作系统 / 驱动程序 / 应用程序)

Page 29: 嵌入式 Linux 起步

远见品质 嵌入式产品内部机构

Page 30: 嵌入式 Linux 起步

远见品质 嵌入式系统与 PC设备名称 嵌入式系统 PC 机

CPU 嵌入式处理器( ARM , MIPS )

CPU ( Intel 的 Pentium 、 AMD 的 Athlon 等)

内存 SDRAM 芯片 SDRAM , DDR 内存条

存储设备 Flash 芯片 硬盘

输入设备 按键、触摸屏 鼠标、键盘

输出设备 LCD 显示器

声音设备 音频芯片 声卡

接口 MAX232 等芯片 主板集成

其他设备 USB 芯片、网卡芯片 主板集成或外接卡

Page 31: 嵌入式 Linux 起步

远见品质 嵌入式系统与 PC (2)嵌入式系统 PC 机

引导代码 Bootloader 引导,针对不同电路板进行移植

主板的 BIOS 引导,无须改动

操作系统 WinCE 、 VxWorks 、 Linux 等,需要移植

Windows 、 Linux 等,不需要移植

驱动程序 每个设备驱动都必须针对电路板进行重新开发或移植,一般不能直接下载使用

操作系统含有大多数驱动程序,或从网上下载直接使用

协议栈 需要移植 操作系统包括,或第三方提供

开发环境 借助服务器进行交叉编译 在本机就可开发调试

仿真器 需要 不需要

Page 32: 嵌入式 Linux 起步

远见品质 嵌入式系统的特点 1 )嵌入式系统低功耗、体积小,专用性强。嵌

入式系统与 PC 机的最大不同就是嵌入式 CPU大多工作在为特定用户群设计的系统中,能够把PC 机中许多由板卡完成的任务集成在芯片内部,从而有利于嵌入式系统设计趋于小型化。

2 )为了提高执行速度和系统可靠性,嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是存贮于磁盘等载体中。

3 )嵌入式系统的硬件和软件都必须高效率地设计,系统要精简。操作系统一般和应用软件集成在一起。

4 )对软件代码质量要求很高。应该尽最大可能避免死机的情况发生。

5 )嵌入式系统开发需要专门的开发工具和开发环境。

Page 33: 嵌入式 Linux 起步

远见品质 典型的嵌入式操作系统

Linux

uC/OS

Windows CE

VxWorks

Palm OS

QNX

Symbian

•How To Choice How To Choice

Page 34: 嵌入式 Linux 起步

远见品质 嵌入式操作系统使用调查

Which OSes have been in your embedded systems during the past 2 years? Which will be used during the next two?

Page 35: 嵌入式 Linux 起步

远见品质 嵌入式操作系统使用调查

Actual and projected Linux use, over the last five years

Page 36: 嵌入式 Linux 起步

远见品质 嵌入式处理器使用调查

What CPUs were used in your embedded projects during the past two years? Which will be used during the next two?

Page 37: 嵌入式 Linux 起步

远见品质 开发工具调查

What development tools are you most likely to use?

Page 38: 嵌入式 Linux 起步

远见品质 Host 与 Target

Linux 服 务 器 ( Host )

客户机 1

客户机 2

客户机 3

客户机 4

交换机

开发板( Target )串口

•是一个基于 x86 架构的计算机( Pentium4处理器、 Athlon 处理器等),即 i386 平台。

•Target 是目标平台,比如ARM 、 MIPS 、 SuperH 、 Pow

erPC 等。

Page 39: 嵌入式 Linux 起步

远见品质 GCC 交叉编译器GNU Binutils

GNU Binutils 的主要工具有两个,一个是连接程序 ld ,另外一个是汇编程序 as 。其主要目的是为 GNU 系统,提供汇编和连接工具。

GNU GCC GNU GCC 就是上面提到的 GCC , GCC 主要是

为 GNU 系统提供 C 编译器。现在支持多种语言,这其中包括 C/C++ 、 Fortran 、 Java 、 Objective-C 、甚至还有 Ada 。

GNU GLibc 用于定义系统调用和其它一些基本的函数调用。

Page 40: 嵌入式 Linux 起步

远见品质 交叉编译的过程

Page 41: 嵌入式 Linux 起步

远见品质 GCC 交叉编译器的生成第 1步,取得 Binutils 、 GCC 、 Glibc 源码。

第 2步,配置并编译 Binutils 取得我们所需要的汇编和连接程序。

第 3步,配置并编译 GCC 源码生成 GCC 编译器。一般是 C 编译器首先生成,然后以这个为基础在结合下一步生成的 Glibc 的 C 函数库,再编译生成其它编译器。

第 4步,配置 Glibc 并编译生成 Glibc 的C 函数库。

第 5步,再次配置和编译 GCC 源码,生成其它语言的编译器,如 C++ 编译器等。

Page 42: 嵌入式 Linux 起步

远见品质 代码结构

Page 43: 嵌入式 Linux 起步

远见品质 设置环境变量

Export PROJECT=S3C2410TKExport PRJROOT=~/$PROJECTExport TARGET=arm-linuxExport PREFIX=$PROJECT/toolsExport TARGET_PREFIX=$PREFIX/$TARGETExport PATH=$PREFIX/bin:$PATH

Page 44: 嵌入式 Linux 起步

远见品质 TARGET 常用的值实际平台 TARGET 的值

PowerPC powerpc-linux

ARM arm-linux

MIPS (big endian) mips-linux

MIPS (little endian) mipsel-linux

SuperH 4 sh4-linux

Page 45: 嵌入式 Linux 起步

远见品质 交叉编译流程

Page 46: 嵌入式 Linux 起步

远见品质 Step 1

Page 47: 嵌入式 Linux 起步

远见品质 安装内核头文件( 1 )

$ cd include/asm-arm/

$ rm arch proc

$ ln -s arch-s3c2410 arch

$ ln -s proc-armv procproc-armo is for 26-bits ARMproc-armv is for 32-bits ARM

Page 48: 嵌入式 Linux 起步

远见品质 安装内核头文件( 2 )

配置内核make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig

ARCH 目标平台 CROSS_COMPILE 交叉编译工具

保存后退出上述操作成功后,会生成:

linux-2.4.18/include/linux/version.h

Page 49: 嵌入式 Linux 起步

远见品质 安装内核头文件( 3 )

$ mkdir -p $TARGET_PREFIX/include $ cp -r include/linux/ $TARGET_PREFIX/include/ $ cp -r include/asm-arm/ $TARGET_PREFIX/include/asm

与平台相关的汇编 $ cp -r include/asm-generic/ $TARGET_PREFIX/include

Page 50: 嵌入式 Linux 起步

远见品质 刚才都做了些什么?

Page 51: 嵌入式 Linux 起步

远见品质 Step 2

Page 52: 嵌入式 Linux 起步

远见品质 安装 Binutils$ cd $PRJROOT/build-tools/$ tar -xvzf binutils-2.14.tar.gz$ cd build-binutils$ ../binutils-2.14/configure --target=$TARGET --prefix=$

PREFIXMakefile 和 Config 文件将被生成,存放在 build-tools/build-binutils/ 目录下

$ make$ make install

Page 53: 嵌入式 Linux 起步

远见品质 刚才又做了些什么?

Page 54: 嵌入式 Linux 起步

远见品质 Step 3

Page 55: 嵌入式 Linux 起步

远见品质 安装 Bootstrap 编译器

创建交叉编译版本的 gcc ,需要交叉编译版本的 glibc 及其头文件;而交叉编译版本的 glibc 是通过交叉编译版本的 gcc 创建的。

Page 56: 嵌入式 Linux 起步

远见品质 安装 Bootstrap 编译器修改 gcc 源代码中的 gcc/config/arm/

t-linux 文件,在该文件的 TARGET_LIBGCC2_CFLAGS 后面加上 __gthr_posix_h 和 inhibit_libc :

TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer –fPIC (修改前 )

TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer –fPIC -Dinhibit_libc -D__gthr_posix_h.

Page 57: 嵌入式 Linux 起步

远见品质 安装 Bootstrap 编译器$ cd build-boot-gcc/

$ ../gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-newlib --enable-languages=c --disable-threadsMakefile 和 config 文件生成在 build-tools/build-boot-gcc/ --target 目标平台--prefix 安装路径--without-headers 我们现在没有 glibc headers--with-newlib 不使用 glibc--enable-languages=c 只支持 C语言--disable-threads -Dinhibit_libc补丁

$ make all-gcc $ make install-gcc

Page 58: 嵌入式 Linux 起步

远见品质 刚才又做了些什么?

Page 59: 嵌入式 Linux 起步

远见品质 Step 4

Page 60: 嵌入式 Linux 起步

远见品质 安装 C 库 $ cd $PRJROOT/build-tools/ $ tar -xvzf glibc-2.1.3.tar.gz $ tar -xvzf glibc-crypt-2.1.tar.gz --directory=glibc-2.1.3 $ tar -xvzf glibc-linuxthreads-2.1.3.tar.gz --directory=glibc-2.

1.3$ cd build-glibc/$ CC=arm-linux-gcc ../glibc-2.1.3/configure --host=$TARGET \> --prefix="/usr" --enable-add-ons \> --with-headers=$TARGET_PREFIX/include

Makefile 和 config 文件生成在 build-tools/build-glibc/CC=arm-linux-gcc--host=$TARGET --prefix="/usr“--enable-add-ons 使用 linux 线程--with-headers 使用 linux 内核头文件

Page 61: 嵌入式 Linux 起步

远见品质 安装 C 库$ cd $PRJROOT/build-tools/build-glibc/ $ make$ make install_root=$TARGET_PREFIX prefix

="" install安装 glibc 到 $TARGET_PREFIX注意不要覆盖系统原来的库Glibc 的安装路径在 $install_root/$prefix

/usr/lib/, 现在我们安装在 $install_root/$prefix/lib/

$ cd $TARGET_PREFIX/lib/

Page 62: 嵌入式 Linux 起步

远见品质 安装 C 库

$ cp libc.so libc.so.orig$ vi libc.so

修改 libc.so 文件GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a )GROUP ( libc.so.6 libc_nonshared.a )

Page 63: 嵌入式 Linux 起步

远见品质 刚才又做了些什么?

Page 64: 嵌入式 Linux 起步

远见品质 Step 5

Page 65: 嵌入式 Linux 起步

远见品质 最后的安装$ cd $PRJROOT/build-tools/build-gcc/

$ ../gcc-<version>/configure --target=$TARGET \

–prefix=$PREFIX \--enable-languages=c,c++

$ make all $ make install

Page 66: 嵌入式 Linux 起步

远见品质 Finished

Page 67: 嵌入式 Linux 起步

远见品质 $PRJROOT/tools 结构

Page 68: 嵌入式 Linux 起步

远见品质 生成的 Toolchain

Page 69: 嵌入式 Linux 起步

远见品质 开发环境快速建立下载 下载 arm-elf-tools-<version>.sh arm-elf-tools-<version>.sh 执行:执行: sh arm-elf-tools- <version>. ssh arm-elf-tools- <version>. s

hh配置环境变量配置环境变量

Page 70: 嵌入式 Linux 起步

远见品质 PART 3

初识 Bootloader

Page 71: 嵌入式 Linux 起步

远见品质 BootLoader 的概念BootLoader 是系统加电启运行的第一段软件代码

是在操作系统内核或用户应用程序运行之前运行的一段小程序。

BootLoader 大多都是两个阶段的启动过程,也即启动过程可以分为 stage 1和 stage 2两部分:stage 1: 汇编语言实现stage 2: 高级语言实现

Page 72: 嵌入式 Linux 起步

远见品质 BootLoader 的操作模式 启动加载(启动加载( Boot loadingBoot loading )模式)模式: BootLoader

从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。这种模式是 BootLoader 的正常工作模式。嵌入式产品发布时, BootLoader 工作在这种模式下;

下载(下载( Down loadingDown loading )模式)模式: BootLoader通过串口连接或网络连接等通信手段从主机下载文件,比如:下载应用程序、数据文件、内核映像等.从主机下载的文件通常首先被 BootLoader保存到目标机的 RAM 中然后再被 BootLoader 写到目标机上的固态存储设备中。 BootLoader 的这种模式通常在系统更新时使用。工作于这种模式下的 BootLoader通常都会向它的终端用户提供一个简单的命令行接口。

Page 73: 嵌入式 Linux 起步

远见品质 BootLoader 的特征初始化硬件,特别是内存控制器提供 Linux 内核的启动参数启动 Linux 内核

简化开发过程的一些特征:读写存储器通过串口 / 网口上载文件到 RAM从 RAM 复制文件到 Flash 中

Page 74: 嵌入式 Linux 起步

远见品质 U-Boot 程序结构平台相关

board, cpu, lib_ppc, lib_arm, include…

平台无关common, net, fs, drivers…

工具和文档tools, doc

Page 75: 嵌入式 Linux 起步

远见品质 U-Boot 程序结构board Board dependent files,

RPXlite(mpc8xx), smdk2410(arm920t), sc520_cdp(x86) …

cpu CPU specific files,

mpc8xx, ppc4xx, arm720t, arm920t, xscale, i386

lib_ppc Files generic to PowerPC architecture

lib_arm Files generic to ARM architecture

lib_i386 Files generic to X86 architecture

include Header Files and board configs

Page 76: 嵌入式 Linux 起步

远见品质 U-Boot 程序结构common Misc functions

lib_generic Generic library functions

net Networking code

fs File System Code

post Power On Self Test

drivers Common used device drivers

disk Hard disk interface code

rtc Real Time Clock drivers

dtt Digital Thermometer and Thermostat drivers

Page 77: 嵌入式 Linux 起步

远见品质 移植 U-Bootinclude/configs/smdk2410.h

board/smdk2410/smdk2410.c

int board_int(void)

int dram_init(void)

board/smdk2410/flash.c

cpu/arm920t/serial.c

drivers/rtl8019.c

Page 78: 嵌入式 Linux 起步

远见品质 硬件连接准备JTAGJTAG串口串口

网口网口

Page 79: 嵌入式 Linux 起步

远见品质 实物连接图

Page 80: 嵌入式 Linux 起步

远见品质 烧写 u-boot 到 FLASH

$ ./ JFLASH_2410EP_Nor /f:u-boot.bin

选择烧写的 FLASH 类型选择烧写到的地址 Smoking & Waiting…

Page 81: 嵌入式 Linux 起步

远见品质 优龙 FS2410开发板

Page 82: 嵌入式 Linux 起步

远见品质 FS2410的 BIOS功能

主要有文件下载Flash烧写启动程序(存储在 Flash 中)设置启动参数设置启动操作系统

Page 83: 嵌入式 Linux 起步

远见品质 BIOS 具体功能0号功能: USB 下载1号功能:串口下载2号功能:执行 NAND Flash 的烧写3号功能:从 NAND Flash 启动程序4号功能:擦除 NAND Flash分区5号功能:烧写 Nor Flash6号功能:设置启动参数7号功能:设置自启动参数

Page 84: 嵌入式 Linux 起步

远见品质 DNW窗口

Page 85: 嵌入式 Linux 起步

远见品质 MiniCOM和超级终端

配置 MiniCOM 配置超级终端

Page 86: 嵌入式 Linux 起步

远见品质 PART 4

了解并编译 Linux 内核

Page 87: 嵌入式 Linux 起步

远见品质 内核代码布局arch/ Architecture dependent code

include/ Kernel headers

include/asm-<arch>

Architecture dependent headers

include/linux Linux Linux kernel core headers

drivers/ All device drivers (drivers/usb/, etc.)Documentation/

Kernel documentation. Don't miss it!

MAINTAINERS Maintainers of each kernel part.Very useful!

COPYING Linux copying conditions (GNU GPL)

CREDITS Linux main contributors

REPORTINGBUGS

Bug report instructions

Page 88: 嵌入式 Linux 起步

远见品质 内核代码布局 (2)fs/ Filesystems (fs/ext3/, etc.)

init/ Linux initialization (including main.c)

ipc/ Code used for process communication

kernel/ Linux kernel core (very small!)

lib/ Misc library routines (zlib, crc32...)

mm/ Memory management code (small too!)

net/ Network support code (not drivers)

scripts/ Scripts for internal or external use

README Overview and building instructions

Makefile Top Linux makefile (sets arch and version)

Page 89: 嵌入式 Linux 起步

远见品质 编译内核tar jxvf linux-xx-xx.tar.bz2cd /usr/src/linux-xx-xxmake menuconfigmake depmake zImage

Page 90: 嵌入式 Linux 起步

远见品质 uClinux 内核编译 tar xzvf uClinux-xxxxxx.tar.gz cd uClinux-dist   make menuconfig make  dep make  cleanmake lib_only # 编译库文件make user_only # 编译用户应用程序文件make romfs # 生成 romfs 文件系统make image

Page 91: 嵌入式 Linux 起步

远见品质 uC-libc 和 uClibc 的区别 uC-libc 是 uClinux 的原始 c 库 , 基于 Lin

ux-8086 c 库,是一个相当全面的 c 库 ,但它的一些 API 是非标准的 , 一些通用库例程现在已不再使用。

uClibc 是 uC-libc 的派生体 , 用来解决 uC-libc 存在的问题 . 它让所有的 API 都标准化,补充了许多缺失的例程 , 并且已经移植到许多结构中 . 大体上讲 , 它通过提供glibc兼容使得应用程序移植到较小的 c 库时相当得容易 . 它能够应用到带虚拟存储的 Linux 和 uClinux 上 .

M68000M68000

ColdFireColdFire

不带不带 MMMMUU 的的 ARAR

MM

Page 92: 嵌入式 Linux 起步

远见品质 MenuConfig

Page 93: 嵌入式 Linux 起步

远见品质 重要的内核文件 vmlinuz与 vmlinux

vmlinuz是可引导的、压缩的、可执行的内核。

老的 zImage解压缩内核到低端内存(第一个 640K), bzImage解压缩内核到高端内存( 1M以上)。如果内核比较小,那么可以采用 zImage 或 bzImage 之一,两种方式引导的系统运行时是相同的。大的内核采用 bzImage,不能采用 zImage。

vmlinux是未压缩的内核, vmlinuz是 vmlinux的压缩文件。

Page 94: 嵌入式 Linux 起步

远见品质 重要的内核文件 (2) initrd-x.x.x.img

initrd是“ initial ramdisk”的简写 ,一般被用来临时的引导硬件到实际内核 vmlinuz 能够接管并继续引导的状态

initrd实现加载一些模块和安装文件系统等 。

initrd 映象文件是使用 mkinitrd创建的 。

Page 95: 嵌入式 Linux 起步

远见品质 重要的内核文件 (3) System.map

System.map是一个特定内核的内核符号表。它是你当前运行的内核的 System.map的链接。

System.map是由“ nm vmlinux”产生并且不相关的符号被滤出 。

nm vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map 然后复制到 /boot: cp /usr/src/linux/System.map /boot/System.map-2.4.7-10 。

Page 96: 嵌入式 Linux 起步

远见品质 移植 Linux 内核 arch/arm/config.in arch/arm/Makefile arch/arm/mach-s3c2410/* include/asm-arm/arch-s3c2410/* arch/arm/kernel/debug-armv.S arch/arm/kernel/entry-armv.S arch/arm/kernel/head-armv.S arch/arm/tools/mach-types arch/arm/boot/compressed/head-s3c2410.S arch/arm/boot/compressed/Makefile arch/arm/boot/Makefile

Page 97: 嵌入式 Linux 起步

远见品质 下载内核到开发板通过串口通过网口

$ cp zImage /tftpbootUBOOT> tftp 30008000 zImageUBOOT> go 30008000

通过 USB

配置配置 tftptftp 配置配置 NFSNFS

Page 98: 嵌入式 Linux 起步

远见品质 下载并启动内核

Page 99: 嵌入式 Linux 起步

远见品质 SourceInsight界面

•Code•File

Page 100: 嵌入式 Linux 起步

远见品质 PART 5

编写和调试 Linux 程序

Page 101: 嵌入式 Linux 起步

远见品质 Hello , World!1. #include <stdio.h>

2. main(int argc, char **argv)

3. {

4. int i;

5. for ( i=0; i<10; i++)

6. {

7. printf("hello i=%d\n", i);

8. }

9. return 0;

10. }

Page 102: 嵌入式 Linux 起步

远见品质 编译程序

gcc -o hello hello.c //// 编译程序编译程序armv4l-unkown-linux-gcc -o hello hello.c //// 编译程序,不带调试信息编译程序,不带调试信息armv4l-unkown-linux-gcc -g –o hello hello.c //// 编译程序,带调试信息编译程序,带调试信息 ./hello //// 执行程序执行程序gdb hello //// 调试程序 调试程序

Page 103: 嵌入式 Linux 起步

远见品质 程序运行结果

Page 104: 嵌入式 Linux 起步

远见品质 调试程序 ( 目标板 )

Page 105: 嵌入式 Linux 起步

远见品质 调试程序 ( 主机 )

Page 106: 嵌入式 Linux 起步

远见品质 PART 6

编写 Linux 设备驱动程序

Page 107: 嵌入式 Linux 起步

远见品质 设备驱动程序概述 linux 设备驱动程序是处理或操作硬件控制器的软件,被集成在内核中,是常驻内存的低级硬件处理程序的共享库,设备驱动程序就是对设备的抽象处理。 Linux允许设备驱动程序作为内核可加载模块实现,这样除了可以在系统启动是进行注册外,还可以在启动后进行加载注册。

Page 108: 嵌入式 Linux 起步

远见品质 嵌入式设备框图

Page 109: 嵌入式 Linux 起步

远见品质 设备驱动程序 de功能

对设备进行初始化使设备投入运行和退出服务从设备接收数据并将它们送回内核将数据从内核送到设备检测和处理设备出现的错误

Page 110: 嵌入式 Linux 起步

远见品质 Linux 驱动程序 de 特点嵌入式 Linux 驱动程序需求多样

嵌入式设备硬件各异嵌入式处理器往往资源有限,比如处理速度、存储器容量、总线带宽、电池容量等

开发团队面临上市时间的压力开发驱动程序需要专业知识,包括硬件和软件的

Page 111: 嵌入式 Linux 起步

远见品质 Linux 驱动开发流程

1. 学英语2. 熟悉设备的特性3. 确定设备驱动程序是哪一类4. 编写测试用例5. 搜集可重用的代码6. 编写自己的驱动程序代码7. 调试、编码、测试

Page 112: 嵌入式 Linux 起步

远见品质 Linux 驱动开发环境本机编译调试

开发环境配置简单无需网络环境适用于配置较高的 x86 机器

主机 + 目标机主机可以自由选择 Linux 或 Windows+Cygwin主机和目标机通过网络共享文件系统内核崩溃不会影响主机主机运行的工具链∶ cross gcc + glibc + gdb

Page 113: 嵌入式 Linux 起步

远见品质 设备驱动程序 de 代码 驱动程序的注册与注销

register_chrdev() register_blkdev()

设备的打开与释放open() release()

设备的读写操作 read() write()

设备的控制操作 ioctl()

Page 114: 嵌入式 Linux 起步

远见品质 设备驱动 de加载 使用模块的方式动态加载驱动

int func_init(void) Makefile:

insmod xx.o lsmod rmmod xx.o

将驱动静态编译到内核里面 int __init func_init(void) Makefile:

启动时自动加载

Page 115: 嵌入式 Linux 起步

远见品质 Linux 驱动程序模块加载

Page 116: 嵌入式 Linux 起步

远见品质 设备存储器 de映射

Page 117: 嵌入式 Linux 起步

远见品质 电路图

•0x200000000x20000000

Page 118: 嵌入式 Linux 起步

远见品质 驱动源代码#include …

#define SimpleLED_MAJOR 97

static long ioremap_addr;

ssize_t SimpleLED_read (struct file * file ,char * buf,

size_t count,

loff_t * f_ops){

printk("s3c2410: device file-read operation!\n");

return count;}

ssize_t SimpleLED_write(struct file * file ,const char * buf,

size_t count,

loff_t * f_ops){

printk("s3c2410: device file-write operation!\n");

return count;}

Page 119: 嵌入式 Linux 起步

远见品质 驱动源代码ssize_t SimpleLED_ioctl (struct inode * inode ,

struct file * file, unsigned int cmd, long data){

printk("s3c2410: device ioctl operation!\n");}ssize_t SimpleLED_open (struct inode * inode ,

struct file * file){return 0;

}ssize_t SimpleLED_release (struct inode * inode , struct file * file){

outw(0x0000,ioremap_addr);return 0;

}

Page 120: 嵌入式 Linux 起步

远见品质 驱动源代码

struct file_operations SimpleLED_ops ={

open: SimpleLED_open,

read: SimpleLED_read,

write: SimpleLED_write,

ioctl: SimpleLED_ioctl,

release: SimpleLED_release,

// 其他};

Page 121: 嵌入式 Linux 起步

远见品质 驱动源代码1. static int __init HW_SimpleLED_init(void)2. {3. int ret = -ENODEV;4. int delay ;5. ret = devfs_register_chrdev(SimpleLED_MAJOR, "SimpleLED",

&SimpleLED_ops); 6. if( ret < 0 ){7. printk (" s3c2410: init_module failed with %d\n", ret);8. return ret;9. }else{10. printk(KERN_INFO" SimpleLED register success!!!\n");}11. dev_handle = devfs_register( NULL, "SimpleLED", DEVFS_F

L_DEFAULT,SimpleLED_MAJOR,0,S_IFCHR, &SimpleLED_ops, NULL);

12. ioremap_addr=ioremap(0x20000000,0x0f);13. outw(0x55aa,ioremap_addr);14. printk("remap address = %x\n",ioremap_addr);15. return ret;}

devfs_register注册的设备会自动创建 /dev/ 下的设备文件, register_chrdev注册的设备需要用户手工 mknod创建设备文件

Page 122: 嵌入式 Linux 起步

远见品质 驱动源代码1. int __init s3c2410_SimpleLED_init(void) {2. int ret = -ENODEV;3. ret = HW_SimpleLED_init();4. if (ret)return ret;5. return 0;}

6. int init_module()7. {8. s3c2410_SimpleLED_init();9. }10. void cleanup_module()11. {12. devfs_unregister_chrdev( SimpleLED_MAJOR, "SimpleLED" );13. devfs_unregister( dev_handle );14. }

Page 123: 嵌入式 Linux 起步

远见品质 编译驱动程序

Makefile 文件内容:/opt/host/armv4l/bin/armv4l-unknown-linux-gcc \n -D \n __KERNEL__ \n

-I/s3c2410_linux/kernel/include \n-DMODULE \n-c \n-o \nSimpleLED.o SimpleLED.c

Page 124: 嵌入式 Linux 起步

远见品质 应用程序#includeint main(){ int fd1,fd2, i,ret,buf; fd1=open("/dev/SimpleLED",O_RDWR); if (fd1<0) printf("Error open SimpleLED\n"); else printf("Open SimpleLED success!\n"); buf=random(); usleep(1000); write(fd1,&buf,buf); return 0;}

•SimpleLED_openSimpleLED_open

•SimpleLED_writeSimpleLED_write

•sys_opensys_open

•sys_writesys_write

Page 125: 嵌入式 Linux 起步

远见品质 编译应用程序

Makefile 文件内容:/opt/host/armv4l/bin/armv4l-unknown-linux-gcc \n

-o \n

testLED.o testLED.c

Page 126: 嵌入式 Linux 起步

远见品质 文件系统 _romfsromfs 是文件系统类型uCLinux 系统采用 romfs 文件系统,这种文件系统相对于一般的 ext2 文件系统要求更少的空间

romfs 文件系统不支持动态擦写保存,对于系统需要动态保存的数据采用虚拟 RAM 盘的方法进行处理 。

下载生成 romfs 的工具 genromfs

Page 127: 嵌入式 Linux 起步

远见品质 文件系统 _ cramfsLinus Torvalds 开发 cramfs 是只读压缩的文件系统,文件系统类型可以是 ext2 , ext3

系统启动后, kernel把 cramfs 文件系统载入到内存中,解压,所以比较占内存

采取了 zlib 做压缩 ,省空间 mkcramfs rootfs rootfs.cramfsmount -o loop -t cramfs /usr.img /usr

Page 128: 嵌入式 Linux 起步

远见品质 ramdisk

dd if=/dev/zero of=rootfs.img bs=1M count=xx把它格式化为你需要的文件系统,如 ext2 、

ext3 、 reiserfs 等。 格式化 ext3 文件系统的命令: mkfs.ext3 rootfs.img 然后把它 mount 到某个目录

gzip -v9 rootfs.img 会自动生成 rootfs.img.gz

Page 129: 嵌入式 Linux 起步

远见品质 使用 U-BOOT写 FLASH

UBOOT> protect off 40000 3fffff

UBOOT> tftp 30040000 zImage

UBOOT> erase 40000 ffff

UBOOT> prog 30040000 40000 <zImage_size>

UBOOT> tftp 30100000 fsimage.jffs2

UBOOT> erase 100000 3fffff

UBOOT> prog 30100000 100000 <image_size>

Page 130: 嵌入式 Linux 起步

www.farsight.com.cn

The End!

成功之路