uboot启动文件start.s和main.c解析

来源:互联网 发布:太平洋软件网站 编辑:程序博客网 时间:2024/06/03 09:51

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

}