今天就跟大家聊聊有关Zephyr OS 汇编阶段是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
Zephyr OS 内核篇:系统启动 - 汇编阶段
/* * Copyright (c) 2013-2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Reset handler * * Reset handler that prepares the system for running C code. */ #include <board.h> #include <toolchain.h> #include <sections.h> #include <arch/cpu.h> #include <offsets_short.h> #include "vector_table.h" _ASM_FILE_PROLOGUE GTEXT(__reset) GTEXT(memset) GDATA(_interrupt_stack) /** * * @brief Reset vector * * Ran when the system comes out of reset. The processor is in thread mode with * privileged level. At this point, the main stack pointer (MSP) is already * pointing to a valid area in SRAM. * * Locking interrupts prevents anything but NMIs and hard faults from * interrupting the CPU. A default NMI handler is already in place in the * vector table, and the boot code should not generate hard fault, or we're in * deep trouble. * * We want to use the process stack pointer (PSP) instead of the MSP, since the * MSP is to be set up to point to the one-and-only interrupt stack during later * boot. That would not be possible if in use for running C code. * * When these steps are completed, jump to _PrepC(), which will finish setting * up the system for running C code. * * @return N/A */ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__reset) /* * The entry point is located at the __reset symbol, which * is fetched by a XIP image playing the role of a bootloader, which jumps to * it, not through the reset vector mechanism. Such bootloaders might want to * search for a __start symbol instead, so create that alias here. */ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) /* lock interrupts: will get unlocked when switch to main task */ #if defined(CONFIG_ARMV6_M) cpsid i #elif defined(CONFIG_ARMV7_M) /** 直接将中断优先级 _EXC_IRQ_DEFAULT_PRIO 写入中断屏蔽寄存器 BASEPRI 所有优先级高于 _EXC_IRQ_DEFAULT_PRIO 的中断都会被屏蔽 */ movs.n r0, #_EXC_IRQ_DEFAULT_PRIO msr BASEPRI, r0 #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M */ #ifdef CONFIG_WDOG_INIT /* board-specific watchdog initialization is necessary */ bl _WdogInit #endif #ifdef CONFIG_INIT_STACKS /** 初始化中断栈空间,在汇编里面使用寄存器传递参数, r0 对应于 memset 的第一个参数 r1 对应于 memset 的第二个参数 r2 对应于 memset 的第三个参数 注意到,栈空间的初始化值是 0xaa,而不是 0x0。用于堆栈溢出检测 */ ldr r0, =_interrupt_stack ldr r1, =0xaa ldr r2, =CONFIG_ISR_STACK_SIZE bl memset #endif /* * Set PSP and use it to boot without using MSP, so that it * gets set to _interrupt_stack during nanoInit(). */ ldr r0, =_interrupt_stack ldr r1, =CONFIG_ISR_STACK_SIZE adds r0, r0, r1 msr PSP, r0 movs.n r0, #2 /* switch to using PSP (bit1 of CONTROL reg) */ msr CONTROL, r0 b _PrepC #if defined(CONFIG_SOC_TI_LM3S6965_QEMU) GTEXT(_do_software_reboot) SECTION_FUNC(TEXT,_do_software_reboot) eors r0, r0 /* move exception table back to 0 */ ldr r1, =0xe000e000 str r0, [r1, #0xd08] /* VTOR */ ldr r0, [r0, #4] bx r0 GTEXT(_force_exit_one_nested_irq) SECTION_FUNC(TEXT,_force_exit_one_nested_irq) ldr r0, =_SCS_ICSR_RETTOBASE ldr r1, =_SCS_ICSR ldr r1, [r1] ands.w r0, r1 /* * If Z flag is set, we are nested, so un-nest one level and get back to * this function to unwind the next level; else, exit the last interrupt * by jumping to reboot code. */ ittee eq ldreq lr, =0xfffffff1 ldreq r2, =_force_exit_one_nested_irq ldrne lr, =0xfffffffd ldrne r2, =_do_software_reboot ldr ip, =_interrupt_stack add.w ip, #(___esf_t_SIZEOF * 2) /* enough for a stack frame */ ldr r1, =0xfffffffe and.w r2, r1 str r2, [ip, #(6 * 4)] ldr r2, =0x01000000 str r2, [ip, #(7 * 4)] ite eq moveq sp, ip msrne PSP, ip bx lr #endif
看完上述内容,你们对Zephyr OS 汇编阶段是怎样的有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。