基于友善之臂ARM-tiny4412--uboot源码分析
/* * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core * * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com> * * Copyright (c) 2001 Marius Gr?ger <mag@sysgo.de> * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> * Copyright (c) 2003 Kshitij <kshitij@ti.com> * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <asm-offsets.h> #include <config.h> #include <version.h> #if defined(CONFIG_S5PC110) && defined(CONFIG_EVT1) && !defined(CONFIG_FUSED) @阶段启动相关设置 .word 0x2000 .word 0x0 .word 0x0 .word 0x0 #endif .globl _start _start: b reset @复位入口,此时使用b指令作为相对调整,不依赖运行地址 @以下为进入异常处理函数 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 */ @此处保证16个字节进行对齐 .global _end_vect _end_vect: .balignl 16,0xdeadbeef @同样是保证16个字节进行对齐 /************************************************************************* * * Startup Code (reset vector) 启动代码,复位向量,此处仅仅进行还重要的初始化操作,转移代码还有建立堆栈 * * do important init only if we don't start from memory! * setup Memory and board specific bits prior to relocation. * relocate armboot to ram * setup stack * *************************************************************************/ .globl _TEXT_BASE _TEXT_BASE: .word CONFIG_SYS_TEXT_BASE @此处为根目录下Makefile传进来的参数,具体为0xc3e00000 /* * These are defined in the board-specific linker script. */ .globl _bss_start_ofs _bss_start_ofs: .word __bss_start - _start //__bss_start在链接脚本文件中bss段开始,_end在bss段结尾,用于清除bss段,这两个值要链接时才确定 .globl _bss_end_ofs _bss_end_ofs: .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ 中断栈内存 .globl IRQ_STACK_START IRQ_STACK_START: .word 0x0badc0de /* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_START FIQ_STACK_START: .word 0x0badc0de #endif /* IRQ stack memory (calculated at run-time) + 8 bytes */ .globl IRQ_STACK_START_IN IRQ_STACK_START_IN: .word 0x0badc0de /* * the actual reset code 复位相关的代码 */ reset: /* * set the cpu to SVC32 mode 设置CPU进入SVC模式 */ mrs r0, cpsr 清CPSR的第I位 bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr,r0 #if (CONFIG_OMAP34XX) /* Copy vectors to mask ROM indirect addr */ / *拷贝载体掩模ROM间接地址*/ adr r0, _start @ r0 <- current position of code add r0, r0, #4 @ skip reset vector mov r2, #64 @ r2 <- size to copy r2寄存器进行拷贝 add r2, r0, r2 @ r2 <- source end address mov r1, #SRAM_OFFSET0 @ build vect addr mov r3, #SRAM_OFFSET1 add r1, r1, r3 mov r3, #SRAM_OFFSET2 add r1, r1, r3 next: ldmia r0!, {r3 - r10} @ copy from source address [r0] stmia r1!, {r3 - r10} @ copy to target address [r1] cmp r0, r2 @ until source end address [r2] bne next @ loop until equal */ #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT) /* No need to copy/exec the clock code - DPLL adjust already done * in NAND/oneNAND Boot. */ @这里不需要复制/执行时钟代码数字锁相环调整已经完成在NAND / OneNAND启动。 bl cpy_clk_code @ put dpll adjust code behind vectors #endif /* NAND Boot */ #endif /* the mask ROM code should have PLL and others stable */ / *屏蔽代码应该有锁相环和其他稳定* / #ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_crit #endif /* Set stackpointer in internal RAM to call board_init_f */ call_board_init_f: ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ ldr r0,=0x00000000 bl board_init_f /*------------------------------------------------------------------------------*/ /* * void relocate_code (addr_sp, gd, addr_moni) * * This "function" does not return, instead it continues in RAM * after relocating the monitor 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: @清除_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. */ @初始化部分,从内存中开始运行 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 _rel_dyn_start_ofs: .word __rel_dyn_start - _start _rel_dyn_end_ofs: .word __rel_dyn_end - _start _dynsym_start_ofs: .word __dynsym_start - _start /************************************************************************* * * CPU_init_critical registers CO=PU初始化控制錴 * * setup important registers * setup memory timing * *************************************************************************/ cpu_init_crit: bl cache_init @跳到缓存进行初始化 /* * Invalidate L1 I/D */ mov r0, #0 @ set up for MCR mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs 禁止TLB mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 禁止指令缓存 /* * 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 @进制MMC和Cache /* * 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 bl lowlevel_init @ go setup pll,mux,memory mov lr, ip @ restore link mov pc, lr @ back to my caller /* ************************************************************************* * * Interrupt handling 中断处理句柄 * ************************************************************************* */ @ @ IRQ stack frame. @ #define S_FRAME_SIZE 72 #define S_OLD_R0 68 #define S_PSR 64 #define S_PC 60 #define S_LR 56 #define S_SP 52 #define S_IP 48 #define S_FP 44 #define S_R10 40 #define S_R9 36 #define S_R8 32 #define S_R7 28 #define S_R6 24 #define S_R5 20 #define S_R4 16 #define S_R3 12 #define S_R2 8 #define S_R1 4 #define S_R0 0 #define MODE_SVC 0x13 #define I_BIT 0x80 /*定义异常时保存寄存器的宏 * use bad_save_user_regs for abort/prefetch/undef/swi ... * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling */ .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current @ user stack stmia sp, {r0 - r12} @ Save user registers (now in @ svc mode) r0-r12 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort @ stack ldmia r2, {r2 - r3} @ get values for "aborted" pc @ and cpsr (into parm regs) add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr mov r0, sp @ save current stack into r0 @ (param register) .endm .macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 add r8, sp, #S_PC @ !! R8 NEEDS to be saved !! @ a reserved stack spot would @ be good. stmdb r8, {sp, lr}^ @ Calling SP, LR str lr, [r8, #0] @ Save calling PC mrs r6, spsr str r6, [r8, #4] @ Save CPSR str r0, [r8, #8] @ Save OLD_R0 mov r0, sp .endm .macro irq_restore_user_regs ldmia sp, {r0 - lr}^ @ Calling r0 - lr mov r0, r0 ldr lr, [sp, #S_PC] @ Get PC add sp, sp, #S_FRAME_SIZE subs pc, lr, #4 @ return & move spsr_svc into @ cpsr .endm .macro get_bad_stack ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter @ in banked mode) str lr, [r13] @ save caller lr in position 0 @ of saved stack mrs lr, spsr @ get the spsr str lr, [r13, #4] @ save spsr in position 1 of @ saved stack mov r13, #MODE_SVC @ prepare SVC-Mode @ msr spsr_c, r13 msr spsr, r13 @ switch modes, make sure @ moves will execute mov lr, pc @ capture return pc movs pc, lr @ jump to next instruction & @ switch modes. .endm .macro get_bad_stack_swi sub r13, r13, #4 @ space on current stack for @ scratch reg. str r0, [r13] @ save R0's value. ldr r0, IRQ_STACK_START_IN @ get data regions start @ spots for abort stack str lr, [r0] @ save caller lr in position 0 @ of saved stack mrs r0, spsr @ get the spsr str lr, [r0, #4] @ save spsr in position 1 of @ saved stack ldr r0, [r13] @ restore r0 add r13, r13, #4 @ pop stack entry .endm .macro get_irq_stack @ setup IRQ stack ldr sp, IRQ_STACK_START .endm .macro get_fiq_stack @ setup FIQ stack ldr sp, FIQ_STACK_START .endm /* * exception handlers 异常处理句柄 */ .align 5 undefined_instruction: get_bad_stack bad_save_user_regs bl do_undefined_instruction .align 5 software_interrupt: get_bad_stack_swi bad_save_user_regs bl do_software_interrupt .align 5 prefetch_abort: get_bad_stack bad_save_user_regs bl do_prefetch_abort .align 5 data_abort: get_bad_stack bad_save_user_regs bl do_data_abort .align 5 not_used: get_bad_stack bad_save_user_regs bl do_not_used #ifdef CONFIG_USE_IRQ .align 5 irq: get_irq_stack irq_save_user_regs bl do_irq irq_restore_user_regs .align 5 fiq: get_fiq_stack /* someone ought to write a more effective fiq_save_user_regs */ irq_save_user_regs bl do_fiq irq_restore_user_regs #else .align 5 irq: get_bad_stack bad_save_user_regs bl do_irq .align 5 fiq: get_bad_stack bad_save_user_regs bl do_fiq #endif
基于友善之臂ARM-tiny4412--uboot源码分析的更多相关文章
- u-boot源码分析
Uboot源码分析 源码以u-boot-1.3.4为基准,主芯片采用at91sam9260,主要介绍uboot执行流程. uboot官网:http://www.denx.de/wiki/U-Boot/ ...
- u-boot 源码分析(1) 启动过程分析
u-boot 源码分析(1) 启动过程分析 文章目录 u-boot 源码分析(1) 启动过程分析 前言 配置 源码结构 api arch board common cmd drivers fs Kbu ...
- u-boot源码分析之C语言段
题外话: 最近一直在学习u-boot的源代码,从代码量到代码风格,都让我认识到什么才是真正的程序.以往我所学到的C语言知识和u-boot的源代码相比,实在不值一提.说到底,机器都是0和1控制的.感觉这 ...
- (三)uboot源码分析
一.九鼎官方uboot和三星原版uboot对比(1)以九鼎官方的uboot为蓝本来学习的,以三星官方的这份为对照.(2)不同版本的uboot或者同一版本不同人移植的uboot,可能目录结构和文件内容都 ...
- uboot源码分析2-启动第二阶段
一.背景知识 1.uboot第二阶段应该做什么? 概括来讲uboot第一阶段主要就是初始化了SoC内部的一些部件(譬如看门狗.时钟),然后初始化DDR并且完成重定位. 由宏观分析来讲,uboot的第二 ...
- uboot源码分析1-启动第一阶段
1.不简单的头文件包含 #include <config.h>:这个文件的内容其实是包含了一个头文件:#include <configs/x210_sd.h>". # ...
- U-BOOT概述及源码分析(一)
嵌入式Linux系统从软件角度通常可以分为以下4个层次: 引导加载程序 | Linux内核 | 文件系统 | 用户应用程序 嵌入式Linux系统中典型分区结构: 正常启动过程中,Bootloader首 ...
- Java集合源码分析(一)ArrayList
前言 在前面的学习集合中只是介绍了集合的相关用法,我们想要更深入的去了解集合那就要通过我们去分析它的源码来了解它.希望对集合有一个更进一步的理解! 既然是看源码那我们要怎么看一个类的源码呢?这里我推荐 ...
- Envoy 源码分析--network L4 filter manager
目录 Envoy 源码分析--network L4 filter manager FilterManagerImpl addWriteFilter addReadFilter addFilter in ...
- Spring源码分析之IOC的三种常见用法及源码实现(一)
1.ioc核心功能bean的配置与获取api 有以下四种 (来自精通spring4.x的p175) 常用的是前三种 第一种方式 <?xml version="1.0" enc ...
随机推荐
- 剑指Offer——咪咕笔试题+知识点总结
剑指Offer--咪咕笔试题+知识点总结 情景回顾 时间:2016.10.09 15:00-16:30 地点:山东省网络环境智能计算技术重点实验室 事件:咪咕笔试 知识点总结 1.Html设置格式贵阳 ...
- Linux系统编程----僵尸进程
什么是僵尸进程? 僵尸进程, 指子进程退出后, 父进程还没有回收子进程的资源,这个子进程就处在于僵尸状态. 来看看如何产生? #include <stdio.h> #include < ...
- 06 Activity显示跳转
<span style="font-size:18px;">package com.fmy.day8_29task; import com.fmy.day8_29tas ...
- UE4类修饰符
官方文档链接: https://docs.unrealengine.com/latest/CHN/Programming/UnrealArchitecture/Reference/index.html ...
- 【Unity Shaders】Lighting Models —— 衣服着色器
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- Docker教程:dokcer的配置和命令
http://blog.csdn.net/pipisorry/article/details/50803028 Docker命令查询 终端运行docker命令,它会打印所有可用的命令列表及使用描述:# ...
- Android进阶(一)几种网络请求方式详解
Ref:http://blog.csdn.net/zuolongsnail/article/details/6373051 Android应用经常会和服务器端交互,这就需要手机客户端发送网络请求,下面 ...
- UNIX环境高级编程——计算机体系结构基础知识
无论是在CPU外部接总线的设备还是在CPU内部接总线的设备都有各自的地址范围,都可以像访问内存一样访问,很多体系结构(比如ARM)采用这种方式操作设备,称为等都会产生异常. 通常操作系统把虚拟地址空间 ...
- 【翻译】Ext JS 6 Beta发布
原文:Ext JS 6 Beta is Now Available 概述 Ext JS 6的好处 新的Ext JS功能和工具 需要你的反馈意见 概述 很高兴,Ext JS 6 beta版本现在发布了. ...
- go-mysql,一个易用的mysql接口框架实现
介绍 go-mysql是一个用go写的mysql driver,使用接口类似于go自身的database sql,但是稍微有一点不同,现阶段还不支持集成进go database/sql中,但实现难度并 ...