Tiny4412 u-boot分析(2)u-boot启动流程

从大方面来说,u-boot的启动分成两个阶段,第一个阶段主要的职责是准备初始化的环境,主要有以下几点

①设置异常向量表

②把CPU的工作模式设置为SVC32模式

③关闭中断、MMU和cache

④关闭看门狗

⑤初始化内存、时钟、串口

⑥设置堆栈

⑦代码搬移

⑧清bss段

⑨跳转到c语言中执行(第二阶段)

此时系统还没有进入C语言的运行阶段,并没有堆栈,也就不需要额外的RAM。

第二阶段在上一段建立好C语言运行环境的基础上,进行各种外设的初始化,并循环执行用户命令。主要流程图如下

当我们执行make命令来构建u-boot时,它的构建过程是:首先使用交叉编译工具将各目录下的源文件生成目标文件(*.o),目标文件生成后,会将若干个目标文件组合成静态库文件(*.a),最后通过链接各个静态库文件生成ELF格式的可执行文件。在链接的过程中,需要根据链接脚本(一般是各个以lds为后缀的文本文件),确定目标文件的各个段,链接文件通常是board/<board>/目录中的u-boot.lds文件。一般在链接脚本中通过

ENTRY(_start)

来指定入口为_start标号,通过文本段(.text)的第一个目标来制定u-boot入口文件。所以我们通过这个链接脚本文件可以确定u-boot执行的入口。

Tiny4412 u-boot的链接脚本内容为

//  board/samsung/tiny4412/u-boot.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
    . = 0x00000000;
    . = ALIGN(4);
    .text    :
    {
        arch/arm/cpu/armv7/start.o    (.text)
        board/samsung/tiny4412/libtiny4412.o (.text)
        arch/arm/cpu/armv7/exynos/libexynos.o    (.text)
        *(.text)
    }
    . = ALIGN(4);
    .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
    . = ALIGN(4);
    .data : {
        *(.data)
    }
    . = ALIGN(4);
    . = .;
    __u_boot_cmd_start = .;
    .u_boot_cmd : { *(.u_boot_cmd) }
    __u_boot_cmd_end = .;
    . = ALIGN(4);
    .rel.dyn : {
        __rel_dyn_start = .;
        *(.rel*)
        __rel_dyn_end = .;
    }
    .dynsym : {
        __dynsym_start = .;
        *(.dynsym)
    }
    .bss __rel_dyn_start (OVERLAY) : {
        __bss_start = .;
        *(.bss)
         . = ALIGN(4);
        _end = .;
    }
    /DISCARD/ : { *(.dynstr*) }
    /DISCARD/ : { *(.dynamic*) }
    /DISCARD/ : { *(.plt*) }
    /DISCARD/ : { *(.interp*) }
    /DISCARD/ : { *(.gnu*) }
}

在本链接脚本文件中,定义了起始地址为0x00000000,每个段使用4字节对齐(.ALIGN(4)),几个段分别为代码段(.text)、只读数据段(.rodata)、数据段(.data)其中,代码段的第一个目标为arch/arm/cpu/armv7/start.o,在其中定义了映像文件的入口_start。

下面来具体分析一下这个start.S。

在文件的一开始定义了映像的入口_start和中断向量表。

.globl _start  //定义u-boot入口
_start: b       reset   //设置中断向量表
        ldr     pc, _undefined_instruction
        ldr     pc, _software_interrupt
        ldr     pc, _prefetch_abort
        ldr     pc, _data_abort
        ldr     pc, _not_used
        ldr     pc, _irq
        ldr     pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt:    .word software_interrupt
_prefetch_abort:        .word prefetch_abort
_data_abort:            .word data_abort
_not_used:              .word not_used
_irq:                   .word irq
_fiq:                   .word fiq
_pad:                   .word 0x12345678 /* now 16*4=64 */

系统开机进入到u-boot运行时,首先进入到u-boot的入口_start标号处,然后通过 b  reset 跳转到reset标号处,我们就到reset标号一探究竟。

/*
 * the actual reset code
 */
reset:
    /*
         *设置CPU工作模式为SVC32模式
     * set the cpu to SVC32 mode
     */
    mrs    r0, cpsr
    bic    r0, r0, #0x1f
    orr    r0, r0, #0xd3
    msr    cpsr,r0
//......
//调用 cpu_init_crit
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_crit
#endif

首先会将CPU的工作模式设置为svc32模式,然后便调用 cpu_init_crit ,需要注意的是,这里使用的是 bl 指令,也就是说在运行完 cpu_init_crit 标号处的代码之后,会通过

mov    pc, lr            @ back to my caller

指令回到reset中继续执行

bl    cpu_init_crit

下面的指令(所以这里我们应该使用 调用来描述更为贴切)。下面我们去看一下 cpu_init_crit 指令处做了哪些事

/*************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************/
cpu_init_crit:

        //调用 cache_init
    bl cache_init

    /*
         *使  L1 I/D 无效
     * Invalidate L1 I/D
     */
    mov    r0, #0            @ set up for MCR
    mcr    p15, 0, r0, c8, c7, 0    @ invalidate TLBs
    mcr    p15, 0, r0, c7, c5, 0    @ invalidate icache
    /*
         * 关闭 MMU 和 cache
     * disable MMU stuff and caches
     */
    mrc    p15, 0, r0, c1, c0, 0
    bic    r0, r0, #0x00002000    @ clear bits 13 (--V-)
    bic    r0, r0, #0x00000007    @ clear bits 2:0 (-CAM)
    orr    r0, r0, #0x00000002    @ set bit 1 (--A-) Align
    orr    r0, r0, #0x00000800    @ set bit 12 (Z---) BTB
    mcr    p15, 0, r0, c1, c0, 0
    /*
     * Jump to board specific initialization...
     * The Mask ROM will have already initialized
     * basic memory. Go here to bump up clock rate and handle
     * wake up conditions.
     */
    mov    ip, lr            @ persevere link reg across call
        //调用 lowlevel_init
    bl    lowlevel_init        @ go setup pll,mux,memory
    mov    lr, ip            @ restore link
        //返回到 reset 标号继续执行
    mov    pc, lr            @ back to my caller
/*

首先分析 cache_init ,它被定义在  board/samsung/tiny4412/lowlevel_init.S 文件中

    .globl cache_init
cache_init:
    mov pc, lr

可以看出来,这是一个空函数(暂且将它叫做函数-_-!!)。

接下来我们就要去分析 lowlevel_init 了,它也被定义在board/samsung/tiny4412/lowlevel_init.S 文件中

    .globl lowlevel_init
lowlevel_init:

    //初始化串口
    bl uart_asm_init

  //Read booting information
  //读取启动信息
    bl read_om
    /* when we already run in ram, we don‘t need to relocate U-Boot.
     * and actually, memory controller must be configured before U-Boot
     * is running in ram.
     */
    ldr    r0, =0xff000fff
    bic    r1, pc, r0        /* r0 <- current base addr of code */
    ldr    r2, _TEXT_BASE    /* r1 <- original base addr in ram */
    bic    r2, r2, r0        /* r0 <- current base addr of code */
    cmp r1, r2            /* compare r0, r1 */
    beq after_copy        /* r0 == r1 then skip sdram init and u-boot.bin loading */
   //初始化内存
    /* Memory initialize */
    bl mem_ctrl_asm_init
  //初始化系统时钟
    /* init system clock */
    bl system_clock_init

  /*
      eg:
        1: ;A
        cmp r0, #0
        beq 1f ; r0==0那么向前跳转到B处执行
        bne 1b ; 否则向后跳转到A处执行
        :1: ;B
  */

  // 向前跳转到1: 标号处执行
    b  1f
1:
  //初始化 trust zone
    bl tzpc_init
    b load_uboot
after_copy:
#ifdef CONFIG_ENABLE_MMU
    bl enable_mmu
#endif
    /* store second boot information in u-boot C level variable */
    ldr r0, =CONFIG_PHY_UBOOT_BASE
    sub r0, r0, #8
    ldr r1, [r0]
    ldr r0, _second_boot_info
    str r1, [r0]
    /* Print ‘K‘ */
    ldr    r0, =S5PV310_UART_CONSOLE_BASE
    ldr    r1, =0x4b4b4b4b
    str    r1, [r0, #UTXH_OFFSET]
  //第二阶段入口,调用C语言函数:board_init_f
    ldr r0, _board_init_f
    mov pc, r0

_board_init_f:
    .word board_init_f
load_uboot:
    ldr    r0, =INF_REG_BASE
    ldr    r1, [r0, #INF_REG3_OFFSET]
    cmp    r1, #BOOT_NAND
    beq    nand_boot
    cmp    r1, #BOOT_ONENAND
    beq    onenand_boot
    cmp     r1, #BOOT_MMCSD
    beq     mmcsd_boot
    cmp    r1, #BOOT_EMMC
    beq    emmc_boot
    cmp    r1, #BOOT_EMMC_4_4
    beq    emmc_boot_4_4
    cmp     r1, #BOOT_NOR
    beq     nor_boot
    cmp     r1, #BOOT_SEC_DEV
    beq     mmcsd_boot
nand_boot:
    mov    r0, #0x1000
    bl    copy_uboot_to_ram
    b    after_copy
onenand_boot:
    bl    onenand_bl2_copy /*goto 0x1010*/
    b    after_copy
mmcsd_boot:
#ifdef CONFIG_SMDKC220
//#ifdef CONFIG_CLK_BUS_DMC_200_400
    ldr    r0, =ELFIN_CLOCK_BASE
    ldr    r2, =CLK_DIV_FSYS2_OFFSET
    ldr    r1, [r0, r2]
    orr r1, r1, #0xf
    str r1, [r0, r2]
//#endif
#else
#if defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
    ldr    r0, =ELFIN_CLOCK_BASE
    ldr    r2, =CLK_DIV_FSYS2_OFFSET
    ldr    r1, [r0, r2]
    orr r1, r1, #0xf
    str r1, [r0, r2]
#endif
#endif
    bl      movi_uboot_copy
    b       after_copy
emmc_boot:
#if defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
    ldr    r0, =ELFIN_CLOCK_BASE
    ldr    r2, =CLK_DIV_FSYS1_OFFSET
    ldr    r1, [r0, r2]
    orr     r1, r1, #0xf
    str     r1, [r0, r2]
#endif
    bl    emmc_uboot_copy
    b    after_copy
emmc_boot_4_4:
    /* read TCBCNT to get Transferred CIU card byte count */
    ldr r0, =0x1255005c
    ldr r1, [r0]
    ldr r2, =0x6000
    cmp r1, r2
    /* store second boot information in DRAM */
    ldr r0, =CONFIG_PHY_UBOOT_BASE
    sub r0, r0, #8
    mov r3, #0
    movlo r3, #1
    str r3, [r0]
    /* if transferred CIU card byte count >= 0x6000 (24 KB)  */
    /* BL1 and BL2 are loaded from emmc 4.4                  */
    /* Otherwise BL1 and BL2 are loaded from sdmmc ch2.      */
    blo mmcsd_boot
    /* mmc ch4 devider value change */
    bl    mmc_ch4_devider_change
    /* u-boot image copy from boot partition to DRAM. */
    bl    emmc_4_4_uboot_copy
    /* Exit Boot mood */
    bl    emmc_4_4_endbootOp_eMMC
    b    after_copy

在 lowlevel_init 中,主要做了一些初始化工作,比如系统时钟、内存、串口等的初始化工作,然后初始化堆栈、清bss段,并进行了代码搬移,为第二阶段C语言程序运行提供保障。最后通过

ldr r0, _board_init_f
    mov pc, r0

指令跳转到第二阶段C语言函数 board_init_f 函数处。接着我们就去分析一下这个函数。

在分析board_init_f函数之前,先来了解以下gd_t数据结构

// arch/arm/include/asm/global_data.h
typedef    struct    global_data {
    bd_t        *bd;
    unsigned long    flags;
    unsigned long    baudrate;
    unsigned long    have_console;    /* serial_init() was called */
    unsigned long    env_addr;    /* Address  of Environment struct */
    unsigned long    env_valid;    /* Checksum of Environment valid? */
    unsigned long    fb_base;    /* base address of frame buffer */
#ifdef CONFIG_VFD
    unsigned char    vfd_type;    /* display type */
#endif
#ifdef CONFIG_FSL_ESDHC
    unsigned long    sdhc_clk;
#endif
#ifdef CONFIG_AT91FAMILY
    /* "static data" needed by at91‘s clock.c */
    unsigned long    cpu_clk_rate_hz;
    unsigned long    main_clk_rate_hz;
    unsigned long    mck_rate_hz;
    unsigned long    plla_rate_hz;
    unsigned long    pllb_rate_hz;
    unsigned long    at91_pllb_usb_init;
#endif
#ifdef CONFIG_ARM
    /* "static data" needed by most of timer.c on ARM platforms */
    unsigned long    timer_rate_hz;
    unsigned long    tbl;
    unsigned long    tbu;
    unsigned long long    timer_reset_value;
    unsigned long    lastinc;
#endif
    unsigned long    relocaddr;    /* Start address of U-Boot in RAM */
    phys_size_t    ram_size;    /* RAM size */
    unsigned long    mon_len;    /* monitor len */
    unsigned long    irq_sp;        /* irq stack pointer */
    unsigned long    start_addr_sp;    /* start_addr_stackpointer */
    unsigned long    reloc_off;
#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
    unsigned long    tlb_addr;
#endif
    void        **jt;        /* jump table */
    char        env_buf[32];    /* buffer for getenv() before reloc. */
} gd_t;
#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")

u-boot中使用一个结构体gd_t来存储全局区的数据,使用一个存储在寄存器中的指针gd来记录全局数据区的地址。

DECLARE_GLOBAL_DATA_PTR

在board/samsung/tiny4412/tiny4412.c被声明。

u-boot 中还有一个数据结构 bd_t用来存放板级相关的全局数据,是gd_t中结构体指针成员bd的结构体类型。

//   arch/arm/include/asm/u-boot.h
typedef struct bd_info {
    int            bi_baudrate;    /* serial console baudrate */
    unsigned long    bi_ip_addr;    /* IP Address */
    ulong            bi_arch_number;    /* unique id for this board */
    ulong            bi_boot_params;    /* where this board expects params */
    struct                /* RAM configuration */
    {
    ulong start;
    ulong size;
    }            bi_dram[CONFIG_NR_DRAM_BANKS];
} bd_t;

u-boot启动内核时要给内核传递参数,这时需要使用gd_t、bd_t结构体中的信息来设置标记列表。了解了这两个数据结构我们就去分析一下board_init_f函数

//   arch/arm/lib/board.c
void board_init_f(ulong bootflag)
{
    bd_t *bd;
    init_fnc_t **init_fnc_ptr;
    gd_t *id;
    ulong addr, addr_sp;
    //计算全局数据结构的地址,保存在gd指针中
    /* Pointer is writable since we allocated a register for it */
    gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
    /* compiler optimization barrier needed for GCC >= 3.4 */
    __asm__ __volatile__("": : :"memory");

    memset((void*)gd, 0, sizeof (gd_t));
    gd->mon_len = _bss_end_ofs;
    逐个调用init_sequence数组的初始化函数
    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        if ((*init_fnc_ptr)() != 0) {
            hang();
        }
    }
    debug ("monitor len: %08lX\n", gd->mon_len);
    /*
     * Ram is setup, size stored in gd !!
     */
    debug ("ramsize: %08lX\n", gd->ram_size);
    //填充gd数据结构
    gd->bd->bi_baudrate = gd->baudrate;
    /* Ram ist board specific, so move it to board code ... */
    dram_init_banksize();
    display_dram_config();    /* and display it */
    gd->relocaddr = addr;
    gd->start_addr_sp = addr_sp;
    gd->reloc_off = addr - _TEXT_BASE;
    debug ("relocation Offset is: %08lx\n", gd->reloc_off);
    memcpy(id, (void *)gd, sizeof (gd_t));
    //调用arch/arm/cpu/armv7/start.S  relocate_code
    relocate_code(addr_sp, id, addr);
    /* NOTREACHED - relocate_code() does not return */
}

u-boot使用一个init_sequence数组来存储大多数开发板都要执行的初始化函数的函数指针

// arch/arm/lib/board.c
typedef int (init_fnc_t)(void);
init_fnc_t *init_sequence[] = {
#if defined(CONFIG_ARCH_CPU_INIT)
    arch_cpu_init,        /* basic arch cpu dependent setup */
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
    board_early_init_f,
#endif
    timer_init,        /* initialize timer */
#ifdef CONFIG_FSL_ESDHC
    get_clocks,
#endif
    env_init,        /* initialize environment */
#if defined(CONFIG_S5P6450) && !defined(CONFIG_S5P6460_IP_TEST)
    init_baudrate,        /* initialze baudrate settings */
    serial_init,        /* serial communications setup */
#endif
    console_init_f,        /* stage 1 init of console */
    display_banner,        /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
    print_cpuinfo,        /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
    checkboard,        /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
    init_func_i2c,
#endif
    dram_init,        /* configure available RAM banks */
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
    arm_pci_init,
#endif
    NULL,
};

board_init_f函数在调用完初始化函数指针、填充完gd结构之后,调用了arch/arm/cpu/armv7/start.S中的relocate_code去看一下relocate_code做了什么

    .globl    relocate_code
relocate_code:
    mov    r4, r0    /* save addr_sp */
    mov    r5, r1    /* save addr of gd */
    mov    r6, r2    /* save addr of destination */
    /* Set up the stack                            */
stack_setup:
    mov    sp, r4
    adr    r0, _start
#if defined(CONFIG_S5PC110) && defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
    sub    r0, r0, #16
#endif
#ifndef CONFIG_PRELOADER
    cmp    r0, r6
    beq    clear_bss        /* skip relocation */
#endif
    mov    r1, r6            /* r1 <- scratch for copy_loop */
    ldr    r2, _TEXT_BASE
    ldr    r3, _bss_start_ofs
    add    r2, r0, r3        /* r2 <- source end address        */
copy_loop:
    ldmia    r0!, {r9-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r9-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end address [r2]    */
    blo    copy_loop
#ifndef CONFIG_PRELOADER
    /*
     * fix .rel.dyn relocations
     */
    ldr    r0, _TEXT_BASE        /* r0 <- Text base */
    sub    r9, r6, r0        /* r9 <- relocation offset */
    ldr    r10, _dynsym_start_ofs    /* r10 <- sym table ofs */
    add    r10, r10, r0        /* r10 <- sym table in FLASH */
    ldr    r2, _rel_dyn_start_ofs    /* r2 <- rel dyn start ofs */
    add    r2, r2, r0        /* r2 <- rel dyn start in FLASH */
    ldr    r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */
    add    r3, r3, r0        /* r3 <- rel dyn end in FLASH */
fixloop:
    ldr    r0, [r2]        /* r0 <- location to fix up, IN FLASH! */
    add    r0, r0, r9        /* r0 <- location to fix up in RAM */
    ldr    r1, [r2, #4]
    and    r7, r1, #0xff
    cmp    r7, #23            /* relative fixup? */
    beq    fixrel
    cmp    r7, #2            /* absolute fixup? */
    beq    fixabs
    /* ignore unknown type of fixup */
    b    fixnext
fixabs:
    /* absolute fix: set location to (offset) symbol value */
    mov    r1, r1, LSR #4        /* r1 <- symbol index in .dynsym */
    add    r1, r10, r1        /* r1 <- address of symbol in table */
    ldr    r1, [r1, #4]        /* r1 <- symbol value */
    add    r1, r1, r9        /* r1 <- relocated sym addr */
    b    fixnext
fixrel:
    /* relative fix: increase location by offset */
    ldr    r1, [r0]
    add    r1, r1, r9
fixnext:
    str    r1, [r0]
    add    r2, r2, #8        /* each rel.dyn entry is 8 bytes */
    cmp    r2, r3
    blo    fixloop
clear_bss:
    ldr    r0, _bss_start_ofs
    ldr    r1, _bss_end_ofs
    ldr    r3, _TEXT_BASE        /* Text base */
    mov    r4, r6            /* reloc addr */
    add    r0, r0, r4
    add    r1, r1, r4
    mov    r2, #0x00000000        /* clear                */
clbss_l:str    r2, [r0]        /* clear loop...            */
    add    r0, r0, #4
    cmp    r0, r1
    bne    clbss_l
#endif    /* #ifndef CONFIG_PRELOADER */
/*
 * We are done. Do not return, instead branch to second part of board
 * initialization, now running from RAM.
 */

//调用board_init_r
jump_2_ram:
    ldr    r0, _board_init_r_ofs
    adr    r1, _start
    add    lr, r0, r1
@    add    lr, lr, r9
    /* setup parameters for board_init_r */
    mov    r0, r5        /* gd_t */
    mov    r1, r6        /* dest_addr */
    /* jump to it ... */
    mov    pc, lr
_board_init_r_ofs:
    .word board_init_r - _start

可见,最后调用了board_init_r函数

//   arch/arm/lib/board.c
void board_init_r(gd_t *id, ulong dest_addr)
{
    char *s;
    bd_t *bd;
    ulong malloc_start;
    gd = id;
    bd = gd->bd;
    gd->flags |= GD_FLG_RELOC;    /* tell others: relocation done */
    monitor_flash_len = _bss_start_ofs;
    debug ("monitor flash len: %08lX\n", monitor_flash_len);
    board_init();    /* Setup chipselects */
    debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
    /* The Malloc area is immediately below the monitor copy in DRAM */
    malloc_start = dest_addr - TOTAL_MALLOC_LEN;
    mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
    //初始化MMC
#ifdef CONFIG_GENERIC_MMC
    mmc_initialize(bd);
#endif
     //初始化环境变量
    /* initialize environment */
    env_relocate();
     //将环境变量中的IP填充到gd结构体
    /* IP Address */
    gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");
    stdio_init();    /* get the devices list going. */
    jumptable_init();
      //初始化并使能中断
     /* set up exceptions */
    interrupt_init();
    /* enable exceptions */
    enable_interrupts();
    /* Initialize from environment */
    if ((s = getenv("loadaddr")) != NULL) {
        load_addr = simple_strtoul(s, NULL, 16);
    }
     //进入到main_loop
    /* main_loop() can return to retry autoboot, if so just run it again. */
    for (;;) {
        main_loop();
    }
    /* NOTREACHED - no way out of command loop except booting */
}

最后调用了main_loop

带完成:

①main_loop分析

②启动内核过程

。。。。。。

时间: 2024-10-16 22:57:11

Tiny4412 u-boot分析(2)u-boot启动流程的相关文章

DroidPlugin源码分析处理Activity的启动211ew4dfr

正常情况下启动一个Activity,首先需要在AndroidManifest文件中声明,其次需要把该应用安装到手机系统中. 而插件apk是没有正在安装到手机系统中的,也就按照正常的启动流程插件Activity是不能启动的.另外插件apk的类需要加载进来是需要指定ClassLoader.前面的文章也大概讲过,当启动一个插件Activity时,先是用预定义的代理Activity替换目标Activity(及插件Activity)去启动,当AMS处理完回调到应用空间时(及回到运行Activity的进程空

DroidPlugin源码分析处理Activity的启动

正常情况下启动一个Activity,首先需要在AndroidManifest文件中声明,其次需要把该应用安装到手机系统中. 而插件apk是没有正在安装到手机系统中的,也就按照正常的启动流程插件Activity是不能启动的.另外插件apk的类需要加载进来是需要指定ClassLoader.前面的文章也大概讲过,当启动一个插件Activity时,先是用预定义的代理Activity替换目标Activity(及插件Activity)去启动,当AMS处理完回调到应用空间时(及回到运行Activity的进程空

android源码解析之(十)--&gt;Launcher启动流程

Launcher程序就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序,这里我们就简单的分析一下Launcher应用的启动流程. 不同的手机厂商定制android操作系统的时候都会更改Launcher的源代码,我们这里以android23的源码为例大致的分析一下Launcher的启动流程. 通过上一篇文章,我们知道SystemServer进程主要用于启动系统的各种服务,二者其中就包含了负责启动Launcher的服务,Launcher

centos 启动流程及grub、initramfs修复

启动流程.grub配置及修复.initramfs修复 目录: centos启动流程 grup配置及修复 2.1 grub配置 2.2 grub命令启动 2.3 grub修复 initramfs修复 boot破坏修复 1.centos启动流程 在centos5和6中启动流程如下: (1).POST加电自检 硬件加电自检程序(安装在CMOS中的BIOS程序)BIOS负责检测硬件设备是否正常运行,如cpu.内存.硬盘.外接设备等是否正常,在生产中服务器内存较大,由多条内存组成较大内存的服务器,因此对内

Zygote进程的启动流程

Zygote进程时由Android系统的第一个进程init启动起来的.init进程时在内核加载完成之后就启动起来的,它在启动的过程中,会读取根目录下的一个脚本文件init.rc,以便可以将其他需要开机启动的进程也一起启动起来. Zygote进程在脚本文件init.rc中的启动脚本如下: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote s

android源码解析之(十一)--&gt;应用进程启动流程

在android guide中有这样的一段关于android应用程序进程的描述: By default, every application runs in its own Linux process. Android starts the process when any of the application's components need to be executed, then shuts down the process when it's no longer needed or w

《炉石传说》架构设计赏析(1):游戏启动流程

前些天看新闻,Unity Awards两项大奖颁给了暴雪的<炉石传说>,这真是对Unity一个再好不过的宣传了--你看,暴雪都开始用Unity了.大家都知道,目前Unity发布的游戏大多都没有对程序集进行混淆.加密,所以作为一个炉石的玩家&Unity的初学者,自然不能错过这个机会.让我们好好看一下暴雪的代码吧. 炉石传说的游戏内容的非常丰富多彩,所以我花了一些时间分析了其程序集,将一些设计思路记录下来,与大家分析.欢迎各路高手拍砖,欢迎转载,请注明出处:燕良@游戏开发,http://b

Tomcat启动流程

1. 首先去Tomcat的目录下载它的源码包 2. 把此项目解压之后,转换成maven的项目.创建pom.xml文件,以及创建home的目录,再把原先存在的conf目录和webapps目录拷贝至home目录下 3. pom.xml加入必要的Tomcat的依赖 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.

SpringBoot的启动流程是怎样的?SpringBoot源码(七)

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 温故而知新 本篇接 SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(六) 温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBootSpringBoot内置的各种Starter是怎样构建的?,现将关键点重新回顾总结下: spring-boot-starter-xxx起步依赖没有一行代码,而是直接或间接依赖了xxx-autoconfigure模块,而xxx-auto

nova boot代码流程分析(五):VM启动从neutron-dhcp-agent获取IP与MAC

1.   network和subnet创建代码流程 [[email protected] ~(keystone_user1)]# neutron net-create demo-net [[email protected] ~(keystone_user1)]# neutron subnet-create  demo-net 1.1.1.0/24 --name demo-subnet --gateway 1.1.1.1 --enable_dhcp true 这里,我们主要分析上面两个命令的代码流