第9章基于ARM9和Linux嵌入式系统设计.ppt

上传人:本田雅阁 文档编号:2502295 上传时间:2019-04-04 格式:PPT 页数:136 大小:947.51KB
返回 下载 相关 举报
第9章基于ARM9和Linux嵌入式系统设计.ppt_第1页
第1页 / 共136页
第9章基于ARM9和Linux嵌入式系统设计.ppt_第2页
第2页 / 共136页
第9章基于ARM9和Linux嵌入式系统设计.ppt_第3页
第3页 / 共136页
亲,该文档总共136页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第9章基于ARM9和Linux嵌入式系统设计.ppt》由会员分享,可在线阅读,更多相关《第9章基于ARM9和Linux嵌入式系统设计.ppt(136页珍藏版)》请在三一文库上搜索。

1、第9章 基于ARM9和Linux嵌入式系统设计,9.1 嵌入式Linux的开发环境 9.2 Linux开发工具的使用 9.3 GNU make命令和makefile 文件 9.4 嵌入式Linux引导程序 9.5 嵌入式Linux 下程序调试应用举例,9.1 嵌入式Linux的开发环境,9.1.1 嵌入式Linux开发环境建立 嵌入式Linux 开发环境有几个方案: (1)在WINDOWS 下安装Linux虚拟机后,目前大多情况下使用VWare软件; (2)直接安装 Linux 操作系统。,9.1.2 嵌入式Linux开发的一般过程,1.了解硬件 ; 2.准备需要使用的Linux工具以及其他工

2、具 ; 3.安排内存地址 ; 4.编写启动代码和机器相关代码 ; 5.编写驱动程序; 6.C库、GUI和系统程序的移植; 7.调试 .,9.2 Linux开发工具的使用 9.2.1 Linux开发工具GNU gcc的使用,1. GCC简介 GCC是GNU Compiler Collection的简称,GCC是Linux平台下最常用的编译程序,是Linux平台编译器的事实标准。 GCC支持的体系结构有40余种,常见的有x86系列、Arm、PowerPC等。同时,GCC还能运行在不同的操作系统上,如Linux、Solaris、Windows等。 GCC除了支持C语言外,还支持多种其他语言,例如C+

3、、Ada、Java、Objective-C、Fortram、Pascal等。,2. GCC常用模式及选项 gcc最基本的用法是: gcc options file. 其中option是以“-”开始的各种选项,file是相关的文件名。在使用gcc的时,必须给出必要的选项和文件名。gcc的整个编译过程分别是:预处理、编译,汇编和链接。,例如,$ gcc -o hello hello.c gcc编译器就会生成一个hello的可执行文件。在hello.c的当前目录下执行./hello。 gcc编译器生成的目标文件默认格式为elf(executive linked file)格式,是Linux系统所采用

4、的可执行链接文件的通用文件格式。elf格式由若干个段(section)组成,由标准c源代码生成的目标文件中包含以下段: .text(正文段)包含程序的指令代码。 .data(数据段)包含固定的数据,如常量,字符串等。 .bss(未初始化数据段)包含未初始化的变量和数组等。 GCC常用两种模式:编译模式和编译连接模式。,例:假设全部的源代码都在一个文件test.c中。 $ gcc -o test 此命令是把源文件test.c直接编译成可执行程序test。 $ gcc -c test.c 此命令是把源文件test.c编译成不可执行目标文件test.o。默认情况下,生成的目标文件名为test.o,但

5、也可以为输出文件指定名称,如下所示: $ gcc -c test.c o mytest.o 此命令是把源文件test.c编译成不可执行目标文件mytest.o。 下面的命令将同时编译3个源文件,即first.c、second.c和 third.c,然后将它们连接成一个可执行程序test。命令如下: $ gcc -o test first.c second.c third.c,3其他常用选项的使用 $ gcc test.c I/inc -o test 此命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。如果在编译时需要的包含文件存放在多个目录下,可使用多个-I 来指定各个目录。

6、如: $ gcc test.c I/inc I/inc2 -o test 此命令指出了另一个包含子目录inc2,较之前目录它还要在再上两级才能找到。另外,还可在编译命令行中定义符号常量。可简单的在命令行中使用-D选项即可,如下例所示: $ gcc D TEST_CONFIGURATION test.c -o test 上面的命令与在源文件中加入下列命令是等效的: #define TEST_CONFIGURATION,3其他常用选项的使用 $ gcc test.c I/inc -o test 此命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。若在编译时需要的包含文件存放在多个

7、目录下,可使用多个-I 来指定各个目录: $ gcc test.c I/inc I/inc2 -o test 上面命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。若在编译时需的包含文件存放在多个目录下,可使用多个-I 来指定各个目录: $ gcc test.c I/inc I/inc2 -o test 这里指出了另一个包含子目录inc2,较之前目录它还要在再上两级才能找到. 另外,我们还可以在编译命令行中定义符号常量。为此,我们可以简单的 在命令行中使用-D选项即可,如下例所示: $ gcc -DTEST_CONFIGURATION test.c -o test 上面的命令

8、与在源文件中加入下列命令是等效的: #define TEST_CONFIGURATION,4. 警告功能 当GCC在编译过程中检查出错误,则中止编译;但检测到警告时却能继续编译生成可执行程序。 在众多的警告选项之中,最常用的是-Wall选项。该选项能发现程序中一系列的常见错误警告,举例如下: $ gcc -Wall test.c -o test 该选项相当于同时使用了下列所有的选项: unused-function:遇到仅声明过但尚未定义的静态函数时发出警告。 unused-label:遇到声明过但不使用的标号的警告。 unused-parameter:从未用过的函数参数的警告。 ,9.2.2

9、 GDB调试器简介 Linux系统中包含了GNU 调试程序gdb,用来调试C和 C+ 程序的调试器。gdb 提供如下功能: 运行程序,设置所有的能影响程序运行的参数和环境。 控制程序在指定的条件下停止运行。 当程序停止时,可以检查程序的状态。 修改程序的错误,并重新运行程序。 动态监视程序中变量的值。 可以单步执行代码,观察程序的运行状态。,1gdb的启动 在终端窗口中,有两种方法运行gdb,即在终端窗口的命令行中直接输入gdb命令或gdb filename命令运行gdb。 方法1: 先启动gdb后执行file filename命令。即 gdb file filename 执行上述两条命令就可

10、启动gdb,并装入可执行的程序filename。 方法2: 启动gdb的同时装入可执行的程序。即 gdb filename 其中,filename是要调试的可执行文件。这和启动gdb后执行file filename命令效果完全一样。 启动gdb后,就可以使用gdb的命令调试程序。,2gdb的基本命令 gdb中的命令分为以下几类:工作环境相关命令、设置断点与恢复命令、源代码查看命令、查看运行数据相关命令及修改运行参数命令。gdb的命令可以通过help命令进行查找命令所属的种类(class),可以从相关class找到相应命令。如下所示: (gdb) help 此命令可列出命令的种类。 (gdb)

11、help data 此命令查找data类种的命令,并列出data类种的所有命令。 (gdb) help call 此命令查找call命令。 直接键入“help command”来查看命令。,(1)工作环境相关命令,(2) 设置断点与恢复命令,(3)gdb中源码查看相关命令,(4) gdb中查看运行数据相关命令,(5)其他gdb命令 run命令:执行当前被调试的程序。 kill命令:停止正在调试的应用程序。 watch命令:设置监视点,监视表达式的变化。 awatch命令:设置读写监视点。当要监视的表达式被读或写时将应用程序挂起。它的语法与watch命令相同。 rwatch命令:设置读监视点,当

12、监视表达式被读时将程序挂起,等侍调试。此命令的语法与watch相同。, info break命令:显示当前断点列表,包括每个断点到达的次数。 info files命令:显示调试文件的信息。 info func命令:显示所有的函数名。 info local命令:显示当前函数的所有局部变量的信息。 info prog命令:显示调试程序的执行状态。 Shell命令:执行Linux Shell命令。 make命令:不退出gdb而重新编译生成可执行文件。 Quit命令:退出gdb。,(6) gdb中修改运行参数相关命令 gdb可修改运行时的参数,并使该变量按照用户当前输入的值继续运行。 方法为:在单步执

13、行的过程中,键入命令: set 变量设定值 在此之后,程序就会按照该设定的值运行了。 特别注意,在gcc编译选项中一定要加入”-g”。只有在代码处于“运行”或“暂停”状态时才能查看变量值,设置断点后程序在指定行之前停止。,9.3 GNU make命令和makefile 文件 显式规则 隐晦规则 文件指示。其包括3个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。 注释。Makefile中只有行注释,用“#”字符 在Makefile

14、中的命令,必须要以Tab键开始。,GNU的make工作时的执行步骤如下: 1. 读入所有的Makefile。 2. 读入被include的其它Makefile。 3. 初始化文件中的变量。 4. 推导隐晦规则,并分析所有规则。 5. 为所有的目标文件创建依赖关系链。 6. 根据依赖关系,决定哪些目标要重新生成。 7. 执行生成命令。,9.3.1 Makefile文件的规则 1Makefile书写规则 Makefile文件含有一系列的规则,规则内容: 一个目标(target),即make最终需要创建的文件,如可执行文件和目标文件;目标也可以是要执行的动作,如clean。 一个或多个依赖文件(de

15、pendency)列表,通常是编译目标文件所需要的其他文件。 一系列命今(command),是make执行的动作,通常是把指定的相关文件编译成目标文件的编译命令,每个命令占一行,且每个命令行起始字符必须为TAB字符。,Makefile规则的一般形式如下: target:dependency dependency (tab) 例如:有以下的Makefile文件: test:prog.o code.o gcc o test prog.o code.o prog.o:prog.c prog.h code.h gcc c prog.c o prog.o code.o:code.c code.h gcc

16、 c code.c o code.o clean: rm f *.o,一般情况下,调用make命令可输入: # make target target是Makefile文件中定义的目标之一,如果省略target,make就将生成Makefile文件中定义的第一个目标。对于上面Makefile的例子,单独的一个make命令等价于: # make test 因为test是Makefile文件中定义的第一个目标,make首先将其读入,然后从第一行开始执行,把第一个目标test作为它的最终目标,所有后面的目标的更新都会影响到test的更新。,内核源代码中Makefile被分布在目录树中,与Makefil

17、e直接相关的文件有配置文件.config和规则文件Rules.make。顶层Makefile是整个内核配置、编译的总体控制文件。在顶层Makefile中的语句: include arch/$(ARCH)/Makefile 包含了特定CPU体系结构下的Makefile,这个Makefile中包含了平台相关的信息。配置文件.config包含由用户选择项,用来存放内核配置后的结果(如make config)。位于各种CPU体系目录下的Makefile,比如drivers/Makefile,负责所在子目录下源代码的管理。规则文件Rules.make,则被所有的Makefile使用。,用户通过make

18、config配置后,产生了.config。顶层Makefile读入.config中的配置选择。顶层Makefile有两个主要的任务:产生压缩的内核镜像vmlinux文件和内核模块module。为了达到此目的,顶层Makefile递归的进入到内核的各个子目录中,分别调用位于子目录中的Makefile。至于到底进入哪些子目录,取决于内核的配置。位于各个子目录下的Makefile同样也根据.config给出的配置信息,构造出当前配置下需要的源文件列表,并在文件的最后有include $(TOPDIR)/ Rules.make。,2. 在规则中使用通配符 make支持3种通配符:“*”,“?”和“.”

19、。 波浪号(“”)字符在文件名中有特殊的用途。如“test”表示当前用户的$HOME目录下的test目录。而“hchen/test”则表示用户hchen的宿主目录下的 test目录。通配符 “*.c”表示所有以后缀为c的文件。 例如: print: *.c lpr -p $? touch print 该例说明目标print依赖于所有的.c文件。其中的“$?”是一个自动化变量。,3.伪目标 伪目标又称假想目标,如: clean: rm *.o temp 这里并不生成“clean”这个文件。“伪目标”并不是一个文件,只是一个标签,由于“伪目标”不是文件,所以make无法生成它的依赖关系和决定它是否

20、要执行。 可使用“make clean”来使用该目标。 如果你的Makefile需要生成若干个可执行文件,可把所有的目标文件都写在一个Makefile中,可声明了一个“all”的伪目标。,声明了一个“all”的伪目标 例如: all : prog1 prog2 prog3 prog1 : prog1.o utils.o cc -o prog1 prog1.o utils.o prog2 : prog2.o cc -o prog2 prog2.o prog3 : prog3.o sort.o utils.o cc -o prog3 prog3.o sort.o utils.o,9.3.2 Mak

21、efile文件中隐含规则 1常用的隐含规则 编译C程序的隐含规则:.o的目标的依赖目标会自动推导为.c,并且其生成命令是 $(CC) c $(CPPFLAGS) $(CFLAGS)。 编译C+程序的隐含规则:.o的目标的依赖目标会自动推导为.cc或是.C,并且其生成命令是$(CXX) c $(CPPFLAGS) $(CFLAGS)。(建议使用.cc作为C+源文件的后缀,而不是.C), 汇编和汇编预处理的隐含规则:.o的目标的依赖目标会自动推导为.s,默认使用编译器as,并且其生成命令是:$(AS) $(ASFLAGS)。.s的目标的依赖目标会自动推导为.S,默认使用C预编译器cpp,并且其生成

22、命令是:$(AS) $(ASFLAGS)。 链接Object文件的隐含规则目标依赖于.o,通过运行C 的编译器来运行链接程序生成(一般是ld),其生成命令是:$(CC) $(LDFLAGS) .o $(LOADLIBES) $(LDLIBS)。这个规则对于只有一个源文件的工程有效,同时也对多个Object文件(由不同的源文件生成)也有效。,2隐含规则使用的变量 (1)关于命令的变量。 AR :函数库打包程序。默认命令是ar。 AS :汇编语言编译程序。默认命令是as。 CC :C语言编译程序。默认命令是cc。 CXX :C+语言编译程序。默认命令是g+。 CPP :C程序的预处理器(输出是标准

23、输出设备)。默认命令是$(CC) E。 RM :删除文件命令。默认命令是rm f。,(2)关于命令参数的变量 以下变量都是相关上面的命令的参数。若没有指明其默认值,则其默认值都是空。 ARFLAGS :函数库打包程序AR命令的参数。默认值是rv。 ASFLAGS :汇编语言编译器参数。(当明显地调用“.s”或“.S”文件时)。 CFLAGS :C语言编译器参数。 CXXFLAGS :C+语言编译器参数。 CPPFLAGS :C预处理器参数。( C 和 Fortran 编译器也会用到)。 FFLAGS :Fortran语言编译器参数。 GFLAGS :SCCS get程序参数。 LDFLAGS

24、:链接器参数。(如:ld),3自动化变量 常用的自动化变量如下。 $ :表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,“$“就是匹配于目标中模式定义的集合。 $% :仅当目标在函数库文件中,表示规则中的目标成员名。例如,如果一个目标是 foo.a (bar.o),那么,$%就是bar.o,$就是foo.a。如果目标不是函数库文件(Unix下是.a,Windows下是.lib),那么,其值为空。, $ :依赖目标中的第一个目标名字。如果依赖目标是以模式(即“%“)定义的,那么“$“将是符合模式的一系列的文件集。注意,是一个一个取出来的。 $? :所有比目标新的依赖目标的集合,以空格

25、分隔。 $ :所有的依赖目标的集合,以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。 $+ :这个变量很像“$“,也是所有依赖目标的集合。只是它不去除重复的依赖目标。, $* :表示不包含扩展名的目标文件名,即目标模式中“%”及其之前的部分。 例:目标是dir/a.foo.b,并且目标的模式是a.%.b,那么,$*的值就是dir/a.foo。 如果目标中没有模式的定义,那么$*也就不能被推导出。 如果目标文件的后缀是make 所识别的,那么$*就是除了后缀的那一部分。 例如:如果目标是foo.c,因为.c是make所能识别的后缀名,所以,$*的值就是fo

26、o。,对于上面的七个变量都可以分别加上D或是F,表示取文件的目录部分和文件部分。下面以$为例说明其含义: $(D) :表示$的目录部分(不以斜杠作为结尾),如果$值是dir/foo.o,那么$(D)就是dir,若$中没有包含斜杠,其值是“.”(当前目录)。 $(F) :表示$的文件部分,如果$值是dir/foo.o,那么$(F) 就是foo.o,$(F)相当于函数$(notdir $)。,9.3.3 Makefile文件的命令 1显示命令 echo 正在编译XXX模块 当make执行时,会输出“正在编译XXX模块”字符串,但不会输出命令,如果没有“”,那么,make将输出: echo 正在编译

27、XXX模块 正在编译XXX模块 如果make执行时,带入make参数-n或-just-print,则只是显示命令,而不会执行命令,这个功能很有利于调试Makefile文件。 而make参数-s或-slient则是全面禁止命令的显示。,2命令执行 当依赖目标新于目标时,也就是当规则的目标需要被更新时,make会一条一条的执行其后的命令。如果要让上一条命令的结果应用到下一条命令时,应该使用分号分隔这两条命令。比如第一条命令是cd命令,希望第二条命令得在cd之后的基础上运行,那么就不能把这两条命令写在两行上,而应该把这两条命令写在一行上,用分号分隔。如: exec: cd /home/hchen;

28、pwd 当执行“make exec”时,cd就起作用了,pwd会打印出“/home/hchen”。,3命令出错 在Makefile命令行前加减号“-”(在Tab键之后),标记为不管命令出不出错都认为是成功的。例如: clean: -rm -f *.o 若给make加上-i或是-ignore-errors参数,那么,Makefile中所有命令都会忽略错误。而如果一个规则是以.IGNORE作为目标的,那么这个规则中的所有命令将会忽略错误。 若make的参数的是-k或是-keep-going,如果某规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。,9.3.4 Makefile文件的变

29、量 1Makefile中的变量 顶层Makefile定义并向环境中输出了许多变量,并为各个子目录下的Makefile传递一些信息。常用的变量有以下几类: (1)版本信息 版本信息有VERSION、PATCHLEVEL、SUBLEVEL、EXTRAVERSION和KERNELRE LEASE等变量,用来定义当前内核的版本。比如,VERSION = 2,PATCHLEVEL = 4,SUBLEVEL = 18,EXTRAVERSION = -rmk7,共同构成内核的发行版本KERNELRELEASE:2.4.18-rmk7。,(2)CPU体系结构ARCH 在顶层Makefile的开头,用ARCH定

30、义目标CPU的体系结构,比如,ARCH:=arm。许多子目录的Makefile中,要根据ARCH的定义选择编译源文件的列表。 (3)路径信息TOPDIR和SUBDIRS TOPDIR定义了Linux内核源代码所在的根目录。例如,各个子目录下的Makefile通过$(TOPDIR)/Rules.make就可以找到Rules.make的位置。 SUBDIRS定义了一个目录列表,在编译内核或模块时,顶层Makefile根据SUBDIRS来决定进入哪些子目录。SUBDIRS的值取决于内核的配置,在顶层Makefile中SUBDIRS赋值为kernel drivers mm fs net ipc lib

31、;根据内核的配置情况,在arch/*/Makefile中扩充了SUBDIRS的值,可参考arch/arm/Makefile的例子。,(4)内核组成信息HEAD,CORE_FILES,NETWORKS,DRIVERS,LIBS。 Linux内核文件vmlinux是由以下规则产生的: vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o -start-group $(CORE_FILES) $(DRIVERS) $

32、(NETWORKS) $(LIBS) -end-group -o vmlinux 可以看出,vmlinux是由HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS和LIBS组成的。,这些变量(如HEAD)都是用来定义链接生成vmlinux所需的目标文件和库文件列表。其中,HEAD在arch/arm/Makefile中定义,用来确定最先链接进vmlinux的文件列表。比如,对于ARM系列HEAD的定义为: HEAD := arch/arm/kernel/head-$(PROCESSOR).o arch/arm/kernel/init_task.o 表

33、明head-$(PROCESSOR).o和init_task.o需要最先被链接到vmlinux中。PROCESSOR为armv或armo,取决于目标CPU。,(5)编译信息CPP,CC,AS,LD,AR,CFLAGS,LINKFLAGS 在Rules.make中定义的是编译的通用规则,具体到特定的场合,需明确给出编译环境,编译环境是在以上的变量中定义的。针对交叉编译的要求,定义了CROSS_COMPILE。比如: CROSS_COMPILE = arm-linux- CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld ,由于CROSS_COMPIL

34、E定义了交叉编译器前缀arm-linux-,表明所有的交叉编译工具都是以arm-linux-开头的,所以在各个交叉编译器工具之前,都加入了$(CROSS_COMPILE),以组成一个完整的交叉编译工具文件名,比如,arm-linux-gcc。 CFLAGS定义了传递给C编译器的参数。 LINKFLAGS是链接生成vmlinux时,由链接器使用的参数。LINKFLAGS在arm/*/ Makefile中定义,比如: #arch/arm/Makefile LINKFLAGS:=-p-X-Tarch/arm/vmlinux.lds,(6)配置变量CONFIG_* .config文件中有许多的配置变量

35、等式,用来说明用户配置的结果。 例如,CONFIG_MODULES=y 表明用户选择了Linux内核的模块功能。 .config被顶层Makefile包含后,就形成许多的配置变量,每个配置变量具有确定的值:y表示本编译选项对应的内核代码被静态编译进Linux内核;m表示本编译选项对应的内核代码被编译成模块;n表示不选择此编译选项;如果没有赋值,那么配置变量的值为空。,2Rules.make变量 Rules.make定义了所有Makefile共用的编译规则。 Rules.make文件定义了许多编译、链接列表变量。 O_OBJS、L_OBJS、OX_OBJS和LX_OBJS:这些变量代表的是本级目

36、录下需要编译进Linux内核vmlinux的目标文件列表,其中OX_OBJS和LX_OBJS中的“X”表明目标文件使用了EXPORT_SYMBOL输出符号。 M_OBJS和MX_OBJS:定义本级目录下需要被编译成可装载模块的目标文件列表。同样,MX_OBJS中的“X”表明目标文件使用了EXPORT_SYMBOL输出符号。 O_TARGET和L_TARGET:每个子目录下都有一个O_TARGET或L_TARGET,Rules.make首先从源代码编译生成O_OBJS和OX_OBJS中所有的目标文件,然后使用$(LD) -r把它们链接成一个O_TARGET或L_TARGET。O_TARGET以.

37、o结尾,而L_TARGET以.a结尾。,3. 追加变量值 可以使用“+=”操作符给变量追加值,例如: objects = main.o foo.o bar.o utils.o objects += another.o 于是,$(objects)值变成:“main.o foo.o bar.o utils.o another.o”,等价于: objects = main.o foo.o bar.o utils.o objects := $(objects) another.o 若变量之前没有定义过,那么“+=”会自动变成“=”;若前面有变量定义,那么“+=”会继承于前次操作的赋值符;若前一次的是“

38、:=”,那么“+=”会以“:=”作为其赋值符。,4目标变量 其语法是: : 可以是各种赋值表达式,如“=”、“:=”、“+=”或是“?=”。 第二个语法是针对于make命令行带入的变量,或是系统环境变量。这个特性非常的有用,当设置了这样一个变量,这个变量会作用到由这个目标所引发的所有的规则中去。,如:prog : CFLAGS = -g prog : prog.o foo.o bar.o $(CC) $(CFLAGS) prog.o foo.o bar.o prog.o : prog.c $(CC) $(CFLAGS) prog.c foo.o : foo.c $(CC) $(CFLAGS)

39、foo.c bar.o : bar.c $(CC) $(CFLAGS) bar.c 在这个示例中,不管全局的$(CFLAGS)的值是什么,在prog目标以及其所引发的所有规则中(prog.o foo.o bar.o的规则),$(CFLAGS)的值都是“-g”。,9.3.5 Makefile文件的条件判断 条件表达式的语法1: Endif 条件表达式的语法2: Else Endif,9.3.5 Makefile文件的条件判断 例如: bar = foo = $(bar) ifdef foo frobozz = yes else frobozz = no endif 这个例子中,条件为真,“$(f

40、robozz)”值是“yes”。,9.3.6 Makefile文件中常用函数 函数的调用语法 函数调用,很像变量的使用,也是以“$”来标识的,其语法如下: $( ) 或是: $ 其中:就是函数名;是函数的参数,参数间以逗号“,”分隔,而函数名和参数之间以“空格”分隔。函数调用以“$”开头,以圆括号或花括号把函数名和参数括起。如:$(subst a,b,$(x)。,2字符串函数 (1) 字符串处理函数 $(subst , ) 名称:字符串替换函数subst。 功能:把字串中的字符串替换成。 返回:函数返回被替换过后的字符串。 (2)查找字符串函数findstring $(findstring ,

41、 ) 功能:在字串中查找字串。 返回:若找到,那么返回,否则返回空字符串。,(3)过滤函数filter $(filter , ) 功能:以模式过滤字符串中的单词,保留符合模式的单词。可以有多个模式。 返回:返回符合模式的字串。 例如: sources := foo.c bar.c baz.s ugh.h foo: $(sources) cc $(filter %.c %.s,$(sources) -o foo $(filter %.c %.s,$(sources)返回的值是“foo.c bar.c baz.s”。,(4)反过滤函数filter-out $(filter-out , ) 功能:以

42、模式过滤字符串中的单词,去除符合模式的单词。可以有多个模式。 返回:返回不符合模式的字串。 示例: objects=main1.o foo.o main2.o bar.o mains=main1.o main2.o $(filter-out $(mains),$(objects) 返回值是“foo.o bar.o”。,(5)排序函数sort $(sort ) 功能:给字符串中的单词排序(升序)。 返回:返回排序后的字符串。 例如:$(sort foo bar lose)返回“bar foo lose”。,9.3.7 子目录Makefile 子目录Makefile用来控制本级目录下源代码编译规则

43、。下面是一个子目录Makefile文件。 # Makefile for the linux kernel. # All of the (potential) objects that export symbols. # This list comes from grep l EXPORT_SYMBOL *.hc. export-objs := tc.o # Object file lists. obj-y := obj-m := obj-n := obj- :=,obj-$(CONFIG_TC) += tc.o obj-$(CONFIG_ZS) += zs.o obj-$(CONFIG_VT)

44、 += lk201.o lk201-map.o lk201-remap.o # Files that are both resident and modular: remove from modular. obj-m := $(filter-out $(obj-y), $(obj-m) # Translate to Rules.make lists. L_TARGET := tc.a L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y) LX_OBJS := $(sort $(filter $(export-objs), $(obj-y)

45、 M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m) MX_OBJS := $(sort $(filter $(export-objs), $(obj-m) Include $(TOPDIR)/Rules.make,9.4 嵌入式Linux引导程序 9.4.1 Bootloader引导程序 1Bootloader的架构和功能 Bootloader的主要功能有: 初始化CPU 的主频、SDRAM、中断、串口等硬件; 启动Linux内核并提供一个RAMDISK; 通过串口下载内核或RAMDISK到目标板上; 将修改过的内核或RAMDISK写

46、入到Flash内; 为用户提供一个命令接口。,Bootloader引导程序分为stagel和stage2两个阶段。 (1)Bootloader的stage1 包括以下步骤: 屏蔽所有的中断 。为中断提供服务的通常是操作系统,因此在执行Bootloader的过程中可以不响应任何中断。中断屏蔽通过写CPU的中断屏蔽寄存器来完成。 设置CPU的时钟频率和速度。 初始化RAM设置系统内存控制器的功能寄存器和各内存库控制寄存器等。 为加载stage2准备RAM空间。 拷贝stage2到RAM中。 跳转到stage2的入口点。,(2)Bootloader的stage2 stage2的功能是通过串口下载Li

47、nux内核到目标板上。 包括以下几个步骤: 初始化本阶段要使用到的硬件设备。通常包括:初始化至少一个串口,以便和终端用户进行I/O输出信息;初始化计时器等。 检测系统的内存映射。所谓内存映射就是指在整个4GB物理地址空间中有哪些地址范围被分配用来寻址系统的RAM单元。 加载内核映像和根文件系统从Flash读入到RAM中。包括两个方面:第一方面是内核映像所占用的内存范围;第二方面是根文件系统所占用的内存范围。在规划内存占用布局时,主要考虑基地址和映像的大小两个方面。 设置内核的启动参数。 调用内核。Bootloader调用Linux内核的方法是直接跳转到内核的第一条指令处。,2BootLoade

48、r代码分析 下面对引导程序2410INIT.S进行分析,以加深对BootLoader的理解。在第一阶段完成依赖于体系结构硬件初始化的代码,包括禁止看门狗、禁止中断、初始化各控制寄存器拷贝自身到RAM等。, IMPORT Main AREA Init,CODE,READONLY ENTRY b ResetHandler ResetHandler ldr r0,=WTCON ldr r1,=0x0 str r1,r0 ldr r0,=INTMSK ldr r1,=0xffffffff str r1,r0 ldr r0,=INTSUBMSK ldr r1,=0x7ff,str r1,r0 ldr r0,=LOCKTIME ldr r1,=0xffffff str r1,r0 ldr r0,=SMRDATA ldr r1,=BWSCON add r2, r0, #52 0 ldr r3, r0, #4 str r3, r1, #4 cmp r2, r0 bne %B0 ,第二阶段通常用C语言实现,包括内存管理单元初始化、时钟设置、端口设置和串口初始化等。 void Isr_Init(void) rINTMOD = 0x0; /工作在IRQ模式 rINTMSK = BIT_ALLMSK; /屏蔽中断 rI

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1