Ubooti启动文件解析

start.S

#include <config.h>

#include <version.h>

#if defined(CONFIG_OMAP1610)

#include <./configs/omap1510.h>

#elif defined(CONFIG_OMAP730)

#include <./configs/omap730.h>

#elif defined(CONFIG_HISILICON)

#include <asm/arch/platform.h>

#endif

/*

*************************************************************************

*

*Jump vector table as in table 3.1 in [1]

*

*************************************************************************

*/

/*******.globl声明一个符号可以被外部使用,相当于声明一个全局变量******/

.globl _start

_start:

/*******该部分为处理器的异常向量表,地址0x0000 0000 ~ 0x0000 0020******/

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

/*******.word伪操作是分配第一段子内存单元,并用expr初始化,此处即为存放中断函数地址******/

_undefined_instruction:

.wordundefined_instruction

_software_interrupt:

.wordsoftware_interrupt

_prefetch_abort:

.wordprefetch_abort

_data_abort:

.worddata_abort

_not_used:

.wordnot_used

_irq:

.wordirq

_fiq:

.wordfiq

/*******.align等同于balign******/

.balignl16,0xdeadbeef

/*

*************************************************************************

*

*Startup Code (reset vector)

*

* doimportant init only if we don't start from memory!

*setup Memory and board specific bits prior to relocation.

*relocate armboot to ram

*setup stack

*

*************************************************************************

*/

/******定义在/board/hi3515v100/config.mk中*******/

_TEXT_BASE:

.word        TEXT_BASE

.globl _armboot_start

_armboot_start:

.word_start

.globl _img_end

_img_end:

.word__img_end

/*

*These are defined in the board-specific linker script.

*/

.globl _bss_start

_bss_start:

.word__bss_start

.globl _bss_end

_bss_end:

.word_end

#ifdef CONFIG_USE_IRQ

/* IRQ stack memory (calculated atrun-time) */

.globl IRQ_STACK_START

IRQ_STACK_START:

.word        0x0badc0de

/* IRQ stack memory (calculated atrun-time) */

.globl FIQ_STACK_START

FIQ_STACK_START:

.word0x0badc0de

#endif

#ifdef CONFIG_HISILICON

_clr_remap_rom_entry:

.word   ROM_TEXT_ADRS + do_clr_remap - TEXT_BASE

_clr_remap_nand_entry:

.word   NAND_TEXT_ADRS + do_clr_remap - TEXT_BASE

#endif

/*

*the actual reset code

*/

/*******实际的处理代码从这里开始******/

reset:

/*

* set the cpu to SVC32 mode

*/

mrs  r0,cpsr                        /******将CPRS寄存器中的值传送给R0*******/

bic    r0,r0,#0x1f       /******清楚指定位r0 = r0&(!0x1f)*******/

orr    r0,r0,#0xd3      /******或操作r0 = r0|0xd3*******/

msr  cpsr,r0                        /******将R0的值送回CPRS寄存器中*******/

/*

* we do sys-critical inits only at reboot,

* not when booting from ram!

*/

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

/*

* 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 <input type="text" >*/

/*

* 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 */

mcr  p15, 0, r0, c1, c0, 0

ldr    r0, =REG_BASE_SCTL

ldr     r1, [r0, #0x8c]

and     r1, r1, #0x60

lsr     r4, r1, #5

@Checkif I need jump to rom

@movs    r0, pc, lsr#24          /* Z flag if r0 == 0 then 1 else 0 */

@bne     do_clr_remap

mov        r0, pc, lsr#24

cmp        r0, #0x0

bne  do_clr_remap

cmp     r4, #2               /*boot from nand flash*/

ldreq   pc, _clr_remap_nand_entry

cmp        r4, #0                 /* boot from nor flash */

ldreq   pc, _clr_remap_rom_entry

do_clr_remap:

ldr     r4, =REG_BASE_SCTL

@ldr         r0, =REG_VALUE_SC_NOLOCK

@str         r0, [r4, #REG_VALUE_SC_LOCKED]

ldr    r0, [r4, #REG_SC_CTRL]

@Setclear remap bit.

orr    r0, #(1<<8)

str    r0, [r4, #REG_SC_CTRL]

@SetupITCM (ENABLED, 2KB)

ldr    r0, =( 1 | (MEM_CONF_ITCM_SIZE<<2) |MEM_BASE_ITCM)

mcr     p15, 0, r0, c9, c1, 1

@enableI-Cache now

mrc  p15, 0, r0, c1, c0, 0

orr    r0, r0, #0x00001000         /* set bit 12 (I) I-Cache */

mcr  p15, 0, r0, c1, c0, 0

@Setuplowlevel sp

ldr    sp, =(MEM_BASE_ITCM + MEM_SIZE_ITCM)

@Checkif I'm running in static mem bank

mov r0, pc, lsr#28

cmp r0, #(TEXT_BASE>>28)

/*

* Go setup Memory and board specific bitsprior to relocation.

*/

beq  relocate

/******跳转到lowlevel_init,该函数在board/hi3515v100/lowlevel_init.c*******/

bl      lowlevel_init    /* go setup pll,mux,memory */

#endif

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

/******重定向代码,也就是uboot将自己从flash复制到RAM中*******/

relocate:                              /*relocate U-Boot to RAM          */

ldr     r0, =REG_BASE_SCTL

ldr     r6, [r0, #0x8c]

and     r6, #0x60

lsr  r4, r6, #5

adr   r0, _start          /*r0 <- current position of code   */

/******获取_TEXT_BASE地址,定义在/board/hi3515v100/config.mk中*******/

ldr    r1, _TEXT_BASE                 /* test if we run from flash or RAM */

cmp     r0, r1                  /* don't reloc duringdebug         */

beq     stack_setup

ldr    r2, _armboot_start

/******_img_end定义在/board/hi3515v100/u-boot.lds中*******/

ldr    r3, _img_end

sub   r2, r3, r2           /*r2 <- size of armboot            */

cmp        r4, #2

ldreq   r2, =(CFG_NAND_U_BOOT_ONE_PART)

add  r2, r0, r2           /*r2 <- source end address         */

copy_loop:

ldmia        r0!, {r3-r10}               /* copy from source address [r0]    */

stmia        r1!, {r3-r10}               /* copy to  target address [r1]    */

cmp r0, r2                           /*until source end addreee [r2]    */

ble    copy_loop

#endif       /*CONFIG_SKIP_RELOCATE_UBOOT */

/*Set up the stack                                                     */

//初始化堆栈

stack_setup:

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    */

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

/******跳转到start_armboot函数,该函数在/lib_arm/board.c*******/

ldr    pc, _start_armboot

_start_armboot:

.wordstart_armboot

/*

*************************************************************************

*

*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

@carve out a frame on current user stack

sub   sp, sp, #S_FRAME_SIZE

stmia        sp, {r0 - r12}     @ Save user registers (now in svc mode) r0-r12

ldr    r2, _armboot_start

sub   r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)

sub   r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack

@get values for "aborted" pc and cpsr (into parm regs)

ldmia        r2, {r2 - r3}

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

@!!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.

add  r8, sp, #S_PC

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

.macroget_bad_stack

ldr    r13, _armboot_start                 @ setup our mode stack

sub   r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)

sub   r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved acouple spots in abort stack

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

.macroget_irq_stack                         @setup IRQ stack

ldr    sp, IRQ_STACK_START

.endm

.macroget_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

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 effiction 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


main.c

void mian_loop(void)

{

#ifndef CFG_HUSH_PARSER

staticchar lastcommand[CFG_CBSIZE] = { 0, };

intlen;

intrc = 1;

intflag;

#endif

#if defined(CONFIG_BOOTDELAY) &&(CONFIG_BOOTDELAY >= 0)

char*s;

intbootdelay;

#endif

#ifdef CONFIG_PREBOOT

char*p;

#endif

#ifdef CONFIG_BOOTCOUNT_LIMIT

unsignedlong bootcount = 0;

unsignedlong bootlimit = 0;

char*bcs;

charbcs_set[16];

#endif /* CONFIG_BOOTCOUNT_LIMIT */

#if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)

ulongbmp = 0;          /* default bitmap */

externint trab_vfd (ulong bitmap);

#ifdef CONFIG_MODEM_SUPPORT

if(do_mdm_init)

bmp= 1;  /* alternate bitmap */

#endif

trab_vfd(bmp);

#endif       /*CONFIG_VFD && VFD_TEST_LOGO */

#ifdef CONFIG_BOOTCOUNT_LIMIT

bootcount= bootcount_load();

bootcount++;

bootcount_store(bootcount);

sprintf(bcs_set, "%lu", bootcount);

setenv("bootcount", bcs_set);

bcs= getenv ("bootlimit");

bootlimit= bcs ? simple_strtoul (bcs, NULL, 10) : 0;

#endif /* CONFIG_BOOTCOUNT_LIMIT */

#ifdef CONFIG_MODEM_SUPPORT

debug("DEBUG: main_loop:  do_mdm_init=%d\n", do_mdm_init);

if(do_mdm_init) {

char*str = strdup(getenv("mdm_cmd"));

setenv("preboot", str);  /* set ordelete definition */

if(str != NULL)

free(str);

mdm_init();/* wait for modem connection */

}

#endif /* CONFIG_MODEM_SUPPORT */

#ifdef CONFIG_VERSION_VARIABLE

{

externchar version_string[];

setenv("ver", version_string);  /*set version variable */

}

#endif /* CONFIG_VERSION_VARIABLE */

#ifdef CFG_HUSH_PARSER

u_boot_hush_start();

#endif

#ifdef CONFIG_AUTO_COMPLETE

install_auto_complete();

#endif

#ifdef CONFIG_PREBOOT

if((p = getenv ("preboot")) != NULL) {

# ifdef CONFIG_AUTOBOOT_KEYED

intprev = disable_ctrlc(1);       /* disableControl C checking */

# endif

# ifndef CFG_HUSH_PARSER

run_command(p, 0);

# else

parse_string_outer(p,FLAG_PARSE_SEMICOLON |

FLAG_EXIT_FROM_LOOP);

# endif

# ifdef CONFIG_AUTOBOOT_KEYED

disable_ctrlc(prev); /* restore Control C checking */

# endif

}

#endif /* CONFIG_PREBOOT */

#if defined(CONFIG_BOOTDELAY) &&(CONFIG_BOOTDELAY >= 0)

s= getenv ("bootdelay");

bootdelay= s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);

# ifdef CONFIG_BOOT_RETRY_TIME

init_cmd_timeout();

# endif      /*CONFIG_BOOT_RETRY_TIME */

#ifdef CONFIG_POST

if(gd->flags & GD_FLG_POSTFAIL) {

s= getenv("failbootcmd");

}

else

#endif /* CONFIG_POST */

#ifdef CONFIG_BOOTCOUNT_LIMIT

if(bootlimit && (bootcount > bootlimit)) {

printf("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",

(unsigned)bootlimit);

s= getenv ("altbootcmd");

}

else

#endif /* CONFIG_BOOTCOUNT_LIMIT */

s= getenv ("bootcmd");

debug("### main_loop: bootcmd=\"%s\"\n", s ? s :"<UNDEFINED>");

/* abortboot (bootdelay)返回1则不启动boot,否则启动boot */

if(bootdelay >= 0 && s && !abortboot (bootdelay)) {

/*llz added to pass mac address from uboot to kernel by merge the valueof ethaddr to bootargs.*/

//       extern void merge_mac_to_bootargs(void);

//       merge_mac_to_bootargs();

# ifdef CONFIG_AUTOBOOT_KEYED

intprev = disable_ctrlc(1);       /* disableControl C checking */

# endif

# ifndef CFG_HUSH_PARSER

run_command(s, 0);

# else

parse_string_outer(s,FLAG_PARSE_SEMICOLON |

FLAG_EXIT_FROM_LOOP);

# endif

# ifdef CONFIG_AUTOBOOT_KEYED

disable_ctrlc(prev); /* restore Control C checking */

# endif

}

/* # ifdef CONFIG_MENUKEY该部分代码不会调用 */

# ifdef CONFIG_MENUKEY

if(menukey == CONFIG_MENUKEY) {

/*add by heliangbin 2012-7-21 */

printf("main_loop#################trace2!\n");

s = getenv("menucmd");

if (s) {

# ifndef CFG_HUSH_PARSER

run_command(s, 0);

/*add by heliangbin 2012-7-21 */

printf("main_loop#################trace3!\n");

# else

parse_string_outer(s,FLAG_PARSE_SEMICOLON |

FLAG_EXIT_FROM_LOOP);

# endif

}

}

#endif /* CONFIG_MENUKEY*/

#endif       /*CONFIG_BOOTDELAY */

#ifdef CONFIG_AMIGAONEG3SE

{

extern void video_banner(void);

video_banner();

}

#endif

/*

* Main Loop for Monitor Command Processing

*/

#ifdef CFG_HUSH_PARSER

parse_file_outer();

/*This point is never reached */

for(;;);

#else

for(;;) {

#ifdef CONFIG_BOOT_RETRY_TIME

if(rc >= 0) {

/*Saw enough of a valid command to

* restart the timeout.

*/

reset_cmd_timeout();

}

#endif

len = readline (CFG_PROMPT);

flag= 0;    /* assume no special flags for now*/

if(len > 0)

strcpy (lastcommand, console_buffer);

elseif (len == 0)

flag|= CMD_FLAG_REPEAT;

#ifdef CONFIG_BOOT_RETRY_TIME

elseif (len == -2) {

/*-2 means timed out, retry autoboot

*/

puts("\nTimed out waiting for command\n");

# ifdef CONFIG_RESET_TO_RETRY

/*Reinit board to run initialization code again */

do_reset(NULL, 0, 0, NULL);

# else

return;               /* retry autoboot */

# endif

}

#endif

if(len == -1)

puts("<INTERRUPT>\n");

else

rc = run_command (lastcommand, flag);

/*add by heliangbin 2012-7-21 */

printf("main_looplastcommand = %s!\n", lastcommand);

//if(rc <= 0) {

/*invalid command or not repeatable, forget it */

lastcommand[0]= 0;

//}

}

#endif /*CFG_HUSH_PARSER*/

}

uboot启动文件start.s和main.c解析相关推荐

  1. 【Linux】U-Boot启动文件start.S详解(超详细讲解,上篇)

    U-Boot U-Boot的版本选择 U-Boot的下载地址:/pub/u-boot的索引 进入到U-Boot的下载页面,发现U-Boot的版本众多: 那怎么选取U-Boot的版本呢?够用就行. 本文 ...

  2. Uboot启动内核和根文件系统命令分析

      uboot有两种启动 Linux 内核和rootfs的方法,一种是直接从flash(nand或emmc)启动,一种是从网络启动.这里面用到了两个非常重要的环境变量bootcmd 和 bootarg ...

  3. U-Boot完美解读(2)——启动文件start.s解析

    2.谁来唤醒我 在上一节的u-boot.lds文件中有这样一句是: cpu/arm_cortexa8/start.o (.text) 这句话就是调用初始化代码stat.s的元老级功臣,这可和神话中的女 ...

  4. 2014.4新版uboot启动流程分析

    原文 http://blog.csdn.net/skyflying2012/article/details/25804209 此处转载有稍作修改 最近开始接触uboot,现在需要将2014.4版本ub ...

  5. u-boot启动过程

    目录: 一.初识u-boot 3 1,Bootloader介绍 3 2,Bootloader的启动方式 3 (1)网络启动方式 4 (2)磁盘启动方式 4 (3)Flash启动方式 4 3,U-boo ...

  6. uboot学习之三-----uboot启动第一阶段--start.S之一

    uboot分为两个阶段:start.S是uboot的第一阶段. 一:引入start.S u-boot.s找到start.S的入口 ①首先在C语言中整个项目的入口就是main函数(这是C语言规定的),所 ...

  7. Uboot启动过程详解

    u-boot系统启动流程 大多数bootloader都分为stage1和stage2两部分,u-boot也不例外. 依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语 ...

  8. U-Boot启动过程--详细版的完全分析

    目录: 一.初识u-boot 3 1,Bootloader介绍 3 2,Bootloader的启动方式 3 (1)网络启动方式 4 (2)磁盘启动方式 4 (3)Flash启动方式 4 3,U-boo ...

  9. Uboot启动全过程

    1.1       U-Boot 工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 ?  硬件设备初始化 ?  加载U-Boot第二阶段代码到RAM空间 ...

  10. u-boot.lds文件详解

    网上大部分u-boot.lds文件的分析大部分都是千遍一律,例如下面就是本人在网上找到的关于u-boot.lds的资料. OUTPUT_FORMAT("elf32-littlearm&quo ...

最新文章

  1. python数据分析设置_Python 数据分析系列之如何安装和设置 Python
  2. 初学者编写python用什么软件好_初学者编写python用什么软件
  3. LeetCode 1200. 最小绝对差
  4. 12GB内存版华为P30、P30 Pro工信部入网:售价或将突破7000元
  5. 用docker swarm 实现集群
  6. activity 点击后传递数据给fragment_ViewModel+LiveData实现Fragment间通信
  7. 4、Windows2008 R2安装Vcenter5.0
  8. Openvswitch原理与代码分析(5): 内核中的流表flow table操作
  9. linux root用户被锁定如何解除,超级管理员被锁定,如何解锁?
  10. java服务安装(三):使用appassembler
  11. 360oauth token是什么意思_币圈token是什么意思?
  12. 20P18 Pr预设模板300个现代商务婚礼简洁迷你创意文字标题排版设计动画
  13. 初识linux之vim工具与bdb调试工具
  14. UI自动化测试(一)
  15. Mac上出现多个版本选择打开edge浏览器
  16. 《Android NFC开发实战详解》——6.4节Android NFC P2P开发进阶
  17. 计算机技术研究所复试英语,英语复试经验谈
  18. 6成网友睡前不玩手机睡不着 专家称影响生育
  19. 计算机维修知识论文,计算机维修论文2000字
  20. 刀模使用寿命,你们知道吗?

热门文章

  1. snowflake算法
  2. 【转】string.Format对C#字符串格式化
  3. 要么战胜,要么战死,绝不投降
  4. STORM的DRPC通讯
  5. ELK在广告系统监控中的应用 及 Elasticsearch简介
  6. Centos7.4源码搭建zabbix3.4.11企业级监控
  7. Hadoop核心组件
  8. 走一条硬件工程师的道路
  9. AS3 的 2D向量类(Vector2D)
  10. 从哪儿摔倒,从哪儿爬起