Android系统启动过程-uBoot+Kernel+Android

更新时间:2023-05-23 10:39:17 阅读: 评论:0

Android系统启动过程-uBoot+Kernel+Android
摘要:本⽂是参考⼤量⽹上资源在结合⾃⼰查看源代码总结出来的,让⾃⼰同时也让⼤家加深对Android系统启动过程有⼀个更加深⼊的了解!再次强调,本⽂的⼤多数功劳应归功于那些原创者们,同时⼀些必要的参考链接我会⼀⼀附上。
注:由于本⼈采⽤Exynos4412开发板学习,所以本⽂⼤部分资料都是基于此处理器的
简介:对于整个Android系统的启动总的来说分为三个阶段:
    BootLoader引导即uBoot.bin
    linux内核启动即zImage
    Android系统启动即ramdisk.img与system.img
    以上四个⽂件都是经过⾃⼰编译后⽣成的且通过烧写测试,接下来开始说这三⼤部分的启动过程。
⽬录:⼀、BootLoader的启动
     1.汇编部分
     2.c部分
  ⼆、Kernel的启动
      1.zImage解压缩
      2.kernel的汇编启动阶段
      3.kernel的c启动阶段
   三、Android的启动
      1.init进程
      2.init启动的各种服务
      3.android启动图⽰
第⼀部分:BootLoader的启动流程
    uBoot的第⼀条指令从cpu/arm920t/start.S⽂件开始
      1. 设置CPU进⼊SVC模式(系统管理模式),cpsr[4:0]=0xd3。
1 #include <common.h>
2 #include <config.h>
3
4/*
5 *************************************************************************
6 *
7 * Jump vector table as in table 3.1 in [1]
8 *
9 *************************************************************************
10*/
11
12
13 .globl _start
14 _start:    b    start_code
15    ldr    pc, _undefined_instruction
16    ldr    pc, _software_interrupt
17    ldr    pc, _prefetch_abort
18    ldr    pc, _data_abort
19    ldr    pc, _not_ud
describe是什么意思
20    ldr    pc, _irq
21    ldr    pc, _fiq
22
23 _undefined_instruction:    .word undefined_instruction
24 _software_interrupt:    .word software_interrupt
25 _prefetch_abort:    .word prefetch_abort
26 _data_abort:        .word data_abort
27 _not_ud:        .word not_ud
28 _irq:            .word irq
29 _fiq:            .word fiq
30
31    .balignl 16,0xdeadbeef
        接着进⼊Start_code中:设置CPU进⼊SVC模式。
1/*
2 * the actual start code
3*/
4
5 start_code:
6/*
7    * t the cpu to SVC32 mode
8*/
9    mrs    r0, cpsr
10    bic    r0, r0, #0x1f
11    orr    r0, r0, #0xd3
12    msr    cpsr, r0
13
14    bl    coloured_LED_init
15    bl    red_LED_on
        2.关看门狗,WTCON=0x0,并设置寄存器地址。
1/* turn off the watchdog */
2
3 # if defined(CONFIG_S3C2400)
4 #  define pWTCON    0x15300000
5 #  define INTMSK    0x14400008/* Interupt-Controller ba address */
6 #  define CLKDIVN    0x14800014/* clock divisor register */
7#el
8 #  define pWTCON    0x53000000
9 #  define INTMSK    0x4A000008/* Interupt-Controller ba address */
10 #  define INTSUBMSK    0x4A00001C
11 #  define CLKDIVN    0x4C000014/* clock divisor register */
12 # endif
13
14    ldr    r0, =pWTCON
15    mov    r1, #0x0
16    str    r1, [r0]
        3.关中断,INTMSK=0xFFFFFFFF, INTSUBMSK=0x3FF。 1/*
2    * mask all IRQs by tting all bits in the INTMR - default
3*/
4    mov    r1, #0xffffffff
5    ldr    r0, =INTMSK
6    str    r1, [r0]
7 # if defined(CONFIG_S3C2410)
8    ldr    r1, =0x3ff
9    ldr    r0, =INTSUBMSK
10    str    r1, [r0]
11 # endif
        4.时钟设置CLKDIVN=0x3 , FCLK:HCLK:PCLK = 1:2:4
日语三级
1/* FCLK:HCLK:PCLK = 1:2:4 */
2/* default FCLK is 120 MHz ! */
3    ldr    r0, =CLKDIVN
4    mov    r1, #3
5    str    r1, [r0]
6#endif    /* CONFIG_S3C24X0 */
        5.询问是否进⾏CPU初始化
1 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
2    bl    cpu_init_crit
3#endif
        6.relocate函数
1 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
2 relocate:                /* relocate U-Boot to RAM        */
3    adr    r0, _start        /* r0 <- current position of code  */
4    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
5    cmp    r0, r1            /* don't reloc during debug        */
6    beq    stack_tup
7
8    ldr    r2, _armboot_start
9    ldr    r3, _bss_start
10    sub    r2, r3, r2        /* r2 <- size of armboot            */
11    add    r2, r0, r2        /* r2 <- source end address        */
12
13 copy_loop:
14    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
15    stmia    r1!, {r3-r10}        /* copy to  target address [r1]    */
16    cmp    r0, r2            /* until source end addreee [r2]    */
17    ble    copy_loop
18#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */
        7.初始化堆栈
1/* Set up the stack                            */
2 stack_tup:
3    ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot  */
4    sub    r0, r0, #CONFIG_SYS_MALLOC_LEN    /* malloc area              */
5    sub    r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                */
6 #ifdef CONFIG_USE_IRQ
7    sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
8#endif
9    sub    sp, r0, #12/* leave 3 words for abort-stack    */
10
11 clear_bss:
12    ldr    r0, _bss_start        /* find start of bss gment        */
13    ldr    r1, _bss_end        /* stop here                        */
14    mov    r2, #0x00000000/* clear                            */
15
16 clbss_l:str    r2, [r0]        /*                     */
17    add    r0, r0, #4
18    cmp    r0, r1
19    ble    clbss_l
        8.CPU的初始化,即cpu_init_crit函数,完成以后回到主函数
1 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
2 cpu_init_crit:
3/*
4    * flush v4 I/D caches
5*/
6    mov    r0, #0
7    mcr    p15, 0, r0, c7, c7, 0/* flush v3/v4 cache */
8    mcr    p15, 0, r0, c8, c7, 0/* flush v4 TLB */
9
10/*
11    * disable MMU stuff and caches
12*/
13    mrc    p15, 0, r0, c1, c0, 0
14    bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
15    bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
16    orr    r0, r0, #0x00000002    @ t bit 2 (A) Align
17    orr    r0, r0, #0x00001000    @ t bit 12 (I) I-Cache
18    mcr    p15, 0, r0, c1, c0, 0
19
preparation20/*
21    * before relocating, we have to tup RAM timing
22    * becau memory timing is board-dependend, you will
23    * find a lowlevel_init.S in your board directory.
会计实操班24*/
25    mov    ip, lr
26
27    bl    lowlevel_init
startover
28
29    mov    lr, ip
30    mov    pc, lr
31#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
        9.从这⾥跳转到第⼆阶段C代码中去
1 ldr    pc, _start_armboot
2
3 _start_armboot:    .word start_armboot
     C部分从⽂件/lib_arm/board.c的start_armboot()函数开始
        1.定义⼀个struct global_data结构体指针gd,struct global_data结构体对象gd_data,
          定义⼀个struct bd_info结构体对象bd_data,定义⼀个指向函数的⼆级指针init_fnc_ptr,定义的全局结构体对象都是放在堆栈中的,gd是放在寄存器中的。
        2. gd=&gd_data,gd->bd = &bd_data,并且全部空间清0。
        3.init_fnc_ptr = init_quence(⼀个初始化函数指针数组)。将会在接下来的for循环中提取出每⼀个函数来依次执⾏完。
tua
        4.配置可⽤的flash空间,并且打印出相关信息,flash_init()和display_flash_config()。
        5.mem_malloc_init()函数,分配堆空间.athena
        6.env_relocate该函数的作⽤是将0x33ef0000开始16K的环境参数拷贝到堆空间中去。
        7.gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr")通过这中⽅式获得环境变量列表中的ipaddr参数(开发板ip),获得环境变量中的MAC地址,设置到gd->bd->bi_enetaddr[reg]中。
        8.devices_init函数,创建了devlist,但是只有⼀个串⼝设备注册在内。
        9.console_init_r函数:控制台完全初始化,此后可以使⽤函数rial_getc和rial_putc或者putc和getc来输出log。
        10.使能中断,如果有⽹卡设备,设置⽹卡MAC和IP地址。
        11.main_loop ();定义于common/main.c。到此所有的初始化⼯作已经完成,main_loop在标准输⼊设备中接受命令,然后分析,查找和执⾏。
        12.在上⾯的main_loop函数中,通常在开发完成的阶段都会设置⼀个bootcmd的环境变量,然后将延时bootdelay设置成0,这样当u-boot跑到这⾥的时候就不会因为⽤户按下了任意键就进⼊了命令⾏模式,
          可以直接运⾏bootcmd的命令来直接加载kernel的Image然后移交控制权。如果进⼊了命令⾏模式,我们也可以⼿动输⼊命令来启动系统,输⼊的命令也是基本和bootcmd⼀样
1#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
2    s = getenv ("bootdelay");
3    bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
4
5    debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
    这个地⽅时设置bootdelay的地⽅,即在引导kernel时等待⽤户命令,进⼊命令⾏模式,进⾏分区,格式化等操作。
        13.uBoot 引导内核启动的最后⼀步是:通过⼀个函数指针 thekernel()带三个参数跳转到内核( zImage )⼊⼝点开始执⾏,此时, u-boot 的任务已经完成,控制权完全交给内核( zImage )。
          在 uBoot 的⽂件lib_arm\bootm.c中定义了 thekernel, 并在 do_bootm_linux 的最后执⾏ thekernel。
            定义thekernel函数指针,获取bootargs参数给commandline指针。
            theKernel (0, machid, bd->bi_boot_params);第⼀个参数必须为0,第⼆个参数为机器类型ID,第三个参数为传递给内核参数的起始地址0x30000100
1int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
2 {
3    bd_t    *bd = gd->bd;
4char    *s;
四六级准考证号
5int    machid = bd->bi_arch_number;
6void    (*theKernel)(int zero, int arch, uint params);
7int    ret;
8
9 #ifdef CONFIG_CMDLINE_TAG
10char *commandline = getenv ("bootargs");
11#endif
12
13if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
14return1;
15
16    theKernel = (void (*)(int, int, uint))images->ep;
17
18    s = getenv ("machid");
19if (s) {
20        machid = simple_strtoul (s, NULL, 16);
21        printf ("Using machid 0x%x from environment\n", machid);
22    }
23
24    ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_ARM,
25            &(images->rd_start), &(images->rd_end));
26if(ret)
27        printf("[err] boot_get_ramdisk\n");
28
29    show_boot_progress (15);
30
31    debug ("## Transferring control to Linux (at address %08lx) ...\n",
32            (ulong) theKernel);
33
34#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
35    defined (CONFIG_CMDLINE_TAG) || \
36    defined (CONFIG_INITRD_TAG) || \
37    defined (CONFIG_SERIAL_TAG) || \
38    defined (CONFIG_REVISION_TAG) || \
39    defined (CONFIG_LCD) || \
40    defined (CONFIG_VFD)
41    tup_start_tag (bd);
大写字母怎么写42 #ifdef CONFIG_SERIAL_TAG
43    tup_rial_tag (¶ms);
44#endif
45 #ifdef CONFIG_REVISION_TAG
46    tup_revision_tag (¶ms);
47#endif
48 #ifdef CONFIG_SETUP_MEMORY_TAGS
49    tup_memory_tags (bd);
50#endif
51 #ifdef CONFIG_CMDLINE_TAG
52    tup_commandline_tag (bd, commandline);
53#endif
54 #ifdef CONFIG_INITRD_TAG
55if (images->rd_start && images->rd_end)
56        tup_initrd_tag (bd, images->rd_start, images->rd_end); 57#endif
58#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
59    tup_videolfb_tag ((gd_t *) gd);
60#endif
61    tup_end_tag (bd);
62#endif
63
64/* we assume that the kernel is in place */
65    printf ("\nStarting kernel ...\n\n");
66
67 #ifdef CONFIG_USB_DEVICE
68    {
69extern void udc_disconnect (void);
70        udc_disconnect ();
71    }
72#endif
73
74    cleanup_before_linux ();
75
76    theKernel (0, machid, bd->bi_boot_params);
77/* does not return */
78
79return1;
80 }
附上BootLoader启动时的调试信息
OK
U-Boot 2010.03 (Jul 142015 - 00:08:57) for iTOP-4412 Android CPU:    SMDK4412-AP1.1 [e4412211]
APLL = 1000MHz, MPLL = 800MHz
ARM_CLOCK = 1000MHz
PMIC:  S5M8767(VER5.0)
Board:  iTOP-4412-Quad
POP type: POP for C220
DRAM:  1023 MB
MMC:  Count: 100
max_emmc_clock:40 MHZ
Set CLK to 400 KHz
EMMC CLOCK OUTPUT:: 400KHz -[div:50]
respon timeout error : 00000104 cmd 8
respon timeout error : 00000104 cmd 55
max_emmc_clock:40 MHZ
Input CLK [ 50 MHz] is higher than limit [40 MHZ]
Set CLK to 40000 KHz
EMMC clock output: 40000 KHz
max_emmc_clock:40 MHZ
Input CLK [ 50 MHz] is higher than limit [40 MHZ]
Set CLK to 40000 KHz
EMMC clock output: 40000 KHz
MMC0:  3728 MB
SD sclk_mmc is 400K HZ
rai: Signal # 8 caught
沈阳培训学校
rai: Signal # 8 caught
MMC1:  0 MB
0 MB
*** Warning - using default environment

本文发布于:2023-05-23 10:39:17,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/119461.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:启动   参数   函数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图