嵌入式Linux系统设计搭建与配置过程.docx
《嵌入式Linux系统设计搭建与配置过程.docx》由会员分享,可在线阅读,更多相关《嵌入式Linux系统设计搭建与配置过程.docx(16页珍藏版)》请在冰豆网上搜索。
嵌入式Linux系统设计搭建与配置过程
1.摘要………………………………………………………2
2.UBOOT,LINUX内核,文件系统的介绍及相互关系..3
2.1嵌入式系统简介………………………………………3
2.2嵌入式Linux概述……………………………………3
2.3UBOOT简介………………………………………….4
3.UBOOT的启动过程……………………………………..6
4.内核的主要功能和裁剪……………………………………7
4.1Linux的编译…………………………………………………7
4.2嵌入式Linux的配置和剪裁…………………………………..8
5.文件系统的制作过程………………………………………8
6.交叉编译器的搭建和环境变量的设置…………………..9
7.驱动程序的编写过程与关键点…………………………11
7.1Linux网络驱动程序的结构………………………………11
7.2 网络驱动程序的基本方法………………………………12
7.3 网络驱动程序中用到的数据结构……………………….12
7.4 常用的系统支持………………………………………….14
7.5编写Linux网络驱动程序中需要注意的问题…………18
8.参考文献………………………………………………..20
摘要
嵌入式系统是以应用为中心,以计算机为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
嵌入式系统一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户的应用程序4部分组成,用于实现对其它设备的控制、监视或管理等功能。
其广泛应用于控制领域、消费电子产品等行业,已成为现代电子领域的重要研究方向之一。
嵌入式Linux的研究已经成为当前信息技术研究的热点,它的应用蕴含着巨大的商业价值,并且己经广泛的应用于各种信息家电、通讯产品、工业控制中。
论文首先介绍了ARM和嵌入式Linux操作系统的特点和当前的发展概况。
然后阐述了嵌入式Linux开发流程以及移植到具体硬件平台需要完成的工作,如U-Boot的移植、Linux内核的编译与裁剪、文件系统的制作、驱动程序的编写等。
关键字:
嵌入式;ARM;嵌入式Linux;Linux内核;驱动程序
2.LINUX,UBOOT,文件系统的介绍及相互关系
2.1嵌入式系统简介
嵌入式系统是以应用为中心,以计算机为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
单片机、单板机控制系统以及一些专用的工业控制计算机都可以称作嵌入式系统,它是嵌入式系统领域的重要组成部分,只是更着重于对各自硬件系统的研究。
嵌入式系统更着重于对软件系统进行研究,顺应了软硬件协同设计以及应用需求的发展。
目前,嵌入式系统己逐步发展成为一门学科,朝着系统化和规范化的方面发展。
嵌入式系统学科和产业的发展使得设计人员能够从容地面对越来越复杂的应用需求,通过软件和硬件的模块化设计大大地简化和加快应用系统的开发.嵌入式系统主要包括硬件和软件两部分。
硬件包括处理器、存储器及外部设备、I/0端口和图形控制器等;软件部分包括操作系统(OS)和用户应用程序。
嵌入式系统硬件的核心是嵌入式微处理器。
它的功能、外设集成度、速度、功耗、体积、成本、可靠性和电磁兼容性等方面均受到应用要求的制约,是各个半导体厂商之间竞争的热点。
嵌入式系统的软件是实现嵌入式系统功能的关键,软件要求固化存储,代码的高质量、高可靠性和高实时性在许多场合也是基本要求。
多任务嵌入式操作系统是知识集成的平台,是嵌入式系统走向工业标准化道路的基础,是嵌入式系统研究的重要方向。
现在人们讲嵌入式系统时,某种程度上是指近些年来比较热门的具有操作系统的嵌入式系统。
2.2嵌入式Linux概述
Linux操作系统源于芬兰一位大学生—LinusTorvalds的课余作品,随着Intemet的发展,Linux操作系统在全球计算机爱好者的关怀下,不断地发展和成长,己成为当前最流行的免费操作系统,任何人都可以自由的使用Linux源程序。
嵌入式Linux操作系统的组成,我们可以和PC机相对应来理解,在PC机上,Windows的启动大致有BIOS、内核、文件系统和初始化程序几个部分;那么相对而言,嵌入式Linux的移植有Bootloader、Linux内核、文件系统、初始化和用户的应用程序几部分,Bootloader完成系统的初始化和引导。
Linux操作系统具有以下几大特点:
(1)开放源码,丰富的软件资源
Linux遵循GPL(GNU通用许可证),用法律保障了用户免费获得内核源代码的权利。
由于嵌入式系统千差万别,往往需要针对某一具体应用去修改和优化系统,这样,能否获得源代码就至关重要。
Linux是自由的操作系统,它的开放源代码使用户获得了最大的自由度。
Linux上的软件资源十分丰富,每种通用程序在Linux上都可以找到,并且每天都在增加。
在Linux上往往不需要从头做起,而是先选择一个类似的自由软件,进行二次开发。
这就大大节省了开发工作量,缩短了开发时间。
(2)功能强大的内核,性能高效、稳定、多任务
Linux的内核非常稳定。
它的高效和稳定性已经在各个领域,尤其在网络服务器领域得到了事实的验证,而且Linux内核小巧灵活,易于裁剪。
这使Linux能很适合嵌入式系统的应用。
(3)支持多种体系结构
Linux能支持X86,ARM,MIPS,POWERP,ALPHA,SPARC等多种体系结构。
目前,Linux己被移植到数十种硬件平台上,几乎所有流行的CPU,Linux都支持。
(4)完善的网络通信、图形和文件管理机制
Linux自产生之日起就与网络密不可分,网络是Linux的强项。
另外,它支持ext2,fatl6,fat32,romfs等多种文件操作系统。
在图形系统方面,Linux上既有成熟的xWindow,也有embedcdQT,MiniGUI等嵌入式图形用户界面GUI,还有ysvgalib,framebuffer等优秀工具,可以适合不同的用途。
(5)支持大量的周边硬件设备,驱动丰富
Linux上的驱动己经非常丰富了,支持各种主流硬件设备和最新硬件技术,而且随着Linux的广泛应用,许多芯片厂家也已经开始提供Linux上的驱动。
这一步促进了Linux各种硬件平台上的应用。
(6)大小功能都可定制
Linux继承了Unix的优秀设计思想,内核与用户界面是完全独立的。
它非常灵活,各部分的可定制性都很强,能适合多种需求。
2.3UBOOT简介
U—Boot是一个非常复杂的东酉,它也体现了嵌入式系统的一个非常重要的特征:
自己定制。
它脱胎于PC机的Linux,可从网站上直接下载,U.Boot和其它任何BOOTLOADER都是一样的,主要实现对系统进行初始化、系统引导、FLASH操作等功能。
开发平台的U.Boot主要是对板子的硬件进行初始化,包括:
时钟和PLL、定时器、调试串D(DebugDART)等等。
有了U.B00t我们可以在主机的超级终端通过调试串口和目标机进行通信和设置。
2.3.1编译U-Boot
在Linux系统下,用下面的命令对U.Boot进行编译
$cdU.BOOT;进入目录
Smakeat91rm9200dk_eonfig;编译
Smakeall
$gzip_cu-boot.bin>u-boot.gz;压缩为gz文件
编译boot.bin
$cdBoot
Smake
编译loader.bin
$cdLoader
Smake
2.3.2U.Boot命令
在本系统中,采用的是U-Boot,U-Boot在嵌入式系统中相当于Pc机的BIOS加上操作系统引导头部的内容,并且引导操作系统进行装载和运行,U.Boot启动后有一系列的命令,使得我们能够方便的对FLASH、RAM进行操作,U.Boot已经对系统的频率、定时器进行了设置,初始化了一个调试串口,我们可以通过串口或者以太网进行数据的下载。
下面是U.Boot常用的命令:
go一在地址’addr’处开始程序执行
run一运行命令
bootm一从内存中进行应用程序影像运行
bootp一通过网络用BootP/TFTP协议来启动影像
tf砸boot一通过网络用TFTP协议、设置服务器和客户机的IP地址进行影像文件传送
loadb一通过串口线(kermitmode)来装载二进制文件
pfintcnv一打印环境变量.
setcnv一设置环境变量
saveenv一保存环境变量到内存
下面是U.Boot的简单环境变量
baudrate一波特率
bootdelay--Boot延迟
bootcmd--Boot命令
bootargs—Boot参数
ipaddr一客户机IP地址
servefip一服务器地址
loadaddr一装载地址
etlladdr一网卡MAC地址
3.UBOOT的启动过程
嵌入式Linux系统一般没有自举程序,必须通过启动程序来引导硬件系统进入操作系统。
启动程序的工作包括:
改变系统时钟、关闭WATCHDOG、初始化存储控制器等。
本文针对本嵌入式控制系统所需的硬件方案,植入Uboot1-3.4启动程序。
U-Boot是一种功能强大的引导转载程序。
它不仅支持Linux、Vxworks等操作系统,还支持PowerPC、ARM等多种系列处理器。
Uboot启动过程分为两个阶段。
第一阶段由汇编来实现,用于完成依赖于CPU体系结构的初始化,并调用第二阶段的代码。
第二阶段由C语言实现,完成相关初始化后,进入命令循环以等待用户命令,或将参数传给内核,引导Linux内核启动。
图中给出了Uboot的启动流程。
Uboot-1.3.4中对at91rm9200dk系列的开发板有很好的支持,只需做少量修改即可使用。
但是在目前U-Boot-1.3.4引导系统中,不能识别本论文中采用的8MBNORFlash(SPANSION公司的S29GL064N90TFI04)和1GBNANDFlash(SAMSUNG公司的K9K8G08U0A)两款芯片,需要自行移植。
4.Linux的编译,内核配置和裁剪
4.1Linux的编译
在配置内核前的须做必要的设置,主要在内核原码中设置文件Makefile,用下列指令打开Makefile文件:
$viMakefile
在Makefile中主要设置两个地方:
ARCHCROSSCOMPILE。
ARCH:
=arm;表示目标板为arm。
CROSSCOMPILE=交叉编译工具的地址;设置交叉编译工具的地址,例如CRoSSCOMPILE=lusr/10cal/arm/2.95.3、birdarm.1inux。
还要在脚本文件mkimage中把路径改为9200/bootldr/u-boot-1.0.O/tools。
(具体的路径和你的u-boot放的位置有关)然后按如下命令顺序进行内核编译即可:
内核配置:
Smakemenuconfig或makcxeon!
ig
内核编译:
Smaketiean$makedep$make$./mkimage;运行mkimage脚本文件
4.2嵌入式Linux的配置和剪裁
在Linux下,用makemenuconfig或makexeontig进入配置界面。
在内核配置中,一般有四种选择:
Y(选择)、N(不选)、M(模块)和数字,用户可以根据剪裁需要进行设置,最后配置完毕,选择是否对配置结果进行保存?
保存为.eonfig文件。
5.嵌入式Linux文件系统的制作过程
嵌入式系统可以使用硬盘和光盘,但是这与嵌入式系统的便携式特性相违背,所以一般采用Flash作为存储介质。
和硬盘相比,Flash有自己独特的物理特性,所以必须使用专门的文件系统。
嵌入式系统对文件的操作是通过层次结构实现的。
对于用户程序来说,文件是有结构的文件,用户程序通过文件I/O函数操作文件。
嵌入式文件系统是嵌入式系统的一部分,它的任务是对逻辑文件进行管理,其工作包括提供对逻辑文件的操作(复制、删除、修改等)接口,方便用户操作文件和目录。
在文件系统的内部,又根据存储设备的特点,适用不同的文件组织模式来实现文件的逻辑结构,比如磁带终使用的顺序文件以及大多数操作系统适用的树状文件。
此外,文件系统要对管理文件的安全性负责。
目前支持闪存的文件系统技术有以下几种:
eJFFS2和Yaffs。
这些文件系统可以使用在没有初始化的NANDFlash和有CFI接口的NORFlash中。
eTrueFFS,该文件系统相当于Linux中的MTD层,必须配合其他文件系统。
eFTL/NTFL,它是一种中间层解决方案的统称,为上层文件系统提供接口。
eRAMFS、CRAMFS和ROMFS,这些文件系统用于早期的小容量闪存设备,系统
功能比较简单,仅提供基本接口,只属于只读的闪存文件系统。
适合存储空间小的系统。
可按照如下步骤制作自己的文件系统:
解开压缩的文件系统:
$gamzipramdisk.gz
文件系统挂载:
$mount_oloopramdisk/mnt/nweramdisk(注:
newramdisk是新建的目录)。
进入newramdisk目录进行操作,随意的增减文件:
Sod/nmt/newramdisk(注:
进入目录后敲入命令随意的增减文件)
退出newramdisk目录后御载文件系统:
Sumount/mnt/newramdisic
压缩文件系统,生成新的文件系统映象:
$gzip-c-、,9ramdisk>./newramdisk
6.Linux中交叉编译器的搭建和环境变量的设置
1. 安装标准的C开发环境,由于Linux安装默认是不安装的,所以需要先安装一下(如果已经安装好的话,就可以免去这一步了):
#sudoapt-getinstallgccg++libgcc1libg++makegdb
2. 下载arm-linux-gcc-3.4.1.tar.bz2到任意的目录下。
3. 解压arm-linux-gcc-3.4.1.tar.bz2
#tar-jxvfarm-linux-gcc-3.4.1.tar.bz2
解压过程需要一段时间,解压后的文件形成了usr/local/文件夹,进入该文件夹,将arm文件夹拷贝到/usr/local/下
#cdusr/local/
#cp-rvarm/usr/local/
现在交叉编译程序集都在/usr/local/arm/3.4.1/bin下面。
4. 修改环境变量,把交叉编译器的路径加入到PATH。
方法一:
修改/etc/bash.bashrc文件
#vim/etc/bash.bashrc
在最后加上:
exportPATH=$PATH:
/usr/local/arm/3.4.1/bin
exportPATH
方法二:
修改/etc/profile文件:
#vim/etc/profile
增加路径设置,在末尾添加如下,保存/etc/profile文件:
exportPATH=$PATH:
/usr/local/arm/3.4.1/bin
方法三:
#exportPATH=$PATH:
/usr/local/arm/3.4.1/bin
注:
(这只能在当前的终端下才是有效的!
)
5. 立即使新的环境变量生效,不用重启电脑:
对应方法一:
#source/root/.bashrc
对应方法二:
#source/etc/profile
6. 检查是否将路径加入到PATH:
#echo$PATH
显示的内容中有/usr/local/arm/bin,说明已经将交叉编译器的路径加入PATH。
至此,交叉编译环境安装完成。
7.测试是否安装成功
#arm-linux-gcc-v
上面的命令会显示arm-linux-gcc信息和版本:
Readingspecsfrom/usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/specs
Configuredwith
:
/work/crosstool-0.27/build/arm-linux/gcc-3.4.1-glibc-2.3.2/gcc- 3.4.1/configure--target=arm-linux--host=i686-host_pc-linux-gnu
--prefix=/usr/local/arm/3.4.1--with-headers=/usr/local/arm/3.4.1/arm
-linux/include--with-local-prefix=/usr/local/arm/3.4.1/arm-linux--disable
-nls--enable-threads=posix--enable-symvers=gnu--enable-__cxa_atexit--enable- languages=c,c++--enable-shared--enable-c99--enable-long-long
Threadmodel:
posix
gccversion3.4.1
8.编译HelloWorld程序,测试交叉工具链
写下下面的HelloWorld程序,保存为hello.c
#include
intmain()
{
printf("HelloWorld!
/n");
return0;
}
执行下面的命令:
#arm-linux-gcc-ohellohello.c
-------------------------------------------------------------
修改环境变量这一步修改/etc/profile文件
在path中添加arm-linux-gcc路径
if["`id-u`"-eq0];then
PATH="/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:
/bin:
/usr/local/arm/3.4.1/bin"
else
PATH="/usr/local/bin:
/usr/bin:
/bin:
/usr/games"
fi
再source/etc/profile就可以刷新环境变量
7.驱动程序的编写过程与关键点
7.1Linux网络驱动程序的结构
所有的Linux网络驱动程序遵循通用的接口。
设计时采用的是面向对象的方法。
一个设备就是一个对象(device 结构),它内部有自己的数据和方法。
每一个设备的方法被调用时的第一个参数都是这个设备对象本身。
这样这个方法就可以存取自身的数据(类似面向对象程序设计时的this引用)。
一个网络设备最基本的方法有初始化、发送和接收。
|deliver packets | |receive packets queue|
|(dev_queue_xmit())| |them(netif_rx()) |
------------------- ---------------------
| methods and variables(initialize,open,close,hard_xmit,|
| interrupt handler,config,resources,status...)
-------------------------------------------------------
| | ----------------------
|send to hardware | |receivce from hardware|
-----------------------------------------------------
| hardware media |
-----------------------------------------------------
初始化程序完成硬件的初始化、device中变量的初始化和系统资源的申请。
发送程序是在驱动程序的上层协议层有数据要发送时自动调用的。
一般驱动程序中不对发送数据进行缓存,而是直接使用硬件的发送功能把数据发送出去。
接收数据一般是通过硬件中断来通知的。
在中断处理程序里,把硬件帧信息填入一个skbuff结构中,然后调用netif_rx()传递给上层处理。
7.2 网络驱动程序的基本方法
网络设备做为一个对象,提供一些方法供系统访问。
正是这些有统一接口的方法,掩蔽了硬件的具体细节,让系统对各种网络设备的访问都采用统一的形式,做到硬件无关性。
下面是最基本的方法。
(1) 初始化(initialize)
(2)打开(open)(3)关闭(stop)
(4) 发送(hard_start_xmit)(5) 接收(reception)(6)硬件帧头(hard_header)(7) 地址解析(xarp)
(8) 参数设置和统计数据
7.3 网络驱动程序中用到的数据结构
最重要的是网络设备的数据结构。
定义在include/linux/netdevice.h里。
7.4 常用的系统支持
7.4.1 内存申请和释放
include/linux/kernel.h里声明了kmalloc()和kfree()。
用于在内核模式下申请和释放内存。
Void *kmalloc(unsigned int len,int priority);
void kfree(void *__ptr);
与用户模式下的malloc()不同,kmalloc()申请空间有大小限制。
长度是2的整次方。
可以申请的最大长度也有限制。
另外kmalloc()有priority参数,通常使用时可以为GFP_KERNEL,如果在中断里调用用GFP_ATOMIC参数,因为使用GFP_KERNEL则调用者可能进入sleep状态,在处理中断时是不允许的。
Kfree()释放的内存必须是kmalloc()申请的。
如果知道内存的大小,也可以用kfree_s()释放。
7.4.2 request_irq()、free_irq()
这是驱动程序申请中断和释放中断的调用。
在include/linux/sched.h里声明。
Request_irq()调用的定义:
int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,
void *dev_id);
irq是要申请的硬件中断号。
在Intel平台,范围0--15。
Handler是向系统登记的中断处理函数。
这是一个回调函数,中断发生