Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65605
  • 博文数量: 16
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 42
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-07 00:05
文章分类

全部博文(16)

文章存档

2016年(1)

2015年(4)

2014年(11)

我的朋友

分类: 其他平台

2016-10-03 09:12:25

-------- 转载请注明出处
文中使用的是
nuttx-7.17

Nuttx系统编译(主要针对arm体系结构 ):

编译离不开工具链,而arm工具链是在各体系结构下的Toolchain.defs文件中定义的,arm7/9nuttx\arch\arm\src\arm文件中,Cortex-M3/M4/M7nuttx\arch\arm\src\armv7-m文件中,Cortex-M0nuttx\arch\arm\src\armv6-m文件中。

而编译器选择相关的配置在nuttx\configs\xxx\nsh目录的defconfig文件中定义,同时这个文件会被重命名为.config和该目录下的Make.defssetenv.sh文件一起复制到根目录下。这一步可以通过在nuttx\tool中执行 ./configure.sh  /来完成,其中就是nuttx\configs中的目录名,而是包含上述三个文件的目录。

CONFIG_HOST_LINUX=y 定义主机环境

CONFIG_ARCH_ARM=y  定义开发板架构

CONFIG_ARCH_CHIP_STM32=y  定义芯片厂商

CONFIG_ARCH_CORTEXM3=y           定义芯片内核

CONFIG_ARCH_FAMILY="armv7-m"  定义芯片的体系结构

CONFIG_ARM_TOOLCHAIN_GNU=y

CONFIG_ARMXXX_TOOLCHAIN?_XXX定义使用的工具链:

             CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT=y      : NuttX buildroot under Linux or Cygwin (default)

             CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y      : Generic GCC ARM EABI toolchain for Linux

             CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y      : Generic GCC ARM EABI toolchain for Windows

以上这些宏定义都辅助Toolchain.defs文件来判断具体使用的交叉工具链。
总之,开始编译前
nuttx\configs\xxx\nsh目录中Make.defssetenv.sh文件被复制到根目录下。
    setenv.sh
文件会将编译工具目录加到系统环境变量中。
    Make.defs
指定了编译相关的选项,同时也指定了链接脚本的路径,该脚本的主要目的是指定了如何把输入文件中的节(sections)映射到输出文件中,并控制输出文件的存储布局。这里的输出文件可以认为就是bin文件。
    deconfig
会重命名为.config文件复制到根目录,编译过程中会根据该文件自动生成nuttx\include\nuttx目录中的config.h文件,该文件中定义了各种宏是系统编译的基础。

NuttX 启动流程

本文以stm32cm3内核为例介绍,cortexm3内核在上电后,首先会把中断向量表中偏移地址0处的值赋给SP指针,然后把偏移地址04地址(Reset vector)的值赋给PC进入该函数开始执行。这里用到偏移地址是因为CM3的中断向量表基址是可以通过NVIC中的一个寄存器,称为“向量表偏移寄存器”(0xE000_ED08)来配置的。

要追踪系统的启动流程就必须知道程序的入口,而要知道程序入口只要找到链接脚本就可以,链接脚本目录是通过Make.defs中的变量ARCHSCRIPT指定的即在目录nuttx\configs\XXX\scripts中,

点击(此处)折叠或打开

  1. .text : {
  2. _stext = ABSOLUTE(.);
  3. *(.vectors)
  4. *(.text .text.*)
  5. *(.fixup)
  6. *(.gnu.warning)
  7. *(.rodata .rodata.*)
  8. *(.gnu.linkonce.t.*)
  9. *(.glue_7)
  10. *(.glue_7t)
  11. *(.got)
  12. *(.gcc_except_table)
  13. *(.gnu.linkonce.r.*)
  14. _etext = ABSOLUTE(.);
  15. } > flash
    对于CM3核该文件首先加载的是*(.vectors),即中断向量表。该向量表是选择位于nuttx\arch\arm\src\stm32\gnu目录中的stm32_vectors.S中,还是nuttx\arch\arm\src\目录中的up_vectors.c中,这个需要查看nuttx-7.17\arch\arm\src\stm32目录中的Make.defs文件

点击(此处)折叠或打开

  1. ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
  2. HEAD_ASRC =
  3. else
  4. HEAD_ASRC = stm32_vectors.S
  5. endif

  6. CMN_UASRCS =
  7. CMN_UCSRCS =

  8. CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
  9. CMN_ASRCS += up_testset.S vfork.S

  10. CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c
  11. CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c
  12. CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c
  13. CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c
  14. CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c
  15. CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c
  16. CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c
  17. CMN_CSRCS += up_hardfault.c up_svcall.c up_vfork.c

  18. ifeq ($(CONFIG_ARMV7M_STACKCHECK),y)
  19. CMN_CSRCS += up_stackcheck.c
  20. endif

  21. ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
  22. ifeq ($(CONFIG_ARMV7M_LAZYFPU),y)
  23. CMN_ASRCS += up_lazyexception.S
  24. else
  25. CMN_ASRCS += up_exception.S
  26. endif
  27. CMN_CSRCS += up_vectors.c
  28. endif

通过该文件可以知道如果在.config文件中没有配置CONFIG_ARMV7M_CMNVECTOR宏就会选择stm32_vectors.S,否则选择up_vectors.c,不论如何配置0x04地址对应的__start函数位于nuttx-7.17\arch\arm\src\stm32目录的stm32_start.c文件中

点击(此处)折叠或打开

  1. void __start(void)
  2. {
  3.   const uint32_t *src;
  4.   uint32_t *dest;

  5. #ifdef CONFIG_ARMV7M_STACKCHECK
  6.   /* Set the stack limit before we attempt to call any functions */

  7.   __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : );
  8. #endif

  9.   /* Configure the UART so that we can get debug output as soon as possible */

  10.   stm32_clockconfig();
  11.   stm32_fpuconfig();
  12.   stm32_lowsetup();
  13.   stm32_gpioinit();
  14.   showprogress('A');

  15.   /* Clear .bss. We'll do this inline (vs. calling memset) just to be
  16.    * certain that there are no issues with the state of global variables.
  17.    */

  18.   for (dest = _START_BSS; dest < _END_BSS; )
  19.     {
  20.       *dest++ = 0;
  21.     }

  22.   showprogress('B');

  23.   /* Move the initialized data section from his temporary holding spot in
  24.    * FLASH into the correct place in SRAM. The correct place in SRAM is
  25.    * give by _sdata and _edata. The temporary location is in FLASH at the
  26.    * end of all of the other read-only data (.text, .rodata) at _eronly.
  27.    */

  28.   for (src = _DATA_INIT, dest = _START_DATA; dest < _END_DATA; )
  29.     {
  30.       *dest++ = *src++;
  31.     }

  32.   showprogress('C');

  33. #ifdef CONFIG_ARMV7M_ITMSYSLOG
  34.   /* Perform ARMv7-M ITM SYSLOG initialization */

  35.   itm_syslog_initialize();
  36. #endif

  37.   /* Perform early serial initialization */

  38. #ifdef USE_EARLYSERIALINIT
  39.   up_earlyserialinit();
  40. #endif
  41.   showprogress('D');

  42.   /* For the case of the separate user-/kernel-space build, perform whatever
  43.    * platform specific initialization of the user memory is required.
  44.    * Normally this just means initializing the user space .data and .bss
  45.    * segments.
  46.    */

  47. #ifdef CONFIG_BUILD_PROTECTED
  48.   stm32_userspace();
  49.   showprogress('E');
  50. #endif

  51.   /* Initialize onboard resources */

  52.   stm32_boardinitialize();
  53.   showprogress('F');

  54.   /* Then start NuttX */

  55.   showprogress('\r');
  56.   showprogress('\n');

  57. #ifdef CONFIG_STACK_COLORATION
  58.   /* Set the IDLE stack to the coloration value and jump into os_start() */

  59.   go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE);
  60. #else
  61.   /* Call os_start() */

  62.   os_start();

  63.   /* Shoulnd't get here */

  64.   for (; ; );
  65. #endif
  66. }
完成一系列初始化后调用nuttx\sched\init目录os_start.c中的os_start()函数,进入nutxx内核初始化和启动过程中。
阅读(4239) | 评论(0) | 转发(0) |
0

上一篇:从头构建自己的Linux系统

下一篇:没有了

给主人留下些什么吧!~~