liteOS-A学习笔记-1.环境搭建过程中遇到的问题+启动流程分析

韦东山老师教学视频

0.环境搭建过程中遇到的问题

1.解决THE FOLLOWING PACKAGES HAVE UNMET DEPENDENCIES问题!!!

终于搭建完成开发环境:
在这里插入图片描述
2.执行编译指令报错
在这里插入图片描述
报错了
Ubuntu下手动安装clang:

apt-get install clang

进入《Configuring_ubuntu.sh》文件搜索clang,发现如下代码,这是该脚本不支持ubuntu16的意思么?
似乎是…
经过实测需要使用ubuntu18.04
在这里插入图片描述

1.启动流程分析

reset_vector_up.s
1.关中断;设置CPU为SVC32模式;

	/*
	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
	 * except if in HYP mode already
	 */
	mrs	r0, cpsr
	and	r1, r0, #0x1f		@ mask mode bits
	teq	r1, #0x1a		@ test for HYP mode
	bicne	r0, r0, #0x1f		@ clear all mode bits
	orrne	r0, r0, #0x13		@ set SVC mode
	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
	msr	cpsr,r0

2.禁止I-cache;

	/*
	 * If I-cache is enabled invalidate it
	 */
	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
	mcr     p15, 0, r0, c7, c10, 4	@ DSB
	mcr     p15, 0, r0, c7, c5, 4	@ ISB

3.重定位(把程序复制到运行地址);

/* r11: delta of physical address and virtual address */
adr     r11, pa_va_offset //把变量pa_va_offset的地址给r11
ldr     r0, [r11]		  //把变量r11存储的变量作为地址,指向的数据给r0
sub     r11, r11, r0      //计算地址偏差

/* if we need to relocate to proper location or not */
adr     r4, __exception_handlers            /* r4: base of load address */
											/*__exception_handlers就是异常向量表的首地址,也就是整个程序运行的首地址*/
ldr     r5, =SYS_MEM_BASE                   /* r5: base of physical address*/
											/* 处理器内部DDR的物理空间起始地址 */
subs    r12, r4, r5                         /* r12: delta of load address and physical address */
beq     reloc_img_to_bottom_done            /* if we load image at the bottom of physical address */
											/* 若当前的运行地址和物理地址一致,则跳转到下面的函数,无需进行进行搬运 ,即重定位*/

3.1.搬运分支

    /* we need to relocate image at the bottom of physical address */
    ldr     r7, =__exception_handlers           /* r7: base of linked address (or vm address) */
    											/* r7=实际程序代码段的首地址 */
    ldr     r6, =__bss_start                    /* r6: end of linked address (or vm address) */
        										/* r6=实际程序代码段的末地址 */
    sub     r6, r7                              /* r6: delta of linked address (or vm address) */
        										/* r6=实际程序代码段的长度 */
    add     r6, r4                              /* r6: end of load address */
        										/* r6=实际程序代码段的末地址 */
    /* 循环搬运 */
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 */

3.2.无需搬运分支

    ldr     r4, =g_firstPageTable               /* r4: physical address of translation table and clear it */
            									/* r4=页表的物理地址起始地址 */
    add     r4, r4, r11
    bl      page_table_clear					/* 页表空间清零 */

4.LINE175:设置页表(虚拟地址转换为物理地址),代码如下

    PAGE_TABLE_SET SYS_MEM_BASE, UNCACHED_VMM_BASE, UNCACHED_VMM_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED
#ifdef LOSCFG_PLATFORM_IMX6ULL
    PAGE_TABLE_SET DDR_RAMFS_ADDR, DDR_RAMFS_VBASE, DDR_RAMFS_SIZE, MMU_INITIAL_MAP_DEVICE
    PAGE_TABLE_SET LCD_FB_BASE, LCD_FB_VBASE, LCD_FB_SIZE, MMU_INITIAL_MAP_DEVICE
#endif
    PAGE_TABLE_SET SYS_MEM_BASE, KERNEL_VMM_BASE, KERNEL_VMM_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
    PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_DEVICE_BASE, PERIPH_DEVICE_SIZE, MMU_INITIAL_MAP_DEVICE
    PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_CACHED_BASE, PERIPH_CACHED_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
    PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_UNCACHED_BASE, PERIPH_UNCACHED_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED

其中,PAGE_TABLE_SET 为宏定义,其定义在reset_vector_up.s为:

/* param0 is physical address, 物理地址
   param1 virtual address, 虚拟地址
   param2 is sizes, 大小
   param3 is flag 标志
   */
.macro PAGE_TABLE_SET param0, param1, param2, param3
    ldr     r6, =\param0
    ldr     r7, =\param1
    ldr     r8, =\param2
    ldr     r10, =\param3
    bl      page_table_build
.endm

在MMU启动之前,CPU发出的地址可以直接到达设备,之后则需要经过MMU再发给设备(关于页表和MMU的具体值是参见《嵌入式Linux应用开发完全手册_韦东山全系列视频文档全集V2.4》P639)

bl      mmu_setup                           /* set up the mmu */

5.多核心CPU的处理方式

    /* get cpuid and keep it in r11 */
    mrc     p15, 0, r11, c0, c0, 5
    and     r11, r11, #MPIDR_CPUID_MASK
    /* 判断当前的core是否为核0,若为核0则初始化堆栈,若不是则跳过 */
    cmp     r11, #0
    bne     excstatck_loop_done

excstatck_loop:
    /* clear out the interrupt and exception stack and set magic num to check the overflow */
    ldr     r0, =__undef_stack
    ldr     r1, =__exc_stack_top
    bl      stack_init

    STACK_MAGIC_SET __undef_stack, #OS_EXC_UNDEF_STACK_SIZE, OS_STACK_MAGIC_WORD
    STACK_MAGIC_SET __abt_stack, #OS_EXC_ABT_STACK_SIZE, OS_STACK_MAGIC_WORD
    STACK_MAGIC_SET __irq_stack, #OS_EXC_IRQ_STACK_SIZE, OS_STACK_MAGIC_WORD
    STACK_MAGIC_SET __fiq_stack, #OS_EXC_FIQ_STACK_SIZE, OS_STACK_MAGIC_WORD
    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

excstatck_loop_done:

6.设置堆栈

    /* 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, r11
    sub    r0, r0, r2
    mov    sp, r0

7.设置FPU+NEON

    /* enable fpu+neon */
    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

    MOV    r3, #0x40000000
    VMSR   FPEXC, r3

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

    cmp    r11, #0
    bne    cpu_start

8.跳转到main函数

bl     main

9.跳转到main函数-路径\kernel\liteos_a\platform

LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
{
    UINT32 uwRet = LOS_OK;

    OsSetMainTask();
    OsCurrTaskSet(OsGetMainTask());

    /* set smp system counter freq */
#if (LOSCFG_KERNEL_SMP == YES)
#ifndef LOSCFG_TEE_ENABLE
    HalClockFreqWrite(OS_SYS_CLOCK);
#endif
#endif

    /* system and chip info */
    OsSystemInfo();

    PRINT_RELEASE("\nmain core booting up...\n");

    uwRet = OsMain();
    if (uwRet != LOS_OK) {
        return LOS_NOK;
    }

#if (LOSCFG_KERNEL_SMP == YES)
    PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1);
    release_secondary_cores();
#endif

    CPU_MAP_SET(0, OsHwIDGet());

    OsStart();

    while (1) {
        __asm volatile("wfi");
    }
}

7.跳转到uwRet = OsMain();函数
(1)串口初始化;uart_init();
(2)操作系统任务初始化;ret = OsTaskInit();
(3)操作系统内存初始化;ret = OsSysMemInit();

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值