AliOS Things的启动过程分析(一)

在本篇文章中,我们以developerkit开发板为例,介绍AliOS Things的启动过程。AliOS Things支持多种工具链进行编译链接的方式生成可执行文件,在这里主要是以GCC的方式(更加通用)来进行介绍。建议可以先阅读AliOS Things的编译体系,对整个的编译流程有个简单的了解。链接

一个可执行文件生成首先需要确定宿主平台(windows、linux等)、再确定所使用的工具链、确定所有使用的组件源文件等等、最后根据指定的链接脚本进行连接生成可执行文件。而启动过程的理解,也需要从连接脚本和工具链讲起。

以developerkit为例,在board/developer目录下的developerkit.mk文件当中会指定所使用的启动文件以及选择指定的编译工具链。

如下所示,为截取的少量代码,主要是指定所使用的启动文件以及根据条件来选择所使用的链接脚本文件。在developerkit.mk文件中还定义了SoC的相关信息,指定了所使用的源文件等,详情请自行参考该文件。

ifeq ($(COMPILER), armcc)
$(NAME)_SOURCES += startup_stm32l496xx_keil.s
else ifeq ($(COMPILER), iar)
$(NAME)_SOURCES += startup_stm32l496xx_iar.s
else
$(NAME)_SOURCES += startup_stm32l496xx.s
endif
#以上为确定所使用的编译工具,是armcc /  iar  /或者是gcc
#并选择所使用的启动文件#下述代码是根据编译工具来指定其加载文件,在该文件中定义了一些基本的启动加载信息
ifeq ($(COMPILER),armcc)
GLOBAL_LDFLAGS += -L --scatter=board/developerkit/STM32L496.sct
else ifeq ($(COMPILER),iar)
GLOBAL_LDFLAGS += --config board/developerkit/STM32L496.icf
else
ifeq ($(post_run),1)
GLOBAL_LDFLAGS += -T board/developerkit/STM32L496VGTx_FLASH.ld
GLOBAL_DEFINES += VECT_TAB_OFFSET=0x4000
GLOBAL_DEFINES += USING_FLAT_FLASH
else
ifeq ($(MBINS),)
GLOBAL_LDFLAGS += -T board/developerkit/STM32L496VGTx_FLASH.ld
else ifeq ($(MBINS),app)
GLOBAL_LDFLAGS += -T board/developerkit/STM32L496VGTx_FLASH_app.ld
else ifeq ($(MBINS),kernel)
GLOBAL_LDFLAGS += -T board/developerkit/STM32L496VGTx_FLASH_kernel.ld
endif
endif
endif

接下来,我们将以gcc编译工具和STM32L496VGTx_FLASH.ld链接脚本为例来进行理解其启动过程。以下代码是

STM32L496VGTx_FLASH.ld链接脚本文件的部分代码。该文件所完成的最终目的是将编译后生成的文件进行连接生成最终的可执行文件。在该文件中定义了堆栈大小,存储区域的分配大小、以及各种段的定义和存储。本篇文章中只分析和启动过程相关的部分代码定义。

在链接文件的起始部分,指定了程序的入口位置是:Reset_Handler。该函数位于startup_stm32l496xx.s文件中,后续会进行讲解。并且在后面定义了RAM区的结束地址、堆以及栈的大小,RAM 区域和FLASH区域的地址等。

/* Entry Point */
ENTRY(Reset_Handler)/* Highest address of the user mode stack */
_estack = 0x20050000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack *//* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 1024K
}

接下来分析一些后续启动过程可能会用到的段定义,详细的文件内容可以实际参考.ld链接脚本。在此只介绍和启动过程相关的定义。在段定义的开始,首先存储到FLASH区域的是向量表,向量表的定义也位于

startup_stm32l496xx.s文件中。接下来是常见的代码段的存储、只读数据段的存储以及数据段和bss段的存储(中间忽略了很多段定义,可以自行参考)

/* Define output sections */
SECTIONS
{/* The startup code goes first into FLASH */.isr_vector :{. = ALIGN(8);KEEP(*(.isr_vector)) /* Startup code */. = ALIGN(8);} >FLASH/* The program code and other data goes into FLASH */.text :{. = ALIGN(8);*(.text)           /* .text sections (code) */*(.text*)          /* .text* sections (code) */*(.glue_7)         /* glue arm to thumb code */*(.glue_7t)        /* glue thumb to arm code */*(.eh_frame)KEEP (*(.init))KEEP (*(.fini)). = ALIGN(8);_etext = .;        /* define a global symbols at end of code */} >FLASH/* Constant data goes into FLASH */.rodata :{. = ALIGN(8);*(.rodata)         /* .rodata sections (constants, strings, etc.) */*(.rodata*)        /* .rodata* sections (constants, strings, etc.) */. = ALIGN(8);} >FLASH/* used by the startup to initialize data */_sidata = LOADADDR(.data);/* Initialized data sections goes into RAM, load LMA copy after code */.data : {. = ALIGN(8);_sdata = .;        /* create a global symbol at data start */*(.data)           /* .data sections */*(.data*)          /* .data* sections */. = ALIGN(8);_edata = .;        /* define a global symbol at data end */} >RAM AT> FLASH/* Uninitialized data section */. = ALIGN(4);.bss :{/* This is used by the startup in order to initialize the .bss secion */_sbss = .;         /* define a global symbol at bss start */__bss_start__ = _sbss;*(.bss)*(.bss*)*(COMMON). = ALIGN(4);_ebss = .;         /* define a global symbol at bss end */__bss_end__ = _ebss;} >RAM

在startup_stm32l496xx.s文件中和启动过程相关的代码如下所示:

Reset_Handler是程序启动后最先执行的代码(在ld文件中ENTRY指定),这段代码是由汇编语言编写的完成的主要功能是:

  1. 设置sp堆栈指针。将其设置为_estack 在ld链接脚本中将其指定为RAM的截止地址
  2. .data数据段的内容拷贝到RAM区,.data数据段:用于存放在编译阶段(而非运行时)就能确定的数据,可读可写。也是通常所说的静态存储区,赋了初值的全局变量、常量和静态变量都存放在这个域。.data数据段的定义在ld文件中。
  3. 清除bss段。通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。裸机程序需要手动清零。
  4. 跳转到SystemInit函数中进行时钟的初始化。该函数位于board\developerkit\Src\system_stm32l4xx.c文件中。
  5. 调用应用程序入口函数main函数,main函数位于AliOS-Things\platform\mcu\stm32l4xx_cube\aos\aos.c文件中。
  .section   .text.Reset_Handler.weak    Reset_Handler.type  Reset_Handler, %function
Reset_Handler:ldr   sp, =_estack    /* Atollic update: set stack pointer *//* Copy the data segment initializers from flash to SRAM */movs r1, #0b LoopCopyDataInitCopyDataInit:ldr    r3, =_sidataldr    r3, [r3, r1]str r3, [r0, r1]adds    r1, r1, #4LoopCopyDataInit:ldr  r0, =_sdataldr r3, =_edataadds    r2, r0, r1cmp   r2, r3bcc   CopyDataInitldr r2, =_sbssb    LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:movs    r3, #0str   r3, [r2], #4LoopFillZerobss:ldr r3, = _ebsscmp r2, r3bcc   FillZerobss/* Call the clock system intitialization function.*/bl  SystemInit
/* Call static constructors */bl __libc_init_array
/* Call the application's entry point.*/bl mainLoopForever:b LoopForever.size  Reset_Handler, .-Reset_Handler

以上就是developerkit从系统上电开始运行到系统进入应用程序主代码(main函数)所要经历的一些步骤,接下来会针对main函数的一些初始化工作进行讲解。因为是阅读源码进行分析的,如果有任何错误之处敬请谅解。

转载

AliOS Things的启动过程分析(一)

AliOS Things的启动过程分析(一)相关推荐

  1. 嵌入式linux启动过程分析,嵌入式Linux裸机开发(二)——S5PV210启动过程分析

    嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介 友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅 ...

  2. OpenWrt启动过程分析+添加自启动脚本【转】

    一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/p ...

  3. pixhawk PX4FMU和PX4IO最底层启动过程分析

    摘要: pixhawk PX4FMU和PX4IO最底层启动过程分析1.1 主处理器和协处理器的固件烧写和运行流程首先,大体了解PX4IO 与PX4FMU各自的任务.PX4IO(STM32F100)为P ...

  4. linux 重定位arm,Arm linxu启动过程分析(一)

    本文着重分析 FS2410 平台 linux-2.6.14 内核启动的详细过程,主要包括: zImage 解压缩阶段. vmlinux 启动汇编阶段. startkernel 到创建第一个进程阶段三个 ...

  5. linxu 启动过程分析

    linxu 启动过程分析 Linux启动过程如下:当用户打开PC的电源,BIOS开机自检,按BIOS中设置的启动设备(通常是硬盘)启动,接着启动设备上安装的引导程序lilo或grub开始引导Linux ...

  6. 开机SystemServer到ActivityManagerService启动过程分析

    开机SystemServer到ActivityManagerService启动过程 一 从Systemserver到AMS zygote-> systemserver:java入层口: /*** ...

  7. Chromium的GPU进程启动过程分析

    Chromium除了有Browser进程和Render进程,还有GPU进程.GPU进程负责Chromium的GPU操作,例如Render进程通过GPU进程离屏渲染网页,Browser进程也是通过GPU ...

  8. Android开发入门教程2-Android init 启动过程分析

    Android init 启动过程分析   分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linu ...

  9. 嵌入式linux s5pv210,嵌入式Linux裸机开发(二)——S5PV210启动过程分析

    嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅三 ...

最新文章

  1. LTE PUCCH F2 TX/RX汇总
  2. Hadoop “Unable to load native-hadoop library for y
  3. Fedora 30用dnf安装OpenCV及g++编译其应用程序
  4. 【Pushgateway】正则匹配,分隔逗号成数组
  5. Android传感器编程带实例
  6. 深入学习SAP UI5框架代码系列之四:SAP UI5控件的元数据实现
  7. 使用PXE+VNC方式安装CentOS 7
  8. Windows下启动,关闭Nginx命令
  9. 快速简易封装歌词文件
  10. 软件测试 给视频添加字幕功能,巧用百度OCR文字识别技术,实现视频字幕识别...
  11. 已安装过matplotlib但提示ModuleNotFoundError: No module named ‘matplotlib‘的解决方法
  12. C#的百度地图开发(四)前端显示与定位
  13. 照片尺寸及像素对应表
  14. 激活windows系统,你知道吗
  15. 南京绿溢大厦远程预付费系统项目的设计与应用-安科瑞耿敏花
  16. 我与我的专业计算机作文500字,我和学校作文500字(精选5篇)
  17. 有关5G技术的认知与感想
  18. 复变函数和积分变换(Complex Function I)
  19. mysql 简述pk uk fk 的区别和对数据库性能的影响_数据库pk fk ak
  20. C - Line-line Intersection

热门文章

  1. webui 通过提示词矩阵的文本框功能添加负面标签
  2. 坚果pro android版本,坚果Pro有几个版本 哪个版本好?坚果Pro各版本的区别
  3. P1413 坚果保龄球洛谷c++题解
  4. Cobbler 自动装机系统
  5. ubifs 分区格式化方法
  6. android-下拉更多列表
  7. 推荐这三款亲测好用的ai工具
  8. 达人评测 r7 7735h和i7 13700h选哪个 锐龙r77735h和酷睿i713700h差距
  9. 北京市中 高英语听说计算机考,北京2018中考英语听说计算机考试工作通知
  10. 爱普生EPSON实时时钟芯片-RX8900SA