TechTalk

Alios Things编译构建过程

字数统计: 1.3k阅读时长: 5 min
2021/03/18

说明

最近有机会接触到了阿里物联网固件的分析工作,借此机会分析了haas1000开发版的固件的文件的构建过程。
该过程的大致构建过程如下,其中不同的阶段用不同的颜色做了标记,后续会有说明。

注:Alios Things的固件构建需要aos-cube来构建,aos-cube通过pip install可以安装。

下图中不同的颜色表示如下:

  • 蓝色:固件中客户自己的代码的构建过程
  • 紫色:最终bin文件制造前准备工作
  • 黄色:littlefs打包打包过程
  • 绿色:最终的固件文件封装过程

alios固件编译流程

阿里把构建的整个过程暴露给用户非常简单的操作方式,通过aos make进行编译和构建,详细过程参见haas1000页面的说明。

构建过程通过调用AliOS-Things/build/build_rules/aos_target_build.mk来编译整个构建联调。

后续章节对每个阶段做一下说明。

构建过程

二进制程序构建

该过程通过交叉编译的make命令对客户c代码进行编译和构建可执行文件过程,本例用了Alios-Things/application/example/helloworld_demo作为样例。而背后调用了如下命令进行编译:

1
/AliOS-Things/build/cmd/linux64/make HOST_OS=Linux64 TOOLS_ROOT=/AliOS-Things/build -e -f build/Makefile

该命令构建出helloworld_demo@haas100.elf可执行文件,然后在被剥离符号表形成stripped elf。

1
2
/AliOS-Things/build/compiler/gcc-arm-none-eabi/Linux64/bin/arm-none-eabi-strip" -oout/helloworld_dem
o@haas100/binary/helloworld_demo@haas100.stripped.elf out/helloworld_demo@haas100/binary/helloworld_demo@haas100.elf

然后在进一步剥离一些elf段内容,形成ihex文件:
1
2
3
/AliOS-Things/build/compiler/gcc-arm-none-eabi/Linux64/bin/arm-none-eabi-objcopy" -O ihex -R .eh_fra
me -R .init -R .fini -R .comment -R .ARM.attributes out/helloworld_demo@haas100/binary/helloworld_demo@haas100.stripped.elf out/he
lloworld_demo@haas100/binary/helloworld_demo@haas100.hex

最后再次剥离这些sections,形成最终用的binary文件:
1
2
3
/AliOS-Things/build/compiler/gcc-arm-none-eabi/Linux64/bin/arm-none-eabi-objcopy" -O binary -R .eh_f
rame -R .init -R .fini -R .comment -R .ARM.attributes out/helloworld_demo@haas100/binary/helloworld_demo@haas100.stripped.elf out/
helloworld_demo@haas100/binary/helloworld_demo@haas100.bin

自此,helloworld的可执行文件helloworld_demo@haas100.bin构建完成,而这个文件并不被识别为elf格式,剥离的段信息估计和haas1000硬件再加载binary到内存的映射管理有关系,我猜测
是因为mcu属于微型设备,那么内存管理估计没有使用复杂的mmu的管理方式,而至简单的地址直接映射的管理方式。
1
2
#file ./helloworld_demo@haas100.bin
./helloworld_demo@haas100.bin: DOS executable (block device driver\376,HA OS_3.1)

固件文件准备工作

这个阶段的处理非常简单,直接将必要的binary和ota文件拷贝到准备路径下。该过程散落在编译用的mk文件以及shell文件中。
而后续的构建流程,也就是OTA image构建过程,在aos_target_build.mk中的这一段为主:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(BUILD_STRING): $(if $(EXTRA_POST_BUILD_TARGETS),$(EXTRA_POST_BUILD_TARGETS),build_done)
ifneq ($(AOS_2NDBOOT_SUPPORT),yes)
ifneq ($(PING_PONG_OTA),1)
ifneq ($(CUSTOM_OTA),1)
$(info Generate Raw OTA image: $(OTA_BIN_OUTPUT_FILE) ...)
$(QUIET)$(CP) $(BIN_OUTPUT_FILE) $(OTA_BIN_OUTPUT_FILE)
$(MD5_CMD)
$(info Generate Compressed OTA image: $(OTA_BIN_OUTPUT_FILE).xz ...)
$(XZ_CMD)
$(XZ_MD5)
endif
endif
endif
$(README)

littlefs打包过程

该过程看起来是将不需要编译的静态文件打包成以littlefs格式的bin文件中,打包后的文件叫做littlefs.bin。在hello world的例子中littlefs.bin中包含了一些图像识别的python脚本。
该过程主要以/AliOS-Things/platform/mcu/haas1000/release/auto_build_tool下的各个脚本和mk文件为主:

1
2
3
4
5
6
7
8
9
10
11
12
13
(venv) /AliOS-Things/platform/mcu/haas1000/release/auto_build_tool$ ll
total 620
-rw-rw-rw- 1 root root 15933 Mar 16 15:07 haas1000_genbin.py
-rw-rw-r-- 1 root root 578 Mar 15 20:23 haas1000_2ndboot_genbin.mk
-rw-rw-r-- 1 root root 1054 Mar 15 20:23 haas1000_genbin.mk
-rw-rw-r-- 1 root root 107 Mar 15 20:23 haas1000_genfs.bat
-rwxrwxr-x 1 root root 394 Mar 15 20:23 haas1000_genfs.sh
-rw-rw-r-- 1 root root 245 Mar 15 20:23 haas1000_littlefs.mk
-rw-rw-r-- 1 root root 1574 Mar 15 20:23 haas_genbin_config.yaml
-rw-rw-r-- 1 root root 371200 Mar 15 20:23 mklittlefs.exe
-rwxrwxr-x 1 root root 100536 Mar 15 20:23 mklittlefs_linux
-rwxrwxr-x 1 root root 117848 Mar 15 20:23 mklittlefs_osx
(venv) /AliOS-Things/platform/mcu/haas1000/release/auto_build_tool$

这里做一下简单的说明:

  • haas1000_genbin.mk: 该mk文件作为整个过程的入口,触发littlefs构建,xz文件打包和生成多个bin文件堆叠的bin文件过程。
  • haas1000_genbin.py: 做最后的准备工作,将众多ota bin文件拷贝到相应文件夹下面。
  • haas1000_genfs.sh/bat: 按照平台调用mklittlefs程序将prebuild/data/下的文件打包成littlefs.bin

这里遇到一个坑,mklittlefs_linux可以打包littlefs,但是从这个bin中解包的时候出现失败。需要从github下载mklittlefs和littlefs源码重新构建程序。

固件文件封装

该过程主要调用/AliOS-Things/build/scripts/ota_gen_md5_bin.py来构建堆叠bin的过程。
通过对该python文件的分析,该堆叠后的文件的构成如下:
堆叠文件封装
说明如下:
长度1:是input binary+0xffffffff的长度。
数字摘要:按照input binary+0xffffffff的内容做MD5
CRC校验值:按照input binary+0xffffffff的内容做CRC校验值。

堆叠的文件替换源文件,作为最后的OTA升级使用文件。
自此alios things的haas1000的OTA固件文件的构建过程分析完毕。

CATALOG
  1. 1. 说明
  2. 2. 构建过程
    1. 2.1. 二进制程序构建
    2. 2.2. 固件文件准备工作
    3. 2.3. littlefs打包过程
    4. 2.4. 固件文件封装