u-boot中的Makefile
在windos下,pc机上电之后,BIOS会初始化硬件配置,为内核传递参数,引导操作系统启动,并且识别C盘、D盘。等整个操作系统启动起来之后,才可以运行应用程序比如QQ、QQ音影。同理,在嵌入式Linux操作系统中,bootloader在上电之后初始化硬件设备,引导Linux内核启动,并且挂在文件系统,等整个操作系统启动之后。运行应用程序。
bootloader其实就是一个单片机程序,一般采用开发的语言是汇编和C语言,但是不同的硬件平台下的boot是不同的。booloader的启动是:首先将bootloader存在Flash中,开发板通常把板上ROM或者Flash映射到CPU开始执行的地址,当系统加电后,CPU将执行它。
bootloader的功能很明确:那就是引导内核启动。
bootloader 的启动通常分为两个阶段
第一阶段:初始化基本的硬件(时钟,关闭看门狗,SDRAM等),把bootloader自己搬运到RAM中,并且设置堆栈,搭建C语言运行环境。
第二阶段:初始化本阶段需要的硬件(USB,串口,网口等),读取环境变量,给内核传参数,从Flash中读将内核加载到RAM中,为内核传递参数,引导内核启动。
u-boot的结构:想要分析u-boot的结构,最简单直接的途径就是分析Makefile。生成u-boot.bin的过程首先要配置Makefile,然后载编译Makefile。
一、配置过程
在编译时首先执行make 100ask24x0_config在Makefile中找到100ask24x0_config。
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
MKCONFIG这个变量的定义为 MKCONFIG := $(SRCTREE)/mkconfig $(SRCTREE)表示源文件路径下面有个mkconfig文件
@:_config= 中的 @表示目标 100ask24x0,_config=表示替换掉。那么
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0的实际意思为mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
那么紧接着进入u-boot-1.1.6目录打开mkconfig,分析这个文件
在脚本文件中#表示注释。
#mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
#在这里声明一下,mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0这个命令在执行过程中会
# 给mkconfig传入参数,$ 为mkconfig, $ 为100ask24x0,$2为arm,以此类推...
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
] ; do #$#表示执行脚本文件时所传入的参数的个数,当参数个数大于0时,开始往下执行
case "$1" in #case中$1表示执行命令时传入的参数,比如mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
#这个命令中$1表示100ask24x0,而以下代码中没有匹配项
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
[ "${BOARD_NAME}" ] || BOARD_NAME="$1" #表示BOARD_NAME如果没有定义,则定义为所传入的参数即100ask24x0
[ $# -lt ] && exit #若参数个数小于4则退出
[ $# -gt ] && exit #若参数个数大于6则退出
echo "Configuring for ${BOARD_NAME} board..." #echo 表示打印,相当于c语言中的printf配置文件名称
#
# Create link to architecture specific headers
#
if [ "$SRCTREE" != "$OBJTREE" ] ; then #在makefile中找到SRCTREE和OBJTREE,如果不相等,则进入then 开始执行。
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -f asm
asm
else #如果相等,则进入以下部分
cd ./include
rm -f asm
asm #ln -s asm-arm asm 表示建立一个连接文件并且指向asm-arm,进入终端执行ls -la asm 就可以查看
#lrwxrwxrwx book book -- : asm -> asm-arm
#这样做的目的就是在编译asm的头文件时,汇编指令为asm-arm架构下的。
fi
/arch #rm -f asm-arm/arch
if [ -z "$6" -o "$6" = "NULL" ] ; then #如果第六个参数为空或者等于null
asm-$/arch
else
asm-$/arch #ln -s arch-s3c24x0 asm-arm/arch 建立连接文件
fi
if [ "$2" = "arm" ] ; then
/proc #rm -f asm-arm/proc 删除asm-arm/proc
/proc #ln -s proc-armv asm-arm/proc
fi
#
# Create include file for Make
#
echo "ARCH = $2" > config.mk #>表示创建config.mk
echo "CPU = $3" >> config.mk #>>表示追加到config.mk 文件中
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk #$5存在或者不为空
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
#在config.mk 中
#ARCH = arm
#CPU = arm920t
#BOARD = 100ask24x0
#SOC = s3c24x0
#
# Create board specific header file
#
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h #同上,在config.h 中追加
echo "#include <configs/$1.h>" >>config.h
#在config.h中
#/* Automatically generated - do not edit */
##include <configs/100ask24x0.h>
exit
mkconfig
二、编译过程
在配置config.mk脚本文件时,相应的ARCH架构,CPU类型,BOARD平台都会相应的赋值,那么在编译过程中这些参数的值将会被带入进行相应的判断,编译时进入Makefile。查找与mkconfig赋值相关的变量
#通过上面的分析可以知道,在config.mk 中
#ARCH = arm
#CPU = arm920t
#BOARD = 100ask24x0
#SOC = s3c24x0
紧接着分析Makefile
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux- endif
如果ARCH的值与arm 相等,则执行CROSS_COMPILE = arm-linux-
# load other configuration include $(TOPDIR)/config.mk
$(TOPDIR)表示顶端目录
LIBS = lib_generic/libgeneric.a LIBS += board/$(BOARDDIR)/lib$(BOARD).a LIBS += cpu/$(CPU)/lib$(CPU).a
#相当于链接以下的库:
LIBS = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib100ask24x0.a
LIBS += cpu/arm920t/libarm920t.a
#########################################################################
# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o
$(CPU)为arm920t
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) all: $(ALL)
#在Makefile中如果不指定目标,那么生成的目标就是ALL变量指向的内容
查找上边的u-boot.bin所依赖的文件
$(obj)u-boot.bin: $(obj)u-boot #u-boot.bin依赖于u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
#u-boot.bin依赖于u-boot
$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
#u-boot所依赖的库之类的文件
在实际编译过程过的打印消息为
UNDEF_SYM=`arm-linux-objdump -x lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /home/book/system/u-boot- &&
arm-linux-/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o \
--start-group lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a --end-group -L /work/tools/-glibc-/lib/ -lgcc \
-Map u-boot.map -o u-boot
放在最前边的是链接脚本arm-linux-ld -Bstatic -T /home/book/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000,链接地址为0x33F80000
那么现在进入链接文件/u-boot-1.1.6/board/100ask24x0/u-boot.lds中
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; #表示最开始的地址,而在u-boot.lds -Ttext 0x33F80000中指定地址为0x33F80000,所以开始执行的地址为0x33F80000
. = ALIGN(); #表示对齐方式以2的4次方对齐
.text :
{
cpu/arm920t/start.o (.text) #start.o文件的代码段
board/100ask24x0/boot_init.o (.text) #boot_init.o 文件的代码段
*(.text) #最后放置所有文件的代码段
}
. = ALIGN();
.rodata : { *(.rodata) } #放置只读代码段
. = ALIGN();
.data : { *(.data) } #放置数据段
. = ALIGN();
.got : { *(.got) }
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }#放置u-boot的命令段
__u_boot_cmd_end = .;
. = ALIGN();
__bss_start = .;
.bss : { *(.bss) } #放置bss段
_end = .;
}
u-boot.lds
分析完这个u-boot.lds,就可以知道u-boot.bin里具体放置的内容,就知道u-boot的执行顺序了,很显然放置在最前边的是start.o和boot_init.o。进入start.S中进行分析
通过分析Makefile可以得到的结论就是:
1.u-boot中执行的第一个文件就是start.S
2.u-boot存放的地址为0x33F80000。这个0x33F80000定义的地方为./board/100ask24x0/config.mk:25:TEXT_BASE = 0x33F80000
如果想修改u-boot的存放地址,则可以修改./board/100ask24x0/config.mk文件中的TEXT_BASE的值
u-boot中的Makefile的更多相关文章
- spring boot(三):Spring Boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- Spring Boot中的事务管理
原文 http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...
- Spring Boot中的注解
文章来源:http://www.tuicool.com/articles/bQnMra 在Spring Boot中几乎可以完全弃用xml配置文件,本文的主题是分析常用的注解. Spring最开始是为了 ...
- 在Spring Boot中使用Https
本文介绍如何在Spring Boot中,使用Https提供服务,并将Http请求自动重定向到Https. Https证书 巧妇难为无米之炊,开始的开始,要先取得Https证书.你可以向证书机构申请证书 ...
- Spring Boot中使用Swagger2构建强大的RESTful API文档
由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这 ...
- Dubbo在Spring和Spring Boot中的使用
一.在Spring中使用Dubbo 1.Maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifa ...
- springboot(十一):Spring boot中mongodb的使用
mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...
- springboot(三):Spring boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- Spring Boot中使用Swagger2构建API文档
程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...
- Spring Boot中使用 Spring Security 构建权限系统
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全 ...
随机推荐
- P3386 【模板】二分图匹配
题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...
- Repository HDU - 2846 (trie)
题中没给范围 所以控制不好数组范围..不是超内存就是runtime.. 好吧 到了晚上终于调出来数组模拟的了 题意: 求含有某字符段的个数 解析: 把每个字符串遍历一遍 以每个元素为起点建树就好了.. ...
- Android 解决ScrollView嵌入ListView | GridView | ScrollView显示问题
一.ScrollView中嵌套ListView ScrollView和ListView都是滚动结构,很明显如果在ScrollView中加入ListView,可以预见性的知道,肯定会有显示/滚动的问题, ...
- BZOJ1072 排列perm 【状压dp】
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能 被2整除,其中末位为2的有30种,末位为4的有60种. Inpu ...
- C++之智能指针20170920
/*************************************************************************************************** ...
- 关于JBoss基本说明文档及基本使用安装
关于JBoss JBoss是全世界开发者共同努力的成果,一个基于J2EE的开放源代码的应用服务器.在不 到12个月的时间里有一百万以上的拷贝被下载.JBoss是第一位的J2EE应用服务器. J ...
- Nginx基本功能极速入门
http://xxgblog.com/2015/05/17/nginx-start/ 本文主要介绍一些Nginx的最基本功能以及简单配置,但不包括Nginx的安装部署以及实现原理.废话不多,直接开始. ...
- [Z3001] connection to database 'zabbix' failed: [1045] Access denied for user 'zabbix'@'localhost' (using password: YES)
在配置了zabbix服务端后,发现:“zabbix server is running”的Value值是“no”, 用:netstat -atnlp|grep 10051 发现没有出现zabbix_s ...
- python 深、浅拷贝
Python的数据结构总体分为两类: 1.字符串和数字 2.列表.元组.字典等 一.字符串和数字 对于字符串和数字而言,赋值(=).浅拷贝(copy)和深拷贝(deepcopy)其实都没有意义,因为它 ...
- 用python + openpyxl处理excel(07+)文档 + 一些中文处理的技巧
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...