OpenHarmony开发者论坛

标题: LiteOS启动流程分析(基于V3LTS版本) [打印本页]

作者: 润开鸿_闻飞    时间: 2024-9-11 15:16
标题: LiteOS启动流程分析(基于V3LTS版本)
[md]## 一、启动流程图

![image.png](https://forums-obs.openharmony.c ... 55iech60t5inwye.png "image.png")



## 二、LiteOS启动第一阶段(汇编阶段)

**代码路径:kernel/liteos\_a/arch/arm/arm/src/startup/reset\_vector\_mp.S**

**入口函数:reset\_vector**

**1、清寄存器TPIDRPRW**

[http://www.voidcn.com/article/p-oscrtoxb-bgz.html](http://www.voidcn.com/article/p-oscrtoxb-bgz.html)

```
   /* clear register TPIDRPRW */
   mov     r0, #0
   mcr     p15, 0, r0, c13, c0, 4
```

**对于ARMV6K和ARMv7版本,offset保存在TPIDRPRW寄存器中,这样是为了提升系统性能。**

**2、关cache和mmu**

```
   mrc     p15, 0, r0, c1, c0, 0
   bic     r0, #(1<<12)
   bic     r0, #(1<<2 | 1<<0)
   mcr     p15, 0, r0, c1, c0, 0
```

**3、使能fpu(浮点运算单元)和neon(***Neon*是适用于ARM Cortex-A系列处理器的一种128位SIMD(Single Instruction, Multiple Data,单指令、多数据)扩展结构。)

```
#ifndef LOSCFG_TEE_ENABLE
   MRC    p15, 0, r0, c1, c1, 2
   ORR    r0, r0, #0xC00
   BIC    r0, r0, #0xC000
   MCR    p15, 0, r0, c1, c1, 2

   LDR    r0, =(0xF << 20)
   MCR    p15, 0, r0, c1, c0, 2
   ISB
#endif
   MOV    r3, #0x40000000
   VMSR   FPEXC, r3          
```

**4、获取物理地址和虚拟地址的差值**

[https://www.cnblogs.com/w-smile/p/13855291.html](https://www.cnblogs.com/w-smile/p/13855291.html)

```
   ldr     r7, =__exception_handlers  /* r7: base of linked address (or vm address) */
   ldr     r6, =__bss_start /* r6: end of linked address (or vm address) */
   sub     r6, r7 /* r6: delta of linked address (or vm address) */
   add     r6, r4 /* r6: end of load address */

```

**5、代码重定位**

**        **判断是否需要重定位到合适位置

**        **重定位image到物理地址底部

```
   ldr     r7, =__exception_handlers           /* r7: base of linked address (or vm address) */
   ldr     r6, =__bss_start                    /* r6: end of linked address (or vm address) */
   sub     r6, r7                              /* r6: delta of linked address (or vm address) */
   add     r6, r4                              /* r6: end of load address */

reloc_img_to_bottom_loop:
   ldr     r7, [r4], #4
   str     r7, [r5], #4
   cmp     r4, r6
   bne     reloc_img_to_bottom_loop
   sub     pc, r12
   nop
   sub     r11, r11, r12                       /* r11: eventual address offset */

reloc_img_to_bottom_done:
#ifdef LOSCFG_KERNEL_MMU
   ldr     r4, =g_firstPageTable               /* r4: physical address of translation table and clear it */
   add     r4, r4, r11
   mov     r0, r4kernel/liteos_a/tools/build/liteos.ld
   mov     r1, #0
   mov     r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS
   bl      memset_optimized                    /* optimized memset since r0 is 64-byte aligned */

   ldr     r5, =g_archMmuInitMapping
   add     r5, r5, r11
init_mmu_loop:
   ldmia   r5!, {r6-r10}                       /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */
   cmp     r8, 0                               /* if size = 0, the mmu init done */
   beq     init_mmu_done
   bl      page_table_build
   b       init_mmu_loop
init_mmu_done:
   orr     r8, r4, #MMU_TTBRx_FLAGS            /* r8 = r4 and set cacheable attributes on translation walk */
   ldr     r4, =g_mmuJumpPageTable             /* r4: jump pagetable vaddr */
   add     r4, r4, r11
   ldr     r4, [r4]
   add     r4, r4, r11                         /* r4: jump pagetable paddr */
```

**6、设置1M的section映射,这里va == pa,方便后面的mmu跳转(这些都是在定义了los\_mmu的前提下)**

```
   /* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */
   mov     r6, pc
   mov     r7, r6                              /* r7: pa (MB aligned)*/
   lsr     r6, r6, #20                         /* r6: va l1 index */
   ldr     r10, =MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
   add     r12, r10, r6, lsl #20               /* r12: pa |flags */
   str     r12, [r4, r7, lsr #(20 - 2)]        /* jumpTable[paIndex] = pt entry */
   rsb     r7, r11, r6, lsl #20                /* r7: va */
   str     r12, [r4, r7, lsr #(20 - 2)]        /* jumpTable[vaIndex] = pt entry */

   bl      mmu_setup                           /* set up the mmu */
```

**7、清除中断、异常栈并设置magic num用于检查溢出**

```
ldr     r0, =__svc_stack
ldr     r1, =__exc_stack_top
bl      stack_init

STACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORD
STACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORD
```

**8、warm\_reset(热启动)**

[http://blog.sina.com.cn/s/blog\_a189aca10101se98.html](http://blog.sina.com.cn/s/blog_a189aca10101se98.html)

```
   /* initialize CPSR (machine state register) */
   mov    r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE)
   msr    cpsr, r0

   /* Note: some functions in LIBGCC1 will cause a "restore from SPSR"!! */
   msr    spsr, r0

   /* get cpuid and keep it in r12 */
   mrc     p15, 0, r12, c0, c0, 5
   and     r12, r12, #MPIDR_CPUID_MASK

   /* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack */
   ldr    r0, =__svc_stack_top
   mov    r2, #OS_EXC_SVC_STACK_SIZE
   mul    r2, r2, r12
   sub    r0, r0, r2
   mov    sp, r0

   LDR    r0, =__exception_handlers
   MCR    p15, 0, r0, c12, c0, 0

   cmp    r12, #0
   bne    cpu_start
```

**9、清除BSS**

```
   ldr    r0, =__bss_start
   ldr    r2, =__bss_end
   mov    r1, #0
   sub    r2, r2, r0
   bl     memset
```

**10、栈保护初始化(Stack-Protector Init)**

```
#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \
   defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \
   defined(LOSCFG_CC_STACKPROTECTOR)
   bl     __stack_chk_guard_setup
#endif
```

**11、启动GDB(可选)**

```
kernel/liteos_a/tools/build/liteos.ld#ifdef LOSCFG_GDB_DEBUG
   /* GDB_START - generate a compiled_breadk,This function will get GDB stubs started, with a proper environment */
   bl     GDB_START
   .word  0xe7ffdeff
#endif
```

**12、跳转main**

**三、LiteOS启动第二阶段(main)**

**代码路径:kernel/liteos\_a/platform/main.c**

**参考wiki:**[https://device.harmonyos.com/cn/ ... el-0000001127506594](https://device.harmonyos.com/cn/ ... el-0000001127506594)

**入口函数:**

**main**

**重要函数**

**OsMainkernel/liteos\_a/tools/build/liteos.ld**

**OsSchedStart**

**1、OsMain函数**

```
LITE_OS_SEC_BSS STATIC LosTaskCB                g_mainTask[LOSCFG_KERNEL_CORE_NUM];
#define LITE_OS_SEC_BSS         /* __attribute__((section(".bss.sram"))) */

#ifdef LOSCFG_KERNEL_SMP
#define LOSCFG_KERNEL_CORE_NUM                          2
#else
#define LOSCFG_KERNEL_CORE_NUM                          1
#endif
```

**liteos\_a中一次性定义了**

**1.1 OsInitCall------>InitLevelCall函数的定义**

**Liteos在初始化的时候会分不同阶段调用不同的字段内的函数接口并执行,通过OsInitCall函数实现,参数是段的**

```
OS_INIT_LEVEL_REG(kernel, 10, g_kernInitLevelList);
#define OS_INIT_LEVEL_REG(_type, _num, _list)       \
   INIT_LABEL_REG_##_num(EXTERN_LABEL, _type)      \
   STATIC struct ModuleInitInfo* _list [] = {      \
   ┊   INIT_LABEL_REG_##_num(GET_LABEL, _type)     \
   }

#define INIT_LABEL_REG_10(_op, _type)               \
   INIT_LABEL_REG_9(_op, _type)                    \
   _op(_type, 10)

#define EXTERN_LABEL(_type, _level) extern struct ModuleInitInfo __##_type##_init_level_##_level;

#define GET_LABEL(_type, _level) &__##_type##_init_level_##_level,
```

```
struct ModuleInitInfo {
   OsInitHook hook;
#ifdef LOS_INIT_DEBUG
   const CHAR *name;
#endif
};
extern struct ModuleInitInfo __kernel_init_level_0;
extern struct ModuleInitInfo __kernel_init_level_1;
...
extern struct ModuleInitInfo __kernel_init_level_10;
static struct ModuleInitInfo *g_kernInitLevelList[] = {
   &__kernel_init_level_0,
   &__kernel_init_level_1,
   ...
   &__kernel_init_level_10,
};
```

**InitLevelCall函数功能:**

```
InitLevelCall("Kernel", level, g_kernInitLevelList);
```

**取出g\_kernInitLevelList[level]字段内的所有函数然后执行一遍**

**关于\_\_kernel\_init\_level\_0等字段的链接脚本定义可参考目录:kernel/liteos\_a/tools/build/liteos.ld**

**1.2 OsTaskInite函数**

**系统一次性会创建129个task的内存池**

**task和Sched初始化**

```
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;
#define LOSCFG_BASE_CORE_TSK_LIMIT 128
```

**1.3 OsSysMemInit**

**OsKHeapInit堆内存初始化**

[https://www.xujun.org/note-122317.html](https://www.xujun.org/note-122317.html)

[https://www.tqwba.com/x\_d/jishu/286766.html](https://www.tqwba.com/x_d/jishu/286766.html)

```
#define HDF_INIT(module)  HDF_DRIVER_INIT(module)
#define HDF_DRIVER_INIT(module) \
   const size_t USED_ATTR module##HdfEntry HDF_SECTION = (size_t)(&(module))
#define USED_ATTR __attribute__((used))
#define HDF_SECTION __attribute__((section(".hdf.driver")))

const size_t __attribute__((used)) moduleHdfEntry __attribute__((section(".hdf.driver"))) = (size_t)(&(module))
```
[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5