高通Qualcomm平台lk(light kernel)启动流程1——aboot_init()之前-阿里云开发者社区

开发者社区> 开发与运维> 正文

高通Qualcomm平台lk(light kernel)启动流程1——aboot_init()之前

简介: 0lk 启动总体流程 1lk启动流程代码 lk arch arm crt0S lk kernel mainc lk app appc 更多相关文章: 《高通Qualcomm平台lk(light kernel)启动流程1——aboot_init()之前》: http://blog.

更多相关文章:

《高通Qualcomm平台lk(light kernel)启动流程1——aboot_init()之前》:
http://blog.csdn.net/u014134180/article/details/78133916
《高通Qualcomm平台lk(light kernel)启动流程2——aboot_init()》:
http://blog.csdn.net/u014134180/article/details/78132580
《高通Qualcomm平台lk(light kernel)启动流程3——到高通lcm屏点亮》:
http://blog.csdn.net/u014134180/article/details/78177040

《[lcm] Qualcomm Android Display Subsystem 架构》
http://blog.csdn.net/u014134180/article/details/78129502

《[lcm] Qualcomm平台的显示屏lcd驱动移植步骤》:
http://blog.csdn.net/u014134180/article/details/78129499
《[lcm] Qualcomm平台兼容多显示屏lcd的方法&并从lk传输到kernel过程》:
http://blog.csdn.net/u014134180/article/details/78166978
《[lcm] Qualcomm平台显示屏lcd添加I2C读取功能》:
http://blog.csdn.net/u014134180/article/details/78176160

0、lk 启动总体流程

这里写图片描述

1、lk启动流程代码

lk/ arch/ arm/ crt0.S

/*
 * Copyright (c) 2008 Travis Geiselbrecht
 *
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5

.section ".text.boot"
.globl _start
_start:
    b   reset
    b   arm_undefined
    b   arm_syscall
    b   arm_prefetch_abort
    b   arm_data_abort
    b   arm_reserved
    b   arm_irq
    b   arm_fiq

reset:

#ifdef ENABLE_TRUSTZONE
    /*Add reference to TZ symbol so linker includes it in final image */
    ldr r7, =_binary_tzbsp_tzbsp_bin_start
#endif
    /* do some cpu setup */
#if ARM_WITH_CP15
        /* Read SCTLR */
    mrc     p15, 0, r0, c1, c0, 0
        /* XXX this is currently for arm926, revist with armv6 cores */
        /* new thumb behavior, low exception vectors, i/d cache disable, mmu disabled */
    bic     r0, r0, #(1<<15| 1<<13 | 1<<12)
    bic     r0, r0, #(1<<2 | 1<<0)
        /* disable alignment faults */
    bic     r0, r0, #(1<<1)
    /* Enable CP15 barriers by default */
#ifdef ARM_CORE_V8
    orr     r0, r0, #(1<<5)
#endif
        /* Write SCTLR */
    mcr     p15, 0, r0, c1, c0, 0
#ifdef ENABLE_TRUSTZONE
  /*nkazi: not needed ? Setting VBAR to location of new vector table : 0x80000      */
 ldr             r0, =0x00080000
 mcr             p15, 0, r0, c12, c0, 0
#endif
#endif

#if WITH_CPU_EARLY_INIT
    /* call platform/arch/etc specific init code */
#ifndef ENABLE_TRUSTZONE
    /* Not needed when TrustZone is the first bootloader that runs.*/
    bl __cpu_early_init
#endif
    /* declare return address as global to avoid using stack */
.globl _cpu_early_init_complete
    _cpu_early_init_complete:

#endif

#if (!ENABLE_NANDWRITE)
#if WITH_CPU_WARM_BOOT
    ldr     r0, warm_boot_tag
    cmp     r0, #1

    /* if set, warm boot */
    ldreq   pc, =BASE_ADDR

    mov     r0, #1
    str r0, warm_boot_tag
#endif
#endif

    /* see if we need to relocate */
    mov     r0, pc
    sub     r0, r0, #(.Laddr - _start)
.Laddr:
    ldr     r1, =_start
    cmp     r0, r1
    beq     .Lstack_setup

    /* we need to relocate ourselves to the proper spot */
    ldr     r2, =__data_end 

.Lrelocate_loop:
    ldr     r3, [r0], #4
    str     r3, [r1], #4
    cmp     r1, r2
    bne     .Lrelocate_loop

    /* we're relocated, jump to the right address */
    ldr     r0, =.Lstack_setup
    bx      r0

.ltorg
#if WITH_CPU_WARM_BOOT
warm_boot_tag:
    .word 0
#endif

.Lstack_setup:
    /* set up the stack for irq, fiq, abort, undefined, system/user, and lastly supervisor mode */
    mrs     r0, cpsr
    bic     r0, r0, #0x1f

    ldr     r2, =abort_stack_top
    orr     r1, r0, #0x12 // irq
    msr     cpsr_c, r1
    ldr     r13, =irq_save_spot     /* save a pointer to a temporary dumping spot used during irq delivery */

    orr     r1, r0, #0x11 // fiq
    msr     cpsr_c, r1
    mov     sp, r2

    orr     r1, r0, #0x17 // abort
    msr     cpsr_c, r1
    mov     sp, r2

    orr     r1, r0, #0x1b // undefined
    msr     cpsr_c, r1
    mov     sp, r2

    orr     r1, r0, #0x1f // system
    msr     cpsr_c, r1
    mov     sp, r2

    orr     r1, r0, #0x13 // supervisor
    msr     cpsr_c, r1
    mov     sp, r2

    /* copy the initialized data segment out of rom if necessary */
    ldr     r0, =__data_start_rom
    ldr     r1, =__data_start
    ldr     r2, =__data_end

    cmp     r0, r1
    beq     .L__do_bss

.L__copy_loop:
    cmp     r1, r2
    ldrlt   r3, [r0], #4
    strlt   r3, [r1], #4
    blt     .L__copy_loop

.L__do_bss:
    /* clear out the bss */
    ldr     r0, =__bss_start
    ldr     r1, =_end
    mov     r2, #0
.L__bss_loop:
    cmp     r0, r1
    strlt   r2, [r0], #4
    blt     .L__bss_loop

#ifdef ARM_CPU_CORTEX_A8
    DSB
    ISB
#endif

    bl      kmain
    b       .

.ltorg

.bss
.align 2
    /* the abort stack is for unrecoverable errors.
     * also note the initial working stack is set to here.
     * when the threading system starts up it'll switch to a new 
     * dynamically allocated stack, so we don't need it for very long
     */
abort_stack:
    .skip 1024
abort_stack_top:

lk/ kernel/ main.c

/*
 * Copyright (c) 2008 Travis Geiselbrecht
 *
 * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <compiler.h>
#include <debug.h>
#include <string.h>
#include <app.h>
#include <arch.h>
#include <platform.h>
#include <target.h>
#include <lib/heap.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
#include <kernel/dpc.h>
#include <boot_stats.h>

extern void *__ctor_list;
extern void *__ctor_end;
extern int __bss_start;
extern int _end;

static int bootstrap2(void *arg);

#if (ENABLE_NANDWRITE)
void bootstrap_nandwrite(void);
#endif

static void call_constructors(void)
{
    void **ctor;

    ctor = &__ctor_list;
    while(ctor != &__ctor_end) {
        void (*func)(void);

        func = (void (*)())*ctor;

        func();
        ctor++;
    }
}

/* called from crt0.S */
void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE;
void kmain(void)
{
    thread_t *thr;

    // get us into some sort of thread context
    thread_init_early();

    // early arch stuff
    arch_early_init();

    // do any super early platform initialization
    platform_early_init();

    // do any super early target initialization
    target_early_init();

    dprintf(INFO, "welcome to lk\n\n");
    bs_set_timestamp(BS_BL_START);

    // deal with any static constructors
    dprintf(SPEW, "calling constructors\n");
    call_constructors();

    // bring up the kernel heap
    dprintf(SPEW, "initializing heap\n");
    heap_init();

    __stack_chk_guard_setup();

    // initialize the threading system
    dprintf(SPEW, "initializing threads\n");
    thread_init();

    // initialize the dpc system
    dprintf(SPEW, "initializing dpc\n");
    dpc_init();

    // initialize kernel timers
    dprintf(SPEW, "initializing timers\n");
    timer_init();

#if (!ENABLE_NANDWRITE)
    // create a thread to complete system initialization
    dprintf(SPEW, "creating bootstrap completion thread\n");
    thr = thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
    if (!thr)
    {
        panic("failed to create thread bootstrap2\n");
    }
    thread_resume(thr);


    // enable interrupts
    exit_critical_section();

    // become the idle thread
    thread_become_idle();
#else
        bootstrap_nandwrite();
#endif
}

int main(void);

static int bootstrap2(void *arg)
{
    dprintf(SPEW, "top of bootstrap2()\n");

    arch_init();

    // XXX put this somewhere else
#if WITH_LIB_BIO
    bio_init();
#endif
#if WITH_LIB_FS
    fs_init();
#endif

    // initialize the rest of the platform
    dprintf(SPEW, "initializing platform\n");
    platform_init();

    // initialize the target
    dprintf(SPEW, "initializing target\n");
    target_init();

    dprintf(SPEW, "calling apps_init()\n");
    apps_init();

    return 0;
}

#if (ENABLE_NANDWRITE)
void bootstrap_nandwrite(void)
{
    dprintf(SPEW, "top of bootstrap2()\n");

    arch_init();

    // initialize the rest of the platform
    dprintf(SPEW, "initializing platform\n");
    platform_init();

    // initialize the target
    dprintf(SPEW, "initializing target\n");
    target_init();

    dprintf(SPEW, "calling nandwrite_init()\n");
    nandwrite_init();

    return 0;
}
#endif

lk/ app/ app.c

/*
 * Copyright (c) 2009 Travis Geiselbrecht
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <debug.h>
#include <app.h>
#include <kernel/thread.h>

extern const struct app_descriptor __apps_start;
extern const struct app_descriptor __apps_end;

static void start_app(const struct app_descriptor *app);

/* one time setup */
void apps_init(void)
{
    const struct app_descriptor *app;

    /* call all the init routines */
    for (app = &__apps_start; app != &__apps_end; app++) {
        if (app->init)
            app->init(app);
    }

    /* start any that want to start on boot */
    for (app = &__apps_start; app != &__apps_end; app++) {
        if (app->entry && (app->flags & APP_FLAG_DONT_START_ON_BOOT) == 0) {
            start_app(app);
        }
    }
}

static int app_thread_entry(void *arg)
{
    const struct app_descriptor *app = (const struct app_descriptor *)arg;

    app->entry(app, NULL);

    return 0;
}

static void start_app(const struct app_descriptor *app)
{
    thread_t *thr;
    printf("starting app %s\n", app->name);

    thr = thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
    if(!thr)
    {
        return;
    }
    thread_resume(thr);
}

Wu_Being博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
《高通Qualcomm平台lk(light kernel)启动流程1——aboot_init()之前》: http://blog.csdn.net/u014134180/article/details/78133916

Wu_Being 吴兵博客接受赞助费二维码

如果你看完这篇博文,觉得对你有帮助,并且愿意付赞助费,那么我会更有动力写下去。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章