六、uboot 代码流程分析---start.S

6.1 _start 入口函数

6.1.1 vectors.S (arch\arm\lib)

  从上一节可以知道,uboot 的入口函数为 _start 。此 函数定义在 vectors.S (arch\arm\lib) 中。

  在此文件中,定义了异常向量表,及其操作函数。_start 开始后,直接跳入  reset 复位中执行启动。

 1 /* 头文件包含,包含架构和配置相关的头文件,自动生成的 */
 2 #include <config.h>
 3
 4 /*
 5  * A macro to allow insertion of an ARM exception vector either
 6  * for the non-boot0 case or by a boot0-header.
 7  * 这里定义了异常向量表 ARM_VECTORS
 8  */
 9  /* 当异常发生的时候,由硬件机制处理器自动的跳到一个固定地址去执行相关异常处理程序,而这个固定地址就是所谓的异常向量。 */
10         .macro ARM_VECTORS
11     b    reset            /* 跳转到reset执行 0x00000000 复位异常*/
12     /* LDR{条件}   目的寄存器     <存储器地址> */
13     ldr    pc, _undefined_instruction        /* 未定义指令终止模式,当未定义指令执行时进入该模式,可用于支持硬件协处理器的软件仿真 */
14     ldr    pc, _software_interrupt        /* 软中断异常 */
15     ldr    pc, _prefetch_abort        /* 预取异常 */
16     ldr    pc, _data_abort        /* 数据访问终止模式,当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护 */
17     ldr    pc, _not_used        /* 未使用异常,多余的指令 */
18     ldr    pc, _irq        /* 中断模式,用于通用的中断处理 */
19     ldr    pc, _fiq        /* 快速中断模式,用于高速数据传输或通道处理 */
20     .endm
21
22
23 /*
24  *************************************************************************
25  *
26  * Symbol _start is referenced elsewhere, so make it global
27  *
28  *************************************************************************
29  */
30 /* 定义全局函数 _start,为 uboot  代码的起始函数 */
31 .globl _start
32
33 /*
34  *************************************************************************
35  *
36  * Vectors have their own section so linker script can map them easily
37  *
38  *************************************************************************
39  */
40
41     .section ".vectors", "ax"
42
43 /*
44  *************************************************************************
45  *
46  * Exception vectors as described in ARM reference manuals
47  *
48  * Uses indirect branch to allow reaching handlers anywhere in memory.
49  *
50  *************************************************************************
51  */
52 /* uboot 的起始位置 */
53 _start:
54     ARM_VECTORS

6.1.2 start.S (arch\arm\cpu\arm920t)

  在此汇编中,主要执行  reset  函数,主要是做一些重要的硬件初始化、重定向arm启动到 ram,设置栈、跳转到第二阶段去执行启动、

 1 /* 头文件包含 */
 2 #include <asm-offsets.h>
 3 #include <common.h>
 4 #include <config.h>
 5
 6 /*
 7  *************************************************************************
 8  *
 9  * Startup Code (called from the ARM reset exception vector)
10  *
11  * do important init only if we don‘t start from memory!
12  * relocate armboot to ram
13  * setup stack
14  * jump to second stage
15  *
16  *************************************************************************
17  */
18
19     .globl    reset
20
21 reset:
22     /*
23      * set the cpu to SVC32 mode
24      * 将 CPU 设置为管理员(SVC)模式
25      */
26     mrs    r0, cpsr        //将状态寄存器的内容传送至通用寄存器,将CPSR中的内容传送至R0
27     bic    r0, r0, #0x1f    //位清除指令 将R0最低5位清零,其余位不变 工作模式位清零
28     orr    r0, r0, #0xd3    //工作模式位设置为“10011”(管理模式),并将中断禁止位和快中断禁止位置1 "1101 0011" 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中
29     msr    cpsr, r0        //将通用寄存器的内容传送至状态寄存器,将中的内容R0传送至CPSR
30
31     /*
32      * we do sys-critical inits only at reboot,
33      * not when booting from ram!
34      * 未从 ram 启动的时候,所做的CPU 关键初始化工作
35      */
36 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
37     /* CPU 关键初始化 */
38     bl    cpu_init_crit
39 #endif
40
41     bl    _main        /* 跳转到 _main 开始执行,进行初始化C环境 和进行第二阶段 */
42
43 /*------------------------------------------------------------------------------*/
44
45     .globl    c_runtime_cpu_setup
46 c_runtime_cpu_setup:
47
48     mov    pc, lr
49
50 /*
51  *************************************************************************
52  *
53  * CPU_init_critical registers
54  *
55  * setup important registers
56  * setup memory timing
57  * CPU 关键初始化
58  *************************************************************************
59  */
60
61
62 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
63 cpu_init_crit:
64     /*
65      * flush v4 I/D caches
66      * 刷新L1 cache的icache和dcache
67      */
68     mov    r0, #0                    /* 置零r0通用寄存器 */
69     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache 向c7写入0将使ICache与DCache无效 "0"表示省略opcode_2 MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}*/
70     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2*/
71
72     /*
73      * disable MMU stuff and caches
74      * 关闭 MMU 及其 caches
75      */
76     mrc    p15, 0, r0, c1, c0, 0
77     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
78     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
79     orr    r0, r0, #0x00000002    @ set bit 1 (A) Align
80     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
81     mcr    p15, 0, r0, c1, c0, 0
82
83 #ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
84     /*
85      * before relocating, we have to setup RAM timing
86      * because memory timing is board-dependend, you will
87      * find a lowlevel_init.S in your board directory.
88      */
89     mov    ip, lr        /* 保存当前程序地址到 ip  寄存器 */
90
91     bl    lowlevel_init    /* 执行 SDRAM 初始化 */
92     mov    lr, ip
93 #endif
94     mov    pc, lr            /* 返回 */
95 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

6.1.3 内存控制器初始化

  lowlevel_init.S (board\samsung\jz2440)

  主要是为了初始化 SDRAM

  1 #include <config.h>
  2 #include <version.h>
  3
  4
  5 /* some parameters for the board */
  6
  7 /*
  8  *
  9  * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
 10  *
 11  * Copyright (C) 2002 Samsung Electronics SW.LEE  <[email protected]>
 12  * 这里主要是为了初始化 SDRAM
 13  */
 14
 15 #define BWSCON    0x48000000        /* 总线宽度和等待控制寄存器 */
 16
 17 /* BWSCON 总线宽度和等待控制寄存器 */
 18 #define DW8            (0x0)            /* 数据总线宽度为 8位 */
 19 #define DW16            (0x1)        /* 数据总线宽度为 16位 */
 20 #define DW32            (0x2)        /* 数据总线宽度为 32位 */
 21 #define WAIT            (0x1<<2)    /* BANKn WAIT 状态使能 */
 22 #define UBLB            (0x1<<3)    /* BANKn UB/LB 使能 */
 23
 24 /*     这里不设置 BANK0,BANK0(nGCS0)的数据总线应当配置为 16 位或 32 位的宽度。因为 BANK0 是作为引导 ROM 的 bank(映射到 0x0000_0000),
 25     应当在第一个 ROM 访问前决定 BANK0 的总线宽度,其依赖于复位时 OM[1:0]的逻辑电平。 */
 26 /* 原理图中,SDRAM 连接在GCS6上,因此关注 BANK6 */
 27 #define B1_BWSCON        (DW32)                    /* BANK1 设置为 32 位的宽度 */
 28 #define B2_BWSCON        (DW16)                    /* BANK2 设置位 16 位的宽度 */
 29 #define B3_BWSCON        (DW16 + WAIT + UBLB)    /* BANK2 设置位 16 位的宽度,使能 WEIT 和UBLB */
 30 #define B4_BWSCON        (DW16)                    /* BANK2 设置位 16 位的宽度 */
 31 #define B5_BWSCON        (DW16)                    /* BANK2 设置位 16 位的宽度 */
 32 #define B6_BWSCON        (DW32)                    /* BANK6 设置为 32 位的宽度 */
 33 #define B7_BWSCON        (DW32)                    /* BANK7 设置为 32 位的宽度 */
 34
 35 /* BANK 控制寄存器 */
 36 /* BANK0CON */
 37 #define B0_Tacs            0x0    /*  0clk */
 38 #define B0_Tcos            0x0    /*  0clk */
 39 #define B0_Tacc            0x7    /* 14clk */
 40 #define B0_Tcoh            0x0    /*  0clk */
 41 #define B0_Tah            0x0    /*  0clk */
 42 #define B0_Tacp            0x0
 43 #define B0_PMC            0x0    /* normal */
 44
 45 /* BANK1CON */
 46 #define B1_Tacs            0x0    /*  0clk */
 47 #define B1_Tcos            0x0    /*  0clk */
 48 #define B1_Tacc            0x7    /* 14clk */
 49 #define B1_Tcoh            0x0    /*  0clk */
 50 #define B1_Tah            0x0    /*  0clk */
 51 #define B1_Tacp            0x0
 52 #define B1_PMC            0x0
 53
 54 #define B2_Tacs            0x0
 55 #define B2_Tcos            0x0
 56 #define B2_Tacc            0x7
 57 #define B2_Tcoh            0x0
 58 #define B2_Tah            0x0
 59 #define B2_Tacp            0x0
 60 #define B2_PMC            0x0
 61
 62 #define B3_Tacs            0x0    /*  0clk */
 63 #define B3_Tcos            0x3    /*  4clk */
 64 #define B3_Tacc            0x7    /* 14clk */
 65 #define B3_Tcoh            0x1    /*  1clk */
 66 #define B3_Tah            0x0    /*  0clk */
 67 #define B3_Tacp            0x3     /*  6clk */
 68 #define B3_PMC            0x0    /* normal */
 69
 70 #define B4_Tacs            0x0    /*  0clk */
 71 #define B4_Tcos            0x0    /*  0clk */
 72 #define B4_Tacc            0x7    /* 14clk */
 73 #define B4_Tcoh            0x0    /*  0clk */
 74 #define B4_Tah            0x0    /*  0clk */
 75 #define B4_Tacp            0x0
 76 #define B4_PMC            0x0    /* normal */
 77
 78 #define B5_Tacs            0x0    /*  0clk */
 79 #define B5_Tcos            0x0    /*  0clk */
 80 #define B5_Tacc            0x7    /* 14clk */
 81 #define B5_Tcoh            0x0    /*  0clk */
 82 #define B5_Tah            0x0    /*  0clk */
 83 #define B5_Tacp            0x0
 84 #define B5_PMC            0x0    /* normal */
 85
 86 /* BANK6 SDRAM配置 */
 87 #define B6_MT            0x3    /* 配置BANK6的存器类型为 SDRAM */
 88 #define B6_Trcd            0x1    /* RAS 到 CAS 的延迟为 3 个时钟 */
 89 #define B6_SCAN            0x1    /* 列地址数为 9bit */
 90
 91 #define B7_MT            0x3    /* SDRAM */
 92 #define B7_Trcd            0x1    /* 3clk */
 93 #define B7_SCAN            0x1    /* 9bit */
 94
 95 /* REFRESH parameter */
 96 #define REFEN            0x1    /* Refresh enable */
 97 #define TREFMD            0x0    /* CBR(CAS before RAS)/Auto refresh */
 98 #define Trp            0x0    /* 2clk */
 99 #define Trc            0x3    /* 7clk */
100 #define Tchr            0x2    /* 3clk */
101 #define REFCNT            1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
102 /**************************************/
103
104 .globl lowlevel_init
105 lowlevel_init:
106     /* memory control configuration */
107     /* make r0 relative the current location so that it */
108     /* reads SMRDATA out of FLASH rather than memory ! */
109     ldr     r0, =SMRDATA
110     ldr    r1, =CONFIG_SYS_TEXT_BASE
111     sub    r0, r0, r1                    /* 计算内存控制器的偏移值 */
112     ldr    r1, =BWSCON    /* Bus Width Status Controller */
113     add     r2, r0, #13*4            /* 将SMRDATA这一块地址赋值给r2中 */
114 /* 此处遍历赋值表 */
115 0:
116     ldr     r3, [r0], #4
117     str     r3, [r1], #4
118     cmp     r2, r0
119     bne     0b
120
121     /* everything is fine now */
122     mov    pc, lr
123
124     .ltorg
125 /* the literal pools origin */
126
127 /* 存储器控制器寄存器赋值表 */
128 SMRDATA:
129     .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
130     .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
131     .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
132     .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
133     .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
134     .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
135     .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
136     .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
137     .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
138     .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
139     .word 0x32
140     .word 0x30
141     .word 0x30

原文地址:https://www.cnblogs.com/kele-dad/p/8986695.html

时间: 2024-11-09 12:47:45

六、uboot 代码流程分析---start.S的相关文章

u-boot启动流程分析(2)_板级(board)部分

转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global data介绍以及背后的思考 5. 前置的板级初始化操作 6. u-boot的relocation 7. 后置的板级初始化操作 1. 前言 书接上文(u-boot启动流程分析(1)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_i

[国嵌笔记][030][U-Boot工作流程分析]

uboot工作流程分析 程序入口 1.打开顶层目录的Makefile,找到目标smdk2440_config的命令中的第三项(smdk2440) 2.进入目录board/samsung/smdk2440/,找到u-boot.lds文件.uboot的链接都是由这个链接器脚本来控制的 3.打开u-boot.lds文件,找到.text(代码段)的第一个文件cup/s3c24xx/start.o,该文件就是uboot的入口代码.链接器脚本中的ENTRY用来表明整个程序的入口,那么标号_start就是整个

U-boot引导流程分析一

U-Boot,全称 Universal Boot Loader,即通用引导程序,是遵循GPL条款的开放源码项目.它的源码目录.编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点.U-Boot不仅仅支持嵌入式Linux系统的引导,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统. U-Boot的工作模式有启动加载模式和下载模式.

U-boot引导流程分析二

Stage II过程分析 在Stage II中使用到了一些比较重要的数据结构,这里先对这些数据结构来进行下分析: typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; unsigned long have_console; /* serial_init() was called */ unsigned long reloc_off; /* Relocation Offset */ u

Uboot启动流程分析(五)

1.前言 在前面的文章Uboot启动流程分析(五),链接如下: https://www.cnblogs.com/Cqlismy/p/12147411.html 已经对board_init_f() 函数作出了简单的分析,该函数对一些早期的外设进行了初始化,例如调试串口,并填充了gd_t结构体中的成员变量,最主要的是对整个DRAM的内存进行了分配,以便uboot的重定位,接下来,先回顾一下_main函数的大概流程,如下: _main | board_init_f_alloc_reserve-->re

uboot boot流程分析

下面这篇文章分析得比较好: 2014.4新版uboot启动流程分析 http://blog.csdn.net/skyflying2012/article/details/25804209 感谢作者分享

nova boot代码流程分析(三):nova与neutron的交互(2)

继续<nova boot代码流程分析(三):nova与neutron的交互(1)>的分析. #/nova/virt/libvirt/driver.py:LibvirtDriver # NOTE(ilyaalekseyev): Implementation like in multinics # for xenapi(tr3buchet) def spawn(self, context, instance, image_meta, injected_files, admin_password,

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 这里,我们主要分析上面两个命令的代码流

Uboot启动流程分析(四)

1.前言 在前面的文章Uboot启动流程分析(三)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12006287.html 已经对init_sequence_f前半部分函数进行了简单分析,前半部分主要是对调试串口终端进行了初始化,以及输出了一些必要的字符串,接下来,本篇文章将对init_sequence_f后半部分函数进行分析,后半部分主要是对DRAM的内存进行分配,并对gd的相关结构体成员进行初始化,在init_sequence_f函数初始化列表中,已经执