标签:寄存器 contain params char get 包含 步骤 hash jpg
??本分析采用的不是官方u-boot,而是采用九鼎移植之后的u-boot,原u-boot版本为1.3.4。
??start.S相当于BL1,对我们理解uboot启动至关重要
??可以通过link.lds链接脚本来得到start.S的位置
| head file | position | description | 
|---|---|---|
| config.h | ./include/configs/x210_sd.h | 输入make x210_sd_config后执行mkconfig最终生成,是最为关键的头文件 | 
| version.h | ./include/version_autogenerated.h | 主makefile第一步中生成,包含版本信息 | 
| asm/proc/domain.h | include/asm-arm/proc-armv/domain.h | 运用mkconfig中的符号链接,包含domain.h,有关IO,内核,用户内存 | 
| regs.h | ./include/s5pc110.h | 运用mkconfig中的符号链接,包括s5pc110中的寄存器定义 | 

#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
	.word 0x2000
	.word 0x0
	.word 0x0
	.word 0x0
#endif.globl _start
_start: 
	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
_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.balignl 16,0xdeadbeefmsr	cpsr_c, #0xd3		
@ I & F disable, Mode: 0x13 - SVC
0xd3 = 1101 0011 b,工作状态为arm态,关闭FIQ,IRQ,使工作模式为SVC。
bl	disable_l2cache				// 禁止L2 cache
bl	set_l2cache_auxctrl_cycle	// l2 cache相关初始化
bl	enable_l2cache				// 使能l2 cache@ 刷新L1 cache的icache和dcache。
mov	r0, #0                  @ set up for MCR
mcr	p15, 0, r0, c8, c7, 0   @ invalidate TLBs
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/* 在210内部有一个寄存器(地址是0xE0000004)
 * 这个寄存器中的值是硬件根据OM引脚的设置而自动设置值的 
 * 可以通过读取这个寄存器的值然后判断其值来确定当前选中的启动介质是Nand还是SD还是其他的。
 */ 
ldr	r0, =PRO_ID_BASE
ldr	r1, [r0,#OMR_OFFSET]
bic	r2, r1, #0xffffffc1??经过一系列比较,得到
/* SD/MMC BOOT */
cmp     r2, #0xc	// c即为SD或MMC启动
moveq   r3, #BOOT_MMCSD	
// r3中存储了0x03??然后再将0x3放入INFORM3寄存器

	ldr	sp, =0xd0036000 /* end of sram dedicated to u-boot */
	sub	sp, sp, #12	/* set stack */
	mov	fp, #0??这个栈地址设置在SROM中,并且没有按照三星要求来做。因为接下来需要调用C函数,所以需要先设置Stack。
./board/samsung/x210/lowlevel_init.S??主要完成关看门狗,供电锁存,判断当前代码执行位置,初始化时钟,初始化DDR,初始化串口。
	/* get ready to call C functions */
	ldr	sp, _TEXT_PHY_BASE	/* setup temp stack pointer */
	sub	sp, sp, #12
	mov	fp, #0			/* no previous frame, so fp=0 */??_TEXT_PHY_BASE = 0x33E0 0000,这里的栈设置在DDR中,沿着uboot起始地址向下。
#if defined(CONFIG_EVT1)
	/* If BL1 was copied from SD/MMC CH2 */
	ldr	r0, =0xD0037488		//	V210_SDMMC_BASE current boot channel
	ldr	r1, [r0]
	ldr	r2, =0xEB200000		//	SD卡通道二
	cmp	r1, r2
	beq     mmcsd_boot
#endif??当前启动状态与SD卡通道2的启动地址比较,进入mmcsd_boot。

#if DELETE
	ldr     sp, _TEXT_PHY_BASE      
	sub     sp, sp, #12
	mov     fp, #0
#endif
	bl      movi_bl2_copy
	b       after_copy??进入movi_bl2_copy函数
./cpu/s5pc11x/movi.c??复制uboot代码到DDR中
void movi_bl2_copy(void)
{
	ulong ch;
#if defined(CONFIG_EVT1)
	ch = *(volatile u32 *)(0xD0037488);	// EB20_0000通道2启动
	copy_sd_mmc_to_mem copy_bl2 =
	    (copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98));
	#if defined(CONFIG_SECURE_BOOT)
	ulong rv;
	#endif
#else
	ch = *(volatile u32 *)(0xD003A508);
	copy_sd_mmc_to_mem copy_bl2 =
	    (copy_sd_mmc_to_mem) (*(u32 *) (0xD003E008));
#endif
	u32 ret;
	//	iNand
	if (ch == 0xEB000000) {
		ret = copy_bl2(0, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
			CFG_PHY_UBOOT_BASE, 0);
#if defined(CONFIG_SECURE_BOOT)
		/* do security check */
		rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
				      (unsigned char *)CFG_PHY_UBOOT_BASE, (1024*512-128),
			              (unsigned char *)(CFG_PHY_UBOOT_BASE+(1024*512-128)), 128 );
		if (rv != 0){
				while(1);
			}
#endif
	}
	// SD卡2
	else if (ch == 0xEB200000) {
		ret = copy_bl2(2, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
			CFG_PHY_UBOOT_BASE, 0);
		
#if defined(CONFIG_SECURE_BOOT)
		/* do security check */
		rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
				      (unsigned char *)CFG_PHY_UBOOT_BASE, (1024*512-128),
			              (unsigned char *)(CFG_PHY_UBOOT_BASE+(1024*512-128)), 128 );
		if (rv != 0) {
			while(1);
		}
#endif
	}
	else
		return;
	if (ret == 0)
		while (1)
			;
	else
		return;
}??从上一步图片中的寄存器判断是SD0还是SD2启动,然后再使用device copy function复制代码到DDR中。
#if defined(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 */
	// 开启translation table base
	ldr	r0, _mmu_table_base
	ldr	r1, =CFG_PHY_UBOOT_BASE
	ldr	r2, =0xfff00000
	bic	r0, r0, r2
	orr	r1, r0, r1
	mcr	p15, 0, r1, c2, c0, 0??MMU映射表是其中关键。
	/* form a first-level section entry */
	// .macro用于生成宏,.endm用于结束宏,.word表示的数即为表项
.macro FL_SECTION_ENTRY base,ap,d,c,b
	.word (\base << 20) | (\ap << 10) | 	      (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a"
	.align 14
	// the following alignment creates the mmu table at address 0x4000.
	.globl mmu_table
mmu_table:
	.set __base,0
	// Access for iRAM
	// 伪指令.rept相当于循环开始,0x100为循环次数
	.rept 0x100
	FL_SECTION_ENTRY __base,3,0,0,0
	.set __base,__base+1
	// 循环结束
	.endr
	// Not Allowed
	.rept 0x200 - 0x100
	.word 0x00000000
	.endr
	.set __base,0x200
	// should be accessed
	.rept 0x600 - 0x200
	FL_SECTION_ENTRY __base,3,0,1,1
	.set __base,__base+1
	.endr
	.rept 0x800 - 0x600
	.word 0x00000000
	.endr
	.set __base,0x800
	// should be accessed
	.rept 0xb00 - 0x800
	FL_SECTION_ENTRY __base,3,0,0,0
	.set __base,__base+1
	.endr
/*	.rept 0xc00 - 0xb00
	.word 0x00000000
	.endr */
	.set __base,0xB00
	.rept 0xc00 - 0xb00
	FL_SECTION_ENTRY __base,3,0,0,0
	.set __base,__base+1
	.endr
	// 0xC000_0000映射到0x3000_0000
	.set __base,0x300
	//.set __base,0x200
	// 256MB for SDRAM with cacheable
	.rept 0xD00 - 0xC00
	FL_SECTION_ENTRY __base,3,0,1,1
	.set __base,__base+1
	.endr
	// access is not allowed.
	@.rept 0xD00 - 0xC80
	@.word 0x00000000
	@.endr
	.set __base,0xD00
	// 1:1 mapping for debugging with non-cacheable
	.rept 0x1000 - 0xD00
	FL_SECTION_ENTRY __base,3,0,0,0
	.set __base,__base+1
	.endr	
	
	#else	// CONFIG_MCP_AC, CONFIG_MCP_H, CONFIG_MCP_B| 物理地址 | 映射地址 | 
|---|---|
| 0x0000_0000-0FFF_FFFF | 0x0000_0000-0FFF_FFFF | 
| 0x1000_0000-1FFF_FFFF | Not allowed | 
| 0x2000_0000-5FFF_FFFF | 0x2000_0000-5FFF_FFFF | 
| 0x6000_0000-7FFF_FFFF | Not allowed | 
| 0x8000_0000-AFFF_FFFF | 0x8000_0000-AFFF_FFFF | 
| 0xB000_0000-BFFF_FFFF | 0xB000_0000-BFFF_FFFF | 
| 0xC000_0000-CFFF_FFFF | 0x3000_0000-3FFF_FFFF | 
| 0xD000_0000-FFFF_FFFF | 0xD000_0000-FFFF_FFFF | 
	/* Enable the MMU */
	// 使能MMU
mmu_on:
	mrc	p15, 0, r0, c1, c0, 0
	orr	r0, r0, #1
	mcr	p15, 0, r0, c1, c0, 0
	nop
	nop	// 第三次设置栈
	/* Set up the stack						    */
stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
	ldr	sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)??其中CFG_UBOOT_BASE=0xC3E0_0000,CFG_UBOOT_SIZE=2M
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	push	{lr}??CPU允许多种复位状况。我们需要在复位代码中检测复位状态。
	ldr	r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
	ldr	r1, [r0]
	bic	r1, r1, #0xfff6ffff
	cmp	r1, #0x10000
	beq	wakeup_reset_pre
	cmp	r1, #0x80000
	beq	wakeup_reset_from_didle	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET)
	ldr	r1, [r0]
	ldr	r2, =IO_RET_REL
	orr	r1, r1, r2
	str	r1, [r0]	ldr	r0, =ELFIN_WATCHDOG_BASE	/* 0xE2700000 */
	mov	r1, #0
	str	r1, [r0]??略过。
	/* PS_HOLD pin(GPH0_0) set to high */
	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + PS_HOLD_CONTROL_OFFSET)
	ldr	r1, [r0]
	orr	r1, r1, #0x300	
	orr	r1, r1, #0x1	
	str	r1, [r0]	/* 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     1f			/* r0 == r1 then skip sdram init   */
	//	1表示编号,f表示
	forward,向后找??这里采用的方法是截取现在地址的12-14位,以及链接时地址的12-14位,如果相等,则可以判断程序已经在DDR中,否则可认为程序仍然在SROM中。
??进入system_clock_init函数
??进入mem_ctrl_asm_init函数,DMC0_MEMCONFIG_0,在裸机中配置值为0x20E01323;在uboot中配置为0x30F01313.这个配置不同就导致结果不同。
??在 裸机中DMC0的256MB内存地址范围是0x20000000-0x2FFFFFFF;
??在uboot中DMC0的256MB内存地址范围为0x30000000-0x3FFFFFFF。
O??进入uart_asm_init函数,初始化完成后发送一个O。
??进入tzpc_init函数
K??发送K后,返回pop {pc}。

标签:寄存器 contain params char get 包含 步骤 hash jpg
原文地址:https://www.cnblogs.com/0nism/p/12380583.html