Makefile的核心文件包括,rules.mk config.mk Makefile
rules:生成源文件(*.c,*.S)的依赖文件列表规则,规则的目标为包含rules.mk的makefile所在路径下的源文件所组成的.depend,规则的依赖分为3个部分,其一为包含rules.mk的makefile,其二为顶层目录下的config.mk和包含rules.mk的makefile所在路径下的源文件列表,
g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; 表示将源文件(*.c,*.S)转换为*.o
$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@,-M表示生成依赖关系,-MQ表示生成依赖列表的文件格式,后面的$(obj)$$g,即为格式,显示绝对路径
config.mk文件包含最终编译OBJ的规则,此外,包含gcc下的各种编译选项,链接选项,定义头文件包含的目录,库文件的路径等,是Makefile的核心
Makefile:顶层目录下的Makefile文件控制编译过程,参考我自己写的Makefile,其中第一个对象为all:$(OBJTREE)u-boot $(obj)u-boot.bin,即首先生成u-boot(elf格式),然后生成可以烧写的u-boot.bin,其中最重要的变量是$(LIBS),当$(LIBS)作为目标的时候,激活各个子路径下的.depend和对象的编译,并生成.a文件,cpu/不编译.S文件,该文件在Makefile中编译,作为代码的入口
需要解释一个命令,即$(OBJDUMP) –x $(LIBS)|sed –n –e ‘s/.*\(__u_boot_cmd_.*\)/-u\1/p
该命令完成的功能为列出$(LIBS)下的含有__u_boot_cmd的行。然后用将-u插入在__u_boot_cmd之前,1表示出现__u_boot_cmd的列,即-u插在__u_boot_cmd之前,
变为-u__u_boot_cmd_.
嵌入式系统中的bootloader其实就是一段编译好的代码,在系统上电后首先被执行,主要完成,硬件的基本设置,准备ram空间,最主要的是完成kernel和root filesystem的加载。
为了完成上电后首先被执行这一功能,必须明确,使用的cpu的初始上电地址是多少,例如arm9启动地址为0,所以,硬件需要在地址0的位置,安排一种存储介质,如Norflash或者Nandflash,将bootloader代码写入这种存储介质后,上电后,代码就会被执行
嵌入式系统的bootloader设计通常都分2步骤:
1) 用汇编语言实现,主要完成硬件初始化,准备第二步骤的ram空间,设置好堆栈,跳转到第二步骤,通常都包括,屏蔽所有中断,基本上bootloader不需要处理中断,而由内核完成,所以bootloader不实现中断控制器驱动,设置cpu的速率和时钟频率,初始化内存控制器,因为第二步骤由C语言完成,所以要设定好堆栈,第二步骤代码可以顺序在nand或者nor中执行,也可以将第二步骤代码拷贝到ram中执行,加快启动速度,通常该部分的调试,可以通过点灯方式进行,通常将第二部分代码拷贝到顶端内存的1M空间内
2) 初始化本阶段使用的硬件设备,检测系统内存映射,将kernel和root filesystem从flash读到ram空间,设置内核启动参数,调用内核,本阶段通常要实现简单的串口驱动,用于打印信息和接受控制台命令,此外,最好实现TFTP,用于下载主机程序或文件到ram中,还要初始化定时器,定时器主要完成延时等功能,例如可以设定,系统启动时使用启动加载模式,但加载前有10S中延时,来等待用户输入各种命令
嵌入式系统bootloader也有2种操作模式,一种为启动加载模式,一种是下载模式,
1) 启动加载模式,在产品最终提供给客户的都是启动下载模式,该模式将bootloader存在norflash或者Nandflash中,上电运行后,bootloader将内核,根文件系统从nandflash中读到ram中运行,图1-1描述了最终产品中各个部分的存放位置
2) 下载模式,主要应用与调试,bootloader仍旧保存在norflash或者nandflash中,只是启动过程中,不从nandflash中获取kernel和根文件系统,而是通过串口的(xmodem,y,z)协议或者tftp协议从开发主机上获取内核和根文件系统并存入ram中,通常,系统第一次写内核映像和根文件系统都是采用这种方式,先用tftp将内核和根文件系统下载到ram中,然后写入nandflash中
内存占用的布局:
例如arm9,内存为0x30000000 – 0x34000000
通常内核启动参数被bootloader放置在0x30000100位置
内核映像被放在0x30000000 + 0x8000的1M空间
0x8000这32K除放置内核启动参数外,还放置一些全局数据如内核页表等
根文件系统被放置在0x30010000后的1M空间
内核启动参数的传递,采用tag方法,这种方法规定了tag格式,每种tag都包含一个tag_header和具体不同的字段,tag_head中包含该tag的大小,tag以tag_acore开始,以tag_end结束,这样就可以在bootloader中和内核中共享这段数据
调用内核之前,要设置CPU的寄存器,
R0 = 0;
R1 = 机器类型ID,内核启动代码会去检测机器类型ID,以获取相关代码
R2 = 启动参数在RAM中的基地址
BOOTLOADER必须禁止中断,设置CPU模式为SVC,MMU关闭,数据CACHE关闭,指令CACHE可开可关
文章评论(0条评论)
登录后参与讨论