单击此处编辑母版标题样式,,单击此处编辑母版文本样式,,第二级,,第三级,,第四级,,第五级,,*,*,*,嵌入式系统开发与应用,第八章,uclinux,及应用开发,主要内容,8.1,,linux,介绍,,8.2,,µ,Clinux,简介,,8.3,µ,Clinux,中的应用程序开发,,8.4,如何,构造嵌入式,linux,系统,,,8.5,实验理论部分,8.1,,linux,介绍,8.1.1,linux,简介,,8.1.2,linux,特点,,8.1.3,linux,作为嵌入式操作系统的优点,,,8.1.4,嵌入式,linux,的版本,,主要内容,8.1.1,简介,Linux,是个和,Unix,相似、以内核为基础的、完全内存保护、多任务多进程的操作系统Linux,最初是在,1991,年由一名芬兰学生,Linus,,Torvalds,开发的,至今不过,14,个年头,它是一个年轻的操作系统,最初开发的,Linux,不成熟、性能较低,但是,由于,Linux,具有开放性,任何人只要遵守,GNU,组织的,GPL,(,GNU Public License,),标准,都可对其源码进行修改所以,Linux,在短短的时间内就成了一个稳定、成熟的操作系统。
8.1.2,linux,特点,,1.,符合,POSIX 1003.1,标准,,,POSIX 1003.1,标准定义了一个最小,的,Unix,操作系统接口,只有符合这一标准,才可以运行,Unix,程序由于,Unix,具有丰富的应用程序,当今绝大多数操作系统都把满足,POSIX 1003.1,标准作为实现目标,,Linux,完全支持,POSIX 1003.1,标准另外,,,Linux,还增加了部分,System V,和,BSD,的系统接口使得,Unix System V,和,BSD,上的程序能直接在,,Linux,上运行,从而使,Linux,成为一个完善,的,Unix,程序开发系统linux,特点,2.,,支持多用户访问和多任务编程,,,Linux,是一个真正的多用户、多任务操作系统,它允许多个用户同时访问系统且不会造成用户之间的相互干扰而且,每一个用户可以创建多个进程,并使各个进程协同工作来完成用户的需求3.,,采用页式存储管理,,,与大多数操作系统一样,,Linux,支持页式存储管理它能使,Linux,更有效地利用物理存储空间,页面的换入换出为用户提供了更大的存储空间linux,特点,4.,,支持动态链接,,,用户程序的执行往往离不开标准库的支持,运行程序前,需要将标准库与程序链接好。
按照链接方式的不同有静态与动态两种一般的系统往往采用静态链接方式,即在装配阶段就已将用户程序和标准库链接好,这样,当多个进程运行时,可能会出现库代码在内存中有多个副本而浪费存储空间的情况;,Linux,支持动态链接方式,当运行时才进行库链接,如果所需要的库已被其它进程装入内存,则不必再装入,否则才从硬盘中将库调入这样能保证内存中的库程序代码是唯一的,也节省了内存,提高了程序的运行效率linux,特点,5.,,支持多种文件系统,,,Linux,能支持多种文件系统常见的有:,EXT,、,EXT2,、,HPFS,、,MSDOS,、,UMSDOS,、,PROC,、,NFS,、,SYSV,、,MINIX,、,SMB,、,UFS,、,NCP,、,VFAT,、,JFFS,Linux,最常用的文件系统是,EXT2/3,,,它是,EXT,文件的改进版本6.,,支持,TCP/IP,、,SLIP,和,PPP,,,在,Linux,中,用户可以使用所有的网络服务8.1.3linux,作为嵌入式操作系统的优点,1.,,可应用于多种硬件平台,Linux,已经被移植到多种硬件平台,这对受成本、时间限制的研究与开发项目是很有吸引力的。
可以在标准平台上开发然后移植到具体的硬件上,加快了软件与硬件的开发过程并降低了开发成本2.,,Linux,可以随意地配置而不需要任何的许可证或商家的合作关系3.,,它是免费的,源代码可以得到这是最吸引人的毫无疑问,这会节省大量的开发,,费用linux,作为嵌入式操作系统的优点,4.,,它本身内置网络支持,具有公认的强大的网络功能5.,,Linux,的高度模块化使添加部件非常容易6. Linux,在台式机上的成功,使大家看到了,linux,在嵌入式系统中的辉煌前景,8.1.4,嵌入式,linux,的版本,,,Linux,应用于嵌入式领域虽然时间不长,但已形成了许多版本,按照其实际应用的场合及特殊的功能需求,基本上可以分为以下,3,类:,,1.,将,Linux,改进以满足实时要求的实时操作系统,应用于一些关键的控制场合,,如,RT,-,Linux,,,Hard Hat Linux,2.,尽可能保留,Linux,的强大功能,尽可能地减少其体积,以满足许多嵌入式系统对体积的要求,如,µClinux,3.,针对特定嵌入式领域采用的整合方案,,如,Lineo,,,TimeSys,,,合肥华恒等,8.2µClinux,简介,,8.2.1 µ,Clinux,特色,,,8.2.2 µ,Clinux,的设计特征,,,主要内容,,,µClinux,是保留,Linux,的强大功能,但体积大大减少,是主要针对没有,MMU,的微处理器开发的一个嵌入式,Linux,版本。
µClinux,是,Linux2.0,版本的一个分支,被设计用来微型控制应用领域µClinux,单词中,µ,代表微型,,C,代表控制器,,µClinux,的含义就是,",针对微控制领域而设计的,Linux,系统,",,通常读,作“,you see,linux,”,8.2.1µClinux,特色,,通用,的,Linux API,,µ,Ckernel,<512 KB,,µ,Ckernel,+,工具,<900KB,,完整的,TCP/IP,协议堆栈,,,支持大量其它的网络协议,,,支持各种文件系统,包括,NFS,、,EXT2,、,ROMfs,、,JFFS,、,MS-DOS,以及,FAT16/32,,只支持没有,MMU,的微控制器,,8.2.2µClinux,的设计特征,,,1,、,µClinux,的内存管理,,,2,、,µClinux,的多进程处理,,3,、,µClinux,的实时性,,4,、执行程序的格式,,5,、文件系统,,6,、,标准,C,函数库,1,、,µClinux,的内存管理,,µClinux,同标准,Linux,的最大区别就在于内存管理标准,Linux,是针对,有,MMU,的处理器设计的。
在这种处理器上,虚拟地址被送到,MMU,,,MMU,把虚拟地址映射为物理地址通过赋予每个任务不同的虚拟,—,物理地址转换映射,支持不同任务之间的保护其,优点,是提供了比计算机系统实际物理内存大得多的内存空间,这样编程人员在编程时勿需考虑计算机中物理内存的实际容量缺点:,地址转换表和其他一些数据结构占据了内存空间,这样留给程序员的内存空间就减少了;同时地址转换增加了每一条指令的执行时间µClinux,不使用虚拟内存管理技术,采用的是,实存储器管理策略,也就是,µClinux,系统对于内存的访问是直接的,(它对地址的访问不需要经过,MMU,,,而是直接送到地址线上输出),分析,从易用性这一点来说,,,µClinux,的内存管理实际上是一种倒退,,退回到了,UNIX,早期或是,Dos,系统时代开发人员必须参与系统的内存管理从编译内核开始,开发人员就必须告诉系统这块开发板到底拥有多少的内存(假如你欺骗了系统,那将在后面运行程序时受到惩罚),从而系统将在启动的初始化阶段对内存进行分页,并且标记已使用的和未使用的内存系统将在运行应用程序时使用这些分页内存分析,从,内存的访问角度来看,,由于采用实存储器管理策略,,用户程序同内核在一个地址空间,操作系统对内存空间没有保护,。
因此,开发人员的,权利增大了,(开发人员在编程时可以访问任意的地址空间),但与此同时系统的,安全性也大为下降,总结,,µClinux,的内存管理与标准,Linux,系统相比功能相差很多,但当前这种不带有,MMU,的处理器在嵌入式设备中相当普遍原因是系统中实现,MMU,需要在软件及硬件上有些开销,比如说需要有一个,MMU,芯片,而大多数嵌入式应用对成本很敏感同时,地址转换表和其他一些数据结构占据了内存空间,这样留给程序员的内存空间就减少了;同时地址转换增加了每一条指令的执行时间而嵌入式设备通常运行在某一特定的环境下,只需实现特定的功能即可,功能相对也简单,这样就可以不使用,MMU,,,以减小生产成本及系统开销,linux,中创建进程是由,fork,调用实现的,但由于,µClinux,在存储管理方面的特点,在实现多进程时是通过,vfork,来实现,,在,µClinux,中,vfork,等于,fork,2,、,µClinux,的多进程处理,,3,、,µClinux,的实时,性,,,µClinux,本身并没有关注实时问题,它并不是为了,Linux,的实时性而提出的,,因此若将,µClinux,用于实时性要求较高的场合时,需要对其内核做必要的改进。
如:为,µClinux,添加,RT-Linux,的,patch,,,从而增强,µClinux,的实时性,使得,µClinux,可以应用于工业控制、进程控制等一些实时性要求较高的场合4,、执行程序的格式,,不管是内核还是应用程序,,µClinux,均使用,flat,可执行文件格式替代,elf,格式,,,elf,格式有比较大的文件头,,flat,文件格式简化了文件头和部分段信息5,、文件系统,,,µClinux,是,Linux,的扩展,因此,所有,Linux,支持的文件系统,,µ,Cinux,,都支持,为节省资源,,µClinux,一般使用专门为嵌入式系统设计的文件系统如,Romfs,,,JFFS,等,,这些文件系统较常用,的,ext2/3,占用更少资源,,,更支持压缩,,同时在内核中支持,romfs,文件系统相对来说只需要更少的代码,6,、,标准,C,函数库,,µClinux,使用嵌入式标准,C,函数库,µ,Clibc,或,µC-,libC,替代,libc,,,Linux,下使用的标准,C,函数库,libc,需要非常多的资源,,µ,Clibc,对,libc,做了精简,在,µClinux,中的应用程序均采用,静态连接的方式链接标准,C,函数,库,。
µC-,libc,是,µClinux,最初的函数库,,是,libc,的不完全的嵌入式实现,,部分函数接口不标准,,,还有部分函数未实现,目前主要使用在,Coldfire,和,ARM,结构µ,Clibc,函数库弥补了,µC-,libc,的一些问题,,如:使所有的函数接口标准化,填补未实现的函数,,µ,Clibc,目前已支持相当多的处理器结构,使用,µ,Clibc,能够对应用程序的移植提供更好的兼容性µ,Clibc,正在逐步的取代,µC-,libc,8.3µClinux,中的应用程序开发,,8.3.1,程序开发的基本流程,,,8.3.2,交叉开发环境,,,8.3.3,uCLinux,应用程序开发,,主要内容,8.3.1,程序开发的基本流程,建立开发环境,源文件,编译,下载,链接,C,语言程序*,.c,汇编源程序*,.s,目标文件,可,执行文件,8.3.2,交叉开发环境,,先在通用,PC,机上编程,然后通过交叉编译链接,将程序做成目标平台上可以运行的二进制代码格式最后将程序下载到目标平台上的特定位置由目标板上启动代码运行这段二进制代码交叉开发:我们把这种在一台通用计算机上进行软件的编辑编译,然后下载到嵌入式设备中运行调试的开发方式。
开发计算机一般称宿主机,嵌入式设备称为目标机,在宿主机上编译好的程序,下载到目标机上运行交叉开发环境一般由运行于宿主机上的交叉开发软件、宿主机到目标机的调试通道组成如在,µClinux,的开发过程中,需要安装交叉编译工具,arm-elf-,gcc,,调试时还需要,gdb,软件等8.3.3,uCLinux,应用程序开发,,,uClinux,是由,Linux2.0,版本发展来的,主要是针对没有内存管理单元,(MMU),的处理器和控制器而设计的部分标准,C,函数在标准,Linux,下可以使用而在,uClinux,下不能使用,因此,需要用户编写相应的库函数,但是绝大多数的函数还是通用的也就是说大多数函数不需要做太大的改动就可以编译成可以,在,uClinux,上运行的文件格式,总结,在嵌入,式,uClinux,中进行应用程序开发时,首先是在主机上编程并编译,然后经修改后用主机上建立的交叉编译环境生成,.elf,文件,,并用,elf2flat,工具将,.elf,文件转换为,.flat,文件,最后使用下载工具将文件下载到目标板上,并运行及调试8.4,如何,构造嵌入式,linux,系统,,8.4.1,构造嵌入式,Linux,系统的几个关键问题,,8.4.2,构造嵌入式,Linux,系统的关键步骤,,主要内容,8.4.1,构造嵌入,式,Linux,系统的几个关键问题,一个小型的嵌入,式,Linux,系统需要三个基本元素:,,u,,引导工具,,u,,Linux,微内核(由内存管理、进程管理和事务处理构成),,u,,初始化进程,,若想让它干点什么且继续保持小型化,还得加上,,u,,硬件驱动程序,,u,,提供所需功能的一个或多个应用程序,,若再增加功能,需要这些,,u,,一个文件系统(也许在,ROM,或,RAM,中),,u,,TCP/IP,网络协议栈,,u,,一个磁盘用来存放半易失性数据和提供交换能力,8.4.2,构造嵌入式,Linux,系统的关键步骤,,1,、建立交叉开发环境,,2,、安装,µClinux,内核,,3,、安装应用程序库,,8.5,实验理论部分,8.5.1,内核编译,,8.5.2,,Boot Loader,编译运行,,8.5.3,,内核启动加载的方式,,,8.5.4,,uClinux,应用程序开发,,8.5.5,下载及调试应用程序的方法,,8.5.6,,makefile,介绍,,8.5.7,将应用程序添加到文件系统的方法,,主要内容,8.5.1,内核编译,8.5.1.1,实验前的准备工作,,,8.5.1.2,配置及编译,uClinux,,,8.5.1.3,下载并运行,,主要内容,8.5.1.1,实验前的准备工作,,,1,、安装,uClinux,,源代码,,,cp /mnt/hda1/uClinux-s3cev40.tar.gz /root/,,,cd,/root,,,tar,zxvf,uClinux-s3cev40.tar.gz,2,、安装编译器,,cp /mnt/hda1/arm-elf-compiler.tar.gz /,usr,/local,,,tar,zxvf,arm-elf-,compiler.tar.gz,,,PATH=”/,usr/local/bin:$PATH,”,8.5.1.2,配置及编译,uClinux,1,、配置,uClinux,,,make,config,,,make,menuconfig,,,make,xconfig,,,,生成文件,.,config,,,保存配置信息。
下次配置时产生新的,.,config,文件,原来的,.,config,被改名为,.,config.old,配置及编译,2,、编译,uClinux,,,cd,/root/uclinux-s3cev40,,,make clean,,,make,xconfig,,,,make,dep,,,,make lib_only,,,make user_only,,,make,romfs,,,make image,配置及编译,最后,,在,images,目录下生成,2,个文件,,zImage,:,uClinux,,内核,2.4.x,的压缩方式执行映像文件,,,romfs.,img,:,文件系统的映像文件,8.5.1.3,下载并运行,1,、下载,,使用,Embest,S3CEV40,目标板附带的串口线连接目标板上的,UART0,和,PC,机的串口,,,,用,Embest,烧写工具软件进行烧写,加载,EmbestS3CEV40.cfg,目标板配置文件,将,bootloader.bin,烧写至,FLASH,的,1-16,扇区,,zImage,烧写至,17-192,扇区,,,romfs.img,烧写至,193-400,扇区,。
下载并运行,2,、运行,,,在,PC,机上运行,Windows,自带的超级终端串口通信程序(波特率,115200,、,1,位停止位、,8,位数据位、无校验位、无硬件流控制);或者使用其它串口通信程序重新启动目标板,运行,uclinux,8.5.2,,Boot Loader,编译运行,,8.5.2.1,简介,,,8.5.2.2,Boot Loader,设计,,,8.5.2.3,实验,例程,主要内容,8.5.2.1,简介,系统引导程序通常称为,Boot Loader,,,是在系统复位后执行的第一段代码,相当于,PC,上的,BIOS,以及商业实时操作系统中的板级支持,包,BSP,,,Boot Loader,首先完成系统硬件的初始化,包括时钟的设置、存储区的映射等,设置堆栈指针,然后跳转到操作系统内核的入口,将系统控制权交给操作系统,在此之后系统的运行,和,Boot Loader,再无任何关系Boot Loader,独立于操作系统,必须由用户自己设计Boot Loader,的实现高度依赖于硬件,包括处理器的体系结构、具体型号、硬件电路板的设计简介,Boot Loader,、,内核映像和文件系统映像在系统中的存储的典型空间分配结构图如下:,,,,,,,典型空间分配结构图,8.5.2.2 Boot Loader,设计,,1,、最简功能设计要求,禁止所有的中断;,,设置处理器时钟、运行速度;,,存储区初始化;,,设置堆栈指针将,bss,段清零;,,跳转到内核映像的入口,,Boot Loader,设计,上电自检;,,支持串口通讯方式,提供串口方式的命令控制台;,,支持以太网通讯方式,提供以太网通讯方式的命令控制台;,,可以通过串口或以太网下载并引导内核和文件系统映像文件;,2,、完备功能设计要求,8.5.3,,内核启动加载的方式,8.5.3.1,内核提供方式,,,8.5.3.2,内核加载及启动方式,,,主要内容,8.5.3.1,内核提供方式,(,1,)压缩形式内核:固化,在,Flash,中,由,uClinux,提供的解压复制程序将内核解压后复制到,RAM,中运行;,,(,2,)正常未压缩的内核:可以先固化在,Flash,中,由,Boot Loader,复制到,RAM,中运行,显然这样更浪费,Flash,存储空间;故一般通过,Boot Loader,提供的串口、网络下载功能直接,从,PC,机下载到系统,的,RAM,中,然后由,Boot Loader,的启动内核功能启动,这种方式主要用来工程师的内核调试。
8.5.3.2,内核加载及启动方式,(1,),Flash,本地运行方式:内核的未经压缩的可执行映像固化在,Flash,,,系统启动时内核在,Flash,中开始逐句执行2,)压缩内核加载方式:内核的压缩映像固化,在,Flash,上,系统启动时由附加在压缩映像前的解压复制程序读取压缩映像,在内存中解压后执行,这种方式相对复杂,但是运行速度更快,(,RAM,的存取速率要,比,Flash,高)8.5.4,,uClinux,应用程序开发,一、将,Linux,下的应用程序移植到,uCLinux,,下,时,需要注意的限制,,二、应用程序开发步骤,主要内容,一、将,Linux,下的应用程序移植,到,uCLinux,下时,需要注意有以下限制,,1,),uC-libc,中不带有,pthread,库,要进行多线程编程,只能选择,select,函数2,),uClinux,系统中由于内存管理的问题,没有,fork,(),函数,用,vfork,(),代替,因为,uClinux,,系统中没有真正的,fork,,,多进程实际是使用,vfork,实现的,子进程执行完后父进程才继续执行3,),uClinux,所用的,Libc,库不是一个全功能的库,而是一个适合嵌入式应用的功能有限的库,对于一些不太常用的函数可能库里没有,需要用户自己编写。
4,)堆栈有限制,现在堆栈大小限制在,4K,字节,你可以用如下方法增加堆栈的大小:在使用,elf2flt,工具软件时加上,“,-s,”,参数二、应用程序开发步骤,,1,、,在,Linux,下编写源程序,example.c,,,确认编译生 成的程序,example,能在,Linux,下正确执行#,gcc,–o example example.c,,#,./example,,,2,、,按照移植注意事项改写源代码,example.c,,,改写 以后的文件命名为,example_uc.c,3,、,使用交叉编译工具编译,example_uc.c,,,生成,,example_uc,执行文件编译命令如下:,,,,$arm-elf-,gcc,–o,example_uc,,example_uc.c,–elf2flt,,,4,、,下载并执行,,对于下载方法我们介绍两种最经常使用的下载调试应用程序的方法,:,8.5.5,下载及调试应用程序的方法,,8.5.5.1,下载方法,FTP,与,TFTP,,8.5.5.2,uClinux,应用程序调试方法,下载方法,FTP,与,TFTP,文件传输协议,FTP,是,Internet,上使用得最广泛的文件传输协议。
在嵌入式开发中使用,FTP,方式下载应用程序时,是,在,PC,即宿主机上建立,FTP,服务器,然后,在,uClinux,的超级终端窗口启动,FTP,客户程序,执行,FTP,命令下载应用程序到目标板的指定目录中简单文件传输协议,TFTP,全称,为,Trivial File Transfer Protocol,,,适合小型文件传输,比较小并且容易实现在,uClinux,的相关开发过程中,更经常地使用,TFTP,下载方法,1,、在,Win2000,操作系统下建立,TFTP,服务器,,,运行,TFTP,服务器程序,tftpd32.exe,,,进行各种工作状态、权限以及本地,tftp,工作目录的设置,默认状态下可以直接进行工作,本地,tftp,工作目录即当前目录,,,2,、在,uClinux,的超级终端窗口执行,TFTP,客户端命令连接服务器程序,tftpd32,,,直接下载文件(如,LED,灯控制程序)到,var,目录,修改权限后运行:,,,,tftp,-g -l /,var/example_uc,-r,example_uc,192.168.0.35,,,cd,/,var,,,/,var,>,chmod,777,example_uc,,,/,var,> ./,example_uc,,8.5.6,,makefile,介绍,程序大型化、复杂化是嵌入式软件发展的必然趋势。
如何维护和管理程序就是个突出和紧迫的问题高级语言编程所形成的模块之间不可避免的存在着相互的联系和制约,而且其关系也非常复杂这样,如果某个模块需要改动、更换或者删除,那么需要把与该程序相关的所有程序都重新编译、链接这样不仅需要程序员找出与该程序相关的其它程序,并且需要使用长而复杂的命令对其逐一进行编译、链接这对程序员来讲不仅费时费力而且易出错针对以上问题,,GNU,为我们推出了,make,项目管理工具,Make,项目管理工具能够自动确定需要重新编译的文件,并对它们进行重新编译,然后链接生成执行文件Make,项目管理工具是通过,makefile,来完成这一工作的,它对大型项目软件的开发是很有必要的Make,管理项目把所用的命令行保存到,Makefile,文件中,简化了编译工作Make,管理项目可以减少重新编译所需要的时间,它可以识别出,makefile,中哪些文件已经修改,并且在再次编译时只编译这些文件,这样提高了编译的效率Make,管理项目还在数据库中维护了当前开发工程中各个文件的依赖关系,在编译前就可以确定是否能找到所需文件要完成,Make,管理项目的工作必须编写,makefile,,,makefile,是一个文本形式的数据库文件,其中包含一些规则来告诉,Make,编译哪些文件以及怎样编译这些文件。
每条规则包含以下内容:,,,l,,一个,target,,是,Make,最终要创建的文件,,l,,一个或多个,dependencies,列表,是编译生成目标文件所需的其他文件,,l,,需要执行的,commands,,,用于从指定的文件处生成目标文件,,,一个简单,的,makefile,规则可以使用如下代码表示,:,target:dependency file1 dependency file2[…],,command1,,command1,,[…],注意:每一个命令的第一个字符必须是制表符,仅使用,8,个空格是不行的否则,make,会显示出错信息其中:,target,是要创建的目标文件或者,linux,系统支持格式的可执行文件,dependency,fileN,是创建,target,需要的依赖文件列表CommandN,是创建,target,时使用的命令组,是包括,make,在内的许多,shell,命令的集合此外,除非特别指定,否则,make,的工作目录就是当前目录还要注意“,#,”,号以后的文字为注释 a simple,makefile,,square,:,square.o Length.o width.o,,#,gcc,–o square square.o Length.o width.o,,square.o,:,square.c square.h Length.h width.h,,#,gcc,–c square.c,,Length.o,:,Length.c Length.h,,#,gcc,–c Length.c,,width.o,:,width.c,,#,gcc,–c width.c,,clean:,,,rm,,edito,*.o,一个简单,的,makefile,实例,。
makefile,文件编写好以后,,在,makefile,所在目录下键入,make,就可编译,square,这个,makefile,有,5,条规则第,1,条规则用于创建默认的目标,square,,,,它有,3,个依赖文件:,square.o,、,Length.o,和,width.o,在编译,square,时这些文件必须存在第,2,行是,,make,为创建,square,所要执行的命令,后面的三条规(,4,~,9,行)则告诉,make,如何逐个生成那些依赖文件Clean,用来清除编译过程中的中间文件通常情况下,如果试图在依赖文件不存在的情况下使用第二行所示的命令来编译,square,,,gcc,将会出错并退出;,而,make,则在生成,square,前先检查所需要的依赖文件是否存在,如果不存在,则先执行别的规则以生成缺少的依赖文件,最后才编译依赖性最强的目标如果,square.o,、,Length.o,和,width.o,已经存在,则它不急于再次运行后面的规则,而是比较这些依赖文件与其对应的源文件的生成时间,如果判定有一个或者多个源文件新于这些依赖文件,,make,才重新编译生成这些文件以反映相关源文件的最新变化,否则使用旧的依赖文件完成目标,square,的编译。
至此,这个小小的,makefile,显示了它强有力的自动查找、比较、编译等功能,它的用处是显而易见的在编写,makefile,时我们会使用一些常用的诸如,clean,、,install,、,dist,、,tags,、,depend,、,test,、,check,、,installtest,以及,installcheck,的目标名目标,名,clean,一般用来清除编译过程中的中间文件,install,目标名常会把最终的二进制文件、所支持的库文件,和,shell,脚本以及相关文档移到文件系统中与它对应的位置,同时设置文件的权限和所有者Uninstall,用来删除,install,目标安装的文件,Dist,常常用于删除编译工作目录中旧的二进制文件和目标文件并且创建归档文件Tags,用来更新或创建程序的标记表Depend,用来设置,makefile,文件中各个目标所需要的依赖文件列表installtest,和,installcheck,一般用于验证,install,目标的安装过程,5.2.4.7,将应用程序添加到文件系统的方法,一、 编写,Makefile,,,二、,,修改配置相关文件,,,三、 快速添加应用程序,,一、编写,Makefile,1,、使用,Vi,在,/user/app/,下编写,,hello.c,文件,#include <,stdio.h,>,,int,main(void) {,,printf("Hello,world!\n");,,return 1;,,},2,、编写,Makefile,,EXEC = hello,,OBJS = hello.o,,all: $(EXEC),,$(EXEC): $(OBJS),,$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS),,romfs,:,,$(ROMFSINST) /bin/$(EXEC),,clean:,,,,-,rm,-f $(EXEC) *.elf *.,gdb,*.o,二、,,修改配置相关文件,1,、,修改,./,config/config.in,,在最后面增加菜单:,,###############################,,mainmenu_option,next_comment,,comment'User Application',,bool,'Hello‘CONFIG_USER_HELLO,,comment "User Application",,endmenu,,,##################################,,或者在合适的菜单块中增加一行:,,bool,'Hello' CONFIG_USER_HELLO,二、,,修改配置相关文件,CONFIG_USER_HELLO,,This program print hello on screen.,注意:,,描述文本必须缩进两空格,不能包括空行且必须少于,70,个字符,2,、修改,./,config/Configure.help,Configure.help,包含配置时显示的描述文本,在文件中增加:,,修改配置相关文件,增加行,,,dir_$(CONFIG_USER_HELLO) += app,,3,、修改用户程序工程管理文件,,user/,Makefile,三、,快速添加应用程序,1,、编译生成可执行文件,,,输入以下命令直接编译程序源代码文件,对于复杂一点的工程可以使用上节中的,Makefile,:,,,,2,、,复制可执行文件到文件系统,,,,在执行,make,romfs,命令时会生成,romfs,文件夹,它是生成的文件系统目录,因此如果已经执行过,make,romfs,命令,用户可将生成的可执行文件,hello,复制到,romfs,/bin,目录,不必重复该命令。
注意,:如果用户执行了,make clean,命令,,romfs,下的全部内容将被清除arm-elf-,gcc,–Wall –O2 -Wl,-elf2flt –o hello hello.c,3,、,,生成文件系统映像,,,直接执行下面的命令生成文件系统映像,romfs.img,:,,,genromfs,-v -V ",ROMdisk," –f,romfs.img,-d /root/uclinux-s3cev40/romfs,,,这里的文件系统映像,romfs.img,包含了新增的应用程序,hello,genromfs,-v -V ",ROMdisk," –f,romfs.img,-d /root/uclinux-s3cev40/romfs,。