BeagleboneBlack上u-boot的MLO文件是哪里来的
在玩BeagleboneBlack一段时间之后不可避免地接触到了u-boot,之前的玩耍过程大致上是这样的:
在MATLAB下耍,因为MATLAB提供了它的硬件支持,可以直接在命令行与之交互,也可在simulink下直接编译仿真模型下载到板子上运行,当时的感觉是,我勒个去,MATLAB真是无所不能。
在MATLAB下耍了一段时间之后,开始在BBB本身的Linux系统上耍,主要照着Derek Molly的那本书耍,操作GPIO,使用传感器等等。发现在Linux下操作硬件怎么这么容易,以前玩的51,430,STM32貌似都是要操作寄存器的。
接着发现了TI的StartWare,之前玩430的时候在CCS里面看到过这东西,不知道是啥,安装了也不知道是几个意思,现在才知道原来它就相当于BBB的库文件,有裸奔之用。看过几个例程之后发现,接近5k页的datasheet,读完不现实。
不过处理器的启动过程总是值得关注的,AM3358启动过程中需要一个MLO文件,那MLO是怎么来的,于是来到了u-boot面前。。。下载u-boot的源码(2017-03-r1),读了一下readme,大致知道怎么用了,依次敲入
make am335x_boneblack_defconfig
make all CROSS_COMPILE=arm-linux-gnueabihf-
编译了一大堆的文件,貌似有一两百个,看看顶层的Makefile,1600行,这可真够我喝一池子了,一点头绪都没有,然后找了本书《嵌入式Linux系统开发入门宝典——基于Cortex-A8处理器》,人家用2014-04来分析的,于是我也照着来。
敲入make am335x_boneblack_config之后发生了什么:
顶层Makefile第460行:
@$(MKCONFIG) -A $(@:_config=)
展开即为:
mkconfig -A am335x_boneblack
表示执行名为"mkconfig"的shell脚本,带了两个参数-A和am335x_boneblack,看看这个脚本干了些什么:
第28行,读取board.cfg文件:
line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' $srctree/boards.cfg`
找到这样一行:
Active arm armv7 am33xx ti am335x am335x_boneblack am335x_evm:SERIAL1,CONS_INDEX=,EMMC_BOOT ......
根据这一行声生成两个符号链接:
arch-am33xx -->> asm/arch
proc-armv -->> asm/proc
再生成两个文件:
include/config.mk
include/config.h
配置过程就结束了.接下来看看敲入make all CROSS_COMPILE=arm-linux-gnueabihf-之后发生了什么:
这样敲入指定的目标是"all",并将CROSS_COMPILE指定为arm-linux-gnueabihf-,去顶层makefile找我们的"all"目标,第744行:
all: $(ALL-y)
"all"目标依赖于"ALL-y"这个变量,再去找"ALL-y",第698行:
ALL-y += u-boot.srec u-boot.bin System.map
发现我们的有三个目标,"u-boot.srec"为Motorola的xxxx格式的镜像,u-boot.bin就是二进制格式的镜像了,System.map是xxxx(我也不清楚).
但是下面第700行开始有一系列的ALL-$(CONFIG_NAND_U_BOOT)这样的东西,比如第703行和704行:
ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin
ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img
如果$(CONFIG_SPL)是y的话,那就表示我们的目标还要再加上spl/u-boot-spl.bin,下面同理,CONFIG_SPL定义在include/autoconf.mk文件中,在第472行被include进来:
-include include/autoconf.mk
autoconf.mk文件是在编译之前产生的,在第1046行:
include/autoconf.mk: include/config.h
$(call cmd,autoconf)
在autoconfi.mk的第203行确实定义了这个变量
CONFIG_SPL=y
于是我们的"all"目标还要加上两个:spl/u-boot-spl.bin和u-boot.img,makefile会按照规则一个目标一个目标地去生成,以u-boot.bin为例,第771行:
u-boot.bin: u-boot FORCE
继续找u-boot的依赖,第918行:
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds
继续找u-boot-init和u-boot-main的依赖,第931行:
$(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
继续找u-boot-dirs的依赖,第940行:
$(u-boot-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
$(Q)应该是quiet的意思,让make默默执行,变量build在scripts/kbuild.include文件中第170行定义:
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
kbuild.include文件在第316行被include进来:
include $(srctree)/scripts/Kbuild.include
所以命令展开即为:make -f scripts/Makefile.build obj=$(u-boot-dirs),变量u-boot-dirs在第636行定义:
u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples
为变量libs-y加上tools和examples这么些目录,libs-y定义在575~632行,表示要编译的目录,以目录lib/为例,执行make -f scripts/Makefile.build obj=lib,表示使用scripts下的Makefile变量obj=lib执行make,这里没有指定目标,所以在Makefile.build中第一个目标将会是我们的目标,看看Makefile.build文件,第17行:
__build:
目标是__build,它是PHONY目标,再看第172行:
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:
变量KBUILD_BUILTIN是1,所以它依赖于后面那一串变量,展开为builtin-target,lib-target,extra-y,subdris-ym,always,看看builtin-target在哪,第413行:
$(builtin-target): $(obj-y) FORCE
它依赖于变量obj-y,而obj-y定义在开头,是空的,但是在第64行会将要编译的目录,例如这里的lib目录下的Makefile include进来,在其中修改了obj-y变量,比如第23行:
obj-y += crc7.o
于是obj-y就有东西了,然后obj-y依赖于什么呢,.o文件估计依赖于.c或者.s文件,所以第334行:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
但这里的目标多了前面的路径名,而此时obj-y并不包含路径名,再看第129行:
include scripts/Makefile.lib
在Makefile.lib文件中将对obj-y添加路径名,确定需要编译的子目录等等,对于子目录,它会执行同样的过程,第481行:
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@
整个Makefile的结构貌似就是这样子的,顶层makefile确定目标,要编译的目录,子目录中的makefile确定需要编译的文件以及它自己的子目录,然后这些.o文件一层一层地链接,最终生成u-boot.bin文件,其他的目标估计也是这个过程.
可是那个MLO文件在哪里呢?再看看这个目标:spl/u-boot-spl.bin,顶层makefile中第1080行:
spl/u-boot-spl.bin: spl/u-boot-spl
@:
spl/u-boot-spl: tools prepare
$(Q)$(MAKE) obj=spl -f $(srctree)/spl/Makefile all
命令展开为make obj=spl -f spl/Makefile all表示以spl/Makefile为文件,变量obj=spl,目标是all,执行make,spl下的makefile文件结构和顶层makefile结构类似,看看all目标,第191行:
all: $(ALL-y)
展开为spl/u-boot-spl.bin,看看arch/arm/cpu/armv7/am33xx/config.mk文件:
ifdef CONFIG_SPL_BUILD
ALL-y += MLO
ALL-$(CONFIG_SPL_SPI_SUPPORT) += MLO.byteswap
else
ALL-y += u-boot.img
endif
如果定义了CONFIG_SPL_BUILD的话,ALL-y目标将会包含有MLO,编译前面的目标时,顶层makefile的配置文件是include下的autoconf.mk,里面是没有定义CONFIG_SPL_BUILD的,所以不会包含MLO,但是这里的makefile使用的是spl-autoconf.mk作为配置文件,有这么一行:
CONFIG_SPL_BUILD=y
所以MLO文件就会被编译出来了,那这个MLO干了些啥呢?......
BeagleboneBlack上u-boot的MLO文件是哪里来的的更多相关文章
- Beagleboneblack的MLO文件干了些啥
Beagleboneblack在启动linux之前还有三个启动阶段: ROM code --> MLO --> u-boot --> kernel 先看看ROM code干了 ...
- 如何在 Mac 上通过 Boot Camp 安装 Windows?
如何在 Mac 上通过 Boot Camp 安装 Windows? The following contents are chosen from the apple website, thanks f ...
- SpringBoot - 实现文件上传2(多文件上传、常用上传参数配置)
在前文中我介绍了 Spring Boot 项目如何实现单文件上传,而多文件上传逻辑和单文件上传基本一致,下面通过样例进行演示. 多文件上传 1,代码编写 1)首先在 static 目录中创建一个 up ...
- Centos7.4 file '/grub/i386-pc/normal.mod' not found,实际为/boot下所有文件丢失
注:如果服务器特别重要,此方案慎用.如果没有其他方案解决,可以使用该方案 事件:搭建在云计算管理平台CAS上的 Centos7.4 虚拟机在一次断电后,启动虚拟机出现file '/grub/i386- ...
- PHP上传(单个)文件示例
通过 PHP,可以把文件上传到服务器. 创建一个文件上传表单 允许用户从表单上传文件是非常有用的. 请看下面这个供上传文件的 HTML 表单: <html> <body> &l ...
- SharePoint 2010 ——自定义上传页面与多文件上传解决方案
最近项目遇到一个很麻烦的问题,原以为很容易解决,结果搞了那么久,先开个头,再慢慢写 SharePoint 2010 ——自定义上传页面与多文件上传解决方案 1.创建Sharepoint空白项目,创建应 ...
- echo "不允许上传该类型的文件
<?php教程 // 上传设置 $maxsize=10002400; //最大允许上传的文件大小 $alltype=array(".php"," ...
- .Net neatupload上传控件实现文件上传的进度条
1. 引入bin文件 (可以到neatupload官网下载,也可以到教育厅申报系统中找) 2. 将控件加入到工具栏,在工具栏中点鼠标右键,如图: 3. 加入neatuplaod这个文件夹(可以到nea ...
- 使用Delphi读取网络上的文本文件,html文件
使用Delphi读取网络上的txt和html文件 可以使用两种方法: 1.下载文件,然后进行读取 下载文件的Delphi代码可以参考: http://www.delphibbs.com/delphib ...
随机推荐
- axios请求接口的时候带一个参数
getHomeInfo () { this.axios.get('/api/index.json?city=' + this.city) .then(this.getHomeInfoSucc) } 尽 ...
- 个人网站一步一步搭建——(10)后台登陆dome
Service+ui+dto架构 AJAX 方式登陆小DEMO 后面的.得配合vue 做后台管理了... 还是一个个dome做
- Redis的学习之路
应用场景 1.作为缓存使用 (1)原始业务功能设计 秒杀 双十一.618 排队购票 (2)运营平台察觉到突发式高频访问热点 突发式热点新闻 (3)高频复杂的统计数据 在线直播 投票排行榜 2.附加功 ...
- offsetof宏与container_of宏
offsetof宏与container_of宏1.由结构体指针进而访问各元素的原理(1)通过结构体整体变量来访问其中各个元素,本质上是通过指针方式来访问的,形式上是通过.的方式来访问的(这个时候其实是 ...
- 题解P4201: [NOI2008]设计路线
发现给出了一棵树, 不是树的情况直接输出-1 考虑进行DP, 设f[i][0/1/2]为i的子树中选小于等于0/1/2条边修路的方案数, 不妨对于一个节点, 先考虑正好相等的情况, 假设当前扫到了一个 ...
- codeforces 596 C. p-binary
题意:给你一个n和一个p,让你用 (2k+p)进制来表示n,找出用最少的(2k+p)来表示n. 分析:首先我们看到2k,首先下想到二进制,我们可以我们列出式子,也就是 (2x1 + p)+(2x2 + ...
- 关于域名转发proxy_pass
在配置nginx的时候,有一个需求,访问m.XXX.com的时候,需要实际访问www.YYY.com/m,并且域名不能发生变化. 达成这个需求有两种做法: 第一种就是301跳转,使用rewrite来跳 ...
- 2020/1/28 PHP代码审计之命令执行漏洞
0x00 命令执行漏洞原理 应用程序有时需要调用一些执行系统命令的函数,如在PHP中,使用system.exec.shell_exec.passthru.popen.proc_popen等函数可以执行 ...
- 我读《DOOM启世录》——成为一个真正厉害的人
序言 谈到游戏, 你的当然会想到几乎统治游戏市场多年的英雄联盟,你可能还会想起前段时间风头大盛的王者荣耀手游,你应该还会想起正在冲击着游戏市场的"吃鸡"类型游戏. 那么, 大家是否 ...
- usert
usert类型 不是一个函数,而是一个语言构造器 usert后会不会释放内存 当usert的文件大于2044KB时才会释放内存,否则不释放内存