uboot1.1.6中启动流程
U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:
(1)第一阶段的功能
Ø 硬件设备初始化
Ø 加载U-Boot第二阶段代码到RAM空间
Ø 设置好栈
Ø 跳转到第二阶段代码入口
(2)第二阶段的功能
Ø 初始化本阶段使用的硬件设备
Ø 检测系统内存映射
Ø 将内核从Flash读取到RAM中
Ø 为内核设置启动参数
Ø 调用内核
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.=0x00000000;
.= ALIGN(4);
.text :
{
cpu/s3c64xx/start.o (.text)
cpu/s3c64xx/s3c6410/cpu_init.o (.text)
cpu/s3c64xx/onenand_cp.o (.text)
cpu/s3c64xx/nand_cp.o (.text)
cpu/s3c64xx/movi.o (.text)
*(.text)
lib_arm/div0.o
}
.= ALIGN(4);
.rodata :{*(.rodata)}
.= ALIGN(4);
.data :{*(.data)}
.= ALIGN(4);
.got :{*(.got)}
__u_boot_cmd_start =.;
.u_boot_cmd :{*(.u_boot_cmd)}
__u_boot_cmd_end =.;
.= ALIGN(4);
.mmudata :{*(.mmudata)}
.= ALIGN(4);
__bss_start =.;
.bss :{*(.bss)}
_end =.;
}
cpu/s3c64xx/start.o (.text)
cpu/s3c64xx/s3c6410/cpu_init.o (.text)
cpu/s3c64xx/onenand_cp.o (.text)
cpu/s3c64xx/nand_cp.o (.text)
cpu/s3c64xx/movi.o (.text)
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f /* 1f=1 1111 = ~ = 0 0000 */
orr r0,r0,#0xd3 /* d3=1101 0011 => 1 0011*/
msr cpsr,r0
31 | 30 | 29 | 28 | 27 | ~ | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
N | Z | C | V | 保留 | I | F | T | M4 | M3 | M2 | M1 | M0 | |||||
N | Negative/Less Than | I | IRQ disable | ||||||||||||||
Z | Zero | F | FIQ disable | ||||||||||||||
C | Carry/Borrow/Extend | T | State bit | ||||||||||||||
V | Overflow | M0~4 | Mode bits |
1、条件码标志
N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。条件码标志各位的具体含义如下表所示:
标志位 | 含 义 |
N | 当用两个补码表示的带符号数进行运算时,N=1表示运算的结果为负数;N=0表示运算的结果为正数或零 |
Z | Z=1表示运算的结果为零,Z=0表示运算的结果非零。 |
C | 可以有4种方法设置C的值: |
-加法运算(包括CMP):当运算结果产生了进位时(无符号数溢出),C=1,否则C=0。 | |
-减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C=0,否则C=1。 | |
-对于包含移位操作的非加/减运算指令,C为移出值的最后一位。 | |
-对于其它的非加/减运算指令,C的值通常不会改变。 | |
V | 可以有2种方法设置V的值: |
-对于加减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出 | |
-对于其它的非加/减运算指令,V的值通常不会改变。 | |
Q | 在ARM V5及以上版本的E系列处理器中,用Q标志位指示增强的DSP运算指令是否发生了溢出。在其它版本的处理器中,Q标志位无定义 |
在ARM状态下,绝大多数的指令都是有条件执行的;在THUMB状态下,仅有分支指令是条件执行的。
2 控制位
CPSR的低8位(包括I、F、T和M[4:0])称为控制位,当发生异常时这些位可以被改变。如果处理器运行于特权模式时,这些位也可以由程序修改。
·中断禁止位I、F:置1时,禁止IRQ中断和FIQ中断。
·T标志位:该位反映处理器的运行状态。当该位为1时,程序运行于THUMB状态,否则运行于ARM状态。该信号反映在外部引脚TBIT上。在程序中不得修改CPSR中的TBIT位,否则处理器工作状态不能确定。
·运行模式位M[4:0]:这几位是模式位,这些位决定了处理器的运行模式。具体含义如下表所示:
·保留位:CPSR中的其余位为保留位,当改变CPSR中的条件码标志位或者控制位时,保留位不要改变,在程序中也不要用保留位存储数据。保留位将用于ARM版本的扩展。
M[4:0] | 处理器模式 | ARM模式可访问的寄存器 | THUMB模式可访问的寄存器 |
0b10000 | 用户模式 usr | PC,CPSR,R0~R14 | PC,CPSR,R0~R7,LR,SP |
0b10001 | FIQ模式 fiq | PC,CPSR,SPSR_fiq,R14_fiq~R8_fiq,R0~R7 | PC,CPSR,SPSR_fiq,LR_fiq,SP_fiq,R0~R7 |
0b10010 | IRQ模式 irq | PC,CPSR,SPSR_irq,R14_irq~R13_irq,R0~R12 | PC,CPSR,SPSR_irq,LR_irq,SP_irq,R0~R7 |
0b10011 | 管理模式 svc | PC,CPSR,SPSR_svc,R14_svc~R13_svc,R0~R12 | PC,CPSR,SPSR_svc,LR_svc,SP_svc,R0~R7 |
0b10111 | 中止模式 abt | PC,CPSR,SPSR_abt,R14_abt~R13_abt,R0~R12 | PC,CPSR,SPSR_abt,LR_abt,SP_abt,R0~R7 |
0b11011 | 未定义模式 und | PC,CPSR,SPSR_und,R14_und~R13_und,R0~R12 | PC,CPSR,SPSR_und,LR_und,SP_und,R0~R7 |
0b11111 | 系统模式 sys | PC,CPSR,R0~R14 | PC,CPSR,LR,SP,R0~R74 |
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0,#0
mcr p15,0, r0, c7, c7,0/* flush v3/v4 cache */
mcr p15,0, r0, c8, c7,0/* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15,0, r0, c1, c0,0
bic r0, r0,#0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0,#0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0,#0x00000002 @ set bit 2 (A) Align
orr r0, r0,#0x00001000 @ set bit 12 (I) I-Cache
mcr p15,0, r0, c1, c0,0
/* Peri port setup */
ldr r0,=0x70000000
orr r0, r0,#0x13
mcr p15,0,r0,c15,c2,4@256M(0x70000000-0x7fffffff)
#include<config.h>
#include<version.h>
#include<s3c6410.h>
#include"smdk6410_val.h"
_TEXT_BASE:
.word TEXT_BASE
.globl lowlevel_init
lowlevel_init:
- ...
- /* LED on only #8 */
- ...
- /* Disable Watchdog */
- ...
/* init system clock */
- bl system_clock_init
- ...
/*
* system_clock_init: Initialize core clock and bus clock.
* void system_clock_init(void)
*/
system_clock_init:
ldr r0,=ELFIN_CLOCK_POWER_BASE @0x7e00f000
ldr r1,[r0,#OTHERS_OFFSET]
mov r2,#0x40
orr r1, r1, r2
str r1,[r0,#OTHERS_OFFSET]
nop
nop
nop
nop
nop
ldr r2,=0x80
orr r1, r1, r2
str r1,[r0,#OTHERS_OFFSET]
check_syncack:
ldr r1,[r0,#OTHERS_OFFSET]
ldr r2,=0xf00
and r1, r1, r2
cmp r1,#0xf00
bne check_syncack
mov r1,#0xff00
orr r1, r1,#0xff
str r1,[r0,#APLL_LOCK_OFFSET]
str r1,[r0,#MPLL_LOCK_OFFSET]
str r1,[r0,#EPLL_LOCK_OFFSET]
/* CLKUART(=66.5Mhz) = CLKUART_input(532/2=266Mhz) / (UART_RATIO(3)+1) */
/* CLKUART(=50Mhz) = CLKUART_input(400/2=200Mhz) / (UART_RATIO(3)+1) */
/* Now, When you use UART CLK SRC by EXT_UCLK1, We support 532MHz & 400MHz value */
#if defined(CONFIG_CLKSRC_CLKUART)
ldr r1,[r0,#CLK_DIV2_OFFSET]
bic r1, r1,#0x70000
orr r1, r1,#0x30000
str r1,[r0,#CLK_DIV2_OFFSET]
#endif
- ldr r1,[r0,#CLK_DIV0_OFFSET] /*Set Clock Divider*/
bic r1, r1,#0x30000
bic r1, r1,#0xff00
bic r1, r1,#0xff
ldr r2,=CLK_DIV_VAL
orr r1, r1, r2
str r1,[r0,#CLK_DIV0_OFFSET]
ldr r1,=APLL_VAL
str r1,[r0,#APLL_CON_OFFSET]
ldr r1,=MPLL_VAL
str r1,[r0,#MPLL_CON_OFFSET]
ldr r1,=0x80200203/* FOUT of EPLL is 96MHz */
str r1,[r0,#EPLL_CON0_OFFSET]
ldr r1,=0x0
str r1,[r0,#EPLL_CON1_OFFSET]
ldr r1,[r0,#CLK_SRC_OFFSET] /* APLL, MPLL, EPLL select to Fout */
ldr r2,=0x2007
orr r1, r1, r2
str r1,[r0,#CLK_SRC_OFFSET]
/* wait at least 200us to stablize all clock */
mov r1,#0x10000
1: subs r1, r1,#1
bne 1b
ldr r1,[r0,#OTHERS_OFFSET]
orr r1, r1,#0x20
str r1,[r0,#OTHERS_OFFSET]
mov pc, lr /* 子函数执行完毕返回 */
/* for UART */
bl uart_asm_init
/*
* uart_asm_init: Initialize UART in asm mode, 115200bps fixed.
* void uart_asm_init(void)
*/
uart_asm_init:
/* set GPIO to enable UART */
@ GPIO setting for UART
ldr r0,=ELFIN_GPIO_BASE
ldr r1,=0x220022
str r1,[r0,#GPACON_OFFSET]
ldr r1,=0x2222
str r1,[r0,#GPBCON_OFFSET]
ldr r0,=ELFIN_UART_CONSOLE_BASE @0x7F005000
mov r1,#0x0
str r1,[r0,#UFCON_OFFSET]
str r1,[r0,#UMCON_OFFSET]
mov r1,#0x3 @was 0.
str r1,[r0,#ULCON_OFFSET]
#if defined(CONFIG_CLKSRC_CLKUART)
ldr r1,=0xe45/* UARTCLK SRC = 11 => EXT_UCLK1*/
#else
ldr r1,=0x245/* UARTCLK SRC = x0 => PCLK */
#endif
str r1,[r0,#UCON_OFFSET]
#if defined(CONFIG_UART_50)
ldr r1,=0x1A
#elif defined(CONFIG_UART_66)
ldr r1,=0x22
#else
ldr r1,=0x1A
#endif
str r1,[r0,#UBRDIV_OFFSET]
#if defined(CONFIG_UART_50)
ldr r1,=0x3
#elif defined(CONFIG_UART_66)
ldr r1,=0x1FFF
#else
ldr r1,=0x3
#endif
str r1,[r0,#UDIVSLOT_OFFSET]
ldr r1,=0x4f4f4f4f
str r1,[r0,#UTXH_OFFSET] @'O'
mov pc, lr
ldr r0,=ELFIN_UART_BASE
ldr r1,=0x4b4b4b4b
str r1,[r0,#UTXH_OFFSET]
#if defined(CONFIG_NAND)
/* simple init for NAND */
bl nand_asm_init
#endif
bl mem_ctrl_asm_init
#if 1
ldr r0,=(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
ldr r1,[r0]
bic r1, r1,#0xfffffff7
cmp r1,#0x8
beq wakeup_reset
#endif
/*
* Nand Interface Init for SMDK6400 */
nand_asm_init:
ldr r0,=ELFIN_NAND_BASE
ldr r1,[r0,#NFCONF_OFFSET]
orr r1, r1,#0x70
orr r1, r1,#0x7700
str r1,[r0,#NFCONF_OFFSET]
ldr r1,[r0,#NFCONT_OFFSET]
orr r1, r1,#0x03
str r1,[r0,#NFCONT_OFFSET]
mov pc, lr
#include<config.h>
#include<s3c6410.h>
.globl mem_ctrl_asm_init
mem_ctrl_asm_init:
ldr r0,=ELFIN_MEM_SYS_CFG @Memory sussystem address 0x7e00f120
mov r1,#0xd @ Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1
str r1,[r0]
...
mov pc, lr
wakeup_reset:
/*Clear wakeup status register*/
ldr r0,=(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
ldr r1,[r0]
str r1,[r0]
/*LED test*/
ldr r0,=ELFIN_GPIO_BASE
ldr r1,=0x3000
str r1,[r0,#GPNDAT_OFFSET]
/*Load return address and jump to kernel*/
ldr r0,=(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
ldr r1,[r0]/* r1 = physical address of s3c6400_cpu_resume function*/
mov pc, r1 /*Jump to kernel (sleep-s3c6400.S)*/
/* 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 flash copy */
after_copy:
#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldr r5,=0x0000ffff
mcr p15,0, r5, c3, c0,0@ load domain access register
/* Set the TTB register */
ldr r0,
ldr r1,=CFG_PHY_UBOOT_BASE
ldr r2,=0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15,0, r1, c2, c0,0
/* Enable the MMU */
mmu_on:
mrc p15,0, r0, c1, c0,0
orr r0, r0,#1 /* Set CR_M to enable MMU */
mcr p15,0, r0, c1, c0,0
nop
nop
nop
nop
#endif
skip_hw_init:
/* Set up the stack */
stack_setup:
#ifdef CONFIG_MEMORY_UPPER_CODE
ldr sp,=(CFG_UBOOT_BASE + CFG_UBOOT_SIZE -0xc)
#else
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0,#CFG_MALLOC_LEN /* malloc area */
sub r0, r0,#CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0,#12 /* leave 3 words for abort-stack */
#endif
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2,#0x00000000 /* clear */
clbss_l:
str r2,[r0]/* clear loop... */
add r0, r0,#4
cmp r0, r1
ble clbss_l
ldr pc, _start_armboot
- _start_armboot:
.word start_armboot
通过bootm引导linux内核启动
uboot1.1.6中启动流程的更多相关文章
- 从0移植uboot (二) _uboot启动流程分析
经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够,首先,此时的uboot并不符合三星芯片对bootloader的格式要求,同时,此时的uboot.bin也没有结合 ...
- u-boot 编译,启动流程分析,移植
分析u-boot-1.1.6 的启动流程 移植u-boot 2012.04版本到JZ2440开发板 源码百度云链接:https://pan.baidu.com/s/10VnxfDWBqJVGY3SCY ...
- (转)从0移植uboot (二) _uboot启动流程分析
ref:https://www.cnblogs.com/xiaojiang1025/p/6496704.html 经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够 ...
- broadcom代码中httpd进程启动流程介绍
Broadcom代码中包含WEB配置管理媒介, 在嵌入式WEB服务器min_httpd基础上改造实现, 其bin名称为httpd,此httpd可以由管理进程有连接后动态启动,并且当一段时间内没有连接到 ...
- Android 儿子Activity在启动过程中的流程组件 && 儿子Activity在一个新的进程组件启动过程
1.儿子Activity在启动过程中的流程组件 在Android Activity启动过程http://blog.csdn.net/jltxgcy/article/details/35984557一文 ...
- uboot-tiny4412启动流程(下)----如何将自己的裸板测试程序加入uboot中启动测试
今天在工作上搞了一天高通的芯片uboot程序,目的是希望将一个裸板的程序移植到uboot中,并且开机让它运行.这个芯片是NXP4330,目前是高通的一个芯片,基于ARM-contexA9架构,那么就跟 ...
- Centos7启动流程及systemd中Nginx启动配置
Centos7启动流程: 1.post(Power-On-Self-Test) 加电自检 主要实现的功能是检测各个外围硬件设备是否存在而且能够正常运行起来,实现这一自检功能的是固化在主板上的ROM(主 ...
- Spring Boot(三):Spring Boot中的事件的使用 与Spring Boot启动流程(Event 事件 和 Listeners监听器)
前言:在讲述内容之前 希望大家对设计模式有所了解 即使你学会了本片的内容 也不知道什么时候去使用 或者为什么要这样去用 观察者模式: 观察者模式是一种对象行为模式.它定义对象间的一种一对多的依赖关系, ...
- U-BOOT启动流程分析--start.s(二)
一.概述 u-boot的启动流程: 从文件层面上看主要流程是在两个文件中:cpu/arm920t/start.s,lib_arm/board.c, 先来分析start.s 在flash中执行的引 ...
随机推荐
- Debian 修改时间时区
http://blog.51cto.com/zhujiangtao/1554976 第一种图形化方面推荐使用 第二种修改文件的形式 只是在当前的terminal生效 笔者使用的是: debian9.3
- Python Jquery学习
jquery调用方法: $(css的选择器).操作函数 语法格式: 操作函数: html 修改内容 点击button键后,jquery就会变为bootstrap 当然里面也可以进行判断,实现 ...
- search Paths $(SRCROOT)和$(PROJECT_DIR)区别
$(SRCROOT)代表的时项目根目录下 $(PROJECT_DIR)代表的是整个项目 PS:往项目添加文件时,例如.a等,要先showinfinder ,复制到项目中,然后再拖到xcode项目中
- java中传入一个数或字符串或数组进行反转
//将一个数用递归反转--利用余数 public static void inverse(int n) { System.out.print(n % 10); if (n >= 10) inve ...
- Percona XtraBackup 2.4新特性之恢复单个表数据
参考文档:https://www.percona.com/doc/percona-xtrabackup/2.4/xtrabackup_bin/restoring_individual_tables.h ...
- Educational Codeforces Round 13——D. Iterated Linear Function(矩阵快速幂或普通快速幂水题)
D. Iterated Linear Function time limit per test 1 second memory limit per test 256 megabytes input ...
- [luoguP2518][HAOI2010]计数(数位DP)
传送门 重新学习数位DP.. 有一个思路,枚举全排列,然后看看比当前数小的有多少个 当然肯定是不行的啦 但是我们可以用排列组合的知识求出全排列的个数 考虑数位dp 套用数位dp的方法,枚举每一位,然后 ...
- 【强连通分量缩点】poj 1236 Network of Schools
poj.org/problem?id=1236 [题意] 给定一个有向图,求: (1)至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 (2)至少要加多少条边,才能使得从任何一个顶点出发,都 ...
- MyEclipse6.5增加对Tomcat7的支持
MyEclipse6.5增加对Tomcat7的支持 最近在研究Servlet3.0,它是JavaEE6.0规范中的一部分 而Servlet3.0对服务器是有要求的,比如Tomcat7+(而Tomcat ...
- NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]
我只能说,珍爱生命,远离卡常数的题...感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,, 哈罗哈的大披萨 [淡蓝] 时间限制(普通/Java) : 1000 MS/ 3000 MS ...