uboot 源码分析一

xiaoxiao2021-02-28  44

这一篇主要是了解uboot。

在分析uboot的Makefile的时候我们知道他的入口地址在cpu/arm920/start.s

打开文件cpu/arm920/start.s:  (1)硬件设备初始化。

  依次完成各步奏的执行顺序:

   1.将cpu设置成管理模式(svc)。

reset: /*  * set the cpu to SVC32 mode  */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0

   2.关看门狗。

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ldr     r0, =pWTCON mov     r1, #0x0 str     r1, [r0]

   3.屏蔽中断。

/* * mask all IRQs by setting all bits in the INTMR - default */ mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0] # if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0] # endif #if 0 /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] #endif #endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */ /* * we do sys-critical inits only at reboot, * not when booting from ram! */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT adr r0, _start /* r0 <- current position of code   */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp     r0, r1                  /* don't reloc during debug         */ blne cpu_init_crit #endif

其中在跟踪cpu_init_crit 我们会定位到lowlevel_init:

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 /* * before relocating, we have to setup RAM timing * because memory timing is board-dependend, you will * find a lowlevel_init.S in your board directory. */ mov ip, lr bl lowlevel_init mov lr, ip mov pc, lr #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

   4.初始化SDRAM——>设置栈 sp ->内存(继续跟踪/100ask24x0/lowlevel_init board)。

start.S 调用lowlevel_init函数来初始化存储控制器:

.globl lowlevel_init lowlevel_init: /* memory control configuration */ /* make r0 relative the current location so that it */ /* reads SMRDATA out of FLASH rather than memory ! */ ldr     r0, =SMRDATA ldr r1, _TEXT_BASE sub r0, r0, r1 ldr r1, =BWSCON/* Bus Width Status Controller */ add     r2, r0, #13*4 0: ldr     r3, [r0], #4 str     r3, [r1], #4 cmp     r2, r0 bne     0b /* everything is fine now */ mov pc, lr .ltorg /* the literal pools origin */ SMRDATA:     .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))      .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))     .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))     .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))     .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))     .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))     .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))     .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))     .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))     .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)     .word 0xb1     .word 0x30     .word 0x30

   5.设置栈。

/* 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    */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT     bl clock_init #endif     #ifndef CONFIG_SKIP_RELOCATE_UBOOT

   6.时钟。

clock_init:

void cloclock_initck_init(void) { S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000;     /* support both of S3C2410 and S3C2440, by www.100ask.net */     if (isS3C2410)     {         /* FCLK:HCLK:PCLK = 1:2:4 */         clk_power->CLKDIVN = S3C2410_CLKDIV;         /* change to asynchronous bus mod */         __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */                       "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */                       "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */                       :::"r1"                     );          /* to reduce PLL lock time, adjust the LOCKTIME register */         clk_power->LOCKTIME = 0xFFFFFFFF;         /* configure UPLL */         clk_power->UPLLCON = S3C2410_UPLL_48MHZ;         /* some delay between MPLL and UPLL */         delay (4000);         /* configure MPLL */         clk_power->MPLLCON = S3C2410_MPLL_200MHZ;         /* some delay between MPLL and UPLL */         delay (8000);     }     else     {         /* FCLK:HCLK:PCLK = 1:4:8 */         clk_power->CLKDIVN = S3C2440_CLKDIV;         /* change to asynchronous bus mod */         __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */                       "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */                       "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */                       :::"r1"                     );         /* to reduce PLL lock time, adjust the LOCKTIME register */         clk_power->LOCKTIME = 0xFFFFFFFF;         /* configure UPLL */         clk_power->UPLLCON = S3C2440_UPLL_48MHZ;         /* some delay between MPLL and UPLL */         delay (4000);         /* configure MPLL */         clk_power->MPLLCON = S3C2440_MPLL_400MHZ;         /* some delay between MPLL and UPLL */         delay (8000);     } }

   7.代码 flash->SDRAM

relocate: /* relocate U-Boot to RAM   */ adr r0, _start/* r0 <- current position of code   */ ldr r1, _TEXT_BASE/* test if we run from flash or RAM */ cmp     r0, r1                  /* don't reloc during debug         */ beq     clear_bss ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2/* r2 <- size of armboot            */

CopyCode2Ram

int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size) {     unsigned int *pdwDest;     unsigned int *pdwSrc;     int i;     if (bBootFrmNORFlash())     {         pdwDest = (unsigned int *)buf;         pdwSrc  = (unsigned int *)start_addr;         /* 从 NOR Flash启动 */         for (i = 0; i < size / 4; i++)         {             pdwDest[i] = pdwSrc[i];         }         return 0;     }     else     {         /* 初始化NAND Flash */ nand_init_ll();         /* 从 NAND Flash启动 */         nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP)); return 0;     } }

   8.清bass段。

clear_bss: ldr r0, _bss_start/* find start of bss segment        */ ldr r1, _bss_end/* stop here                        */ mov r2, #0x00000000/* clear        

   9.调用start-boot 第二阶段(c函数)。

_start_armboot:

   .....等等等等,基本上步奏都差不多这样。

(2)为加载BootLoader的第二阶段代码准备内存空间。

看看它的内存分配。

  

转载请注明原文地址: https://www.6miu.com/read-78821.html

最新回复(0)