s5pv210三星官方Uboot分析(USB启动方式)

news/2024/12/2 21:54:35/

首先要了解210板子的内存配置情况,我的板子是512M内存,DMC0上接了256M,DMC1接了256M,为了保证地址连续,内存地址只能是0x30000000 ~ 0x4FFFFFFF

第一步运行start.S:

_TEXT_BASE:
.word	TEXT_BASE//存放基址
/*由makefile内容:
x210_nand_config :	unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
得知TXET_BASE = 0xc3e00000,为什么超出了0x30000000 ~ 0x4FFFFFFF,因为dnw烧写在0xd0000010处的启动代码初始化DDR时做了内存映射的工作,这个映射方式是简单的线性映射,只是在把内存起始地址增加至0xc0000000。后面会提到。
*/
/*
* Below variable is very important because we use MMU in U-Boot.
* Without it, we cannot run code correctly before MMU is ON.
* by scsuh.
*/
_TEXT_PHY_BASE:
.word	CFG_PHY_UBOOT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#if defined(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
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode and IRQ & FIQ disable
*/
@;mrs	r0,cpsr
@;bic	r0,r0,#0x1f
@;orr	r0,r0,#0xd3
@;msr	cpsr,r0
msr	cpsr_c, #0xd3		@ I & F disable, Mode: 0x13 - SVC
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
cpu_init_crit:
#ifndef CONFIG_EVT1
#if 0	
bl	v7_flush_dcache_all
#else
bl	disable_l2cache
mov	r0, #0x0	@ 
mov	r1, #0x0	@ i	
mov	r3, #0x0
mov	r4, #0x0
lp1:
mov	r2, #0x0	@ j
lp2:	
mov	r3, r1, LSL #29		@ r3 = r1(i) <<29
mov	r4, r2, LSL #6		@ r4 = r2(j) <<6
orr	r4, r4, #0x2		@ r3 = (i<<29)|(j<<6)|(1<<1)
orr	r3, r3, r4
mov	r0, r3			@ r0 = r3
bl	CoInvalidateDCacheIndex
add	r2, #0x1		@ r2(j)++
cmp	r2, #1024		@ r2 < 1024
bne	lp2			@ jump to lp2
add	r1, #0x1		@ r1(i)++
cmp	r1, #8			@ r1(i) < 8
bne	lp1			@ jump to lp1
bl	set_l2cache_auxctrl
bl	enable_l2cache
#endif
#endif
bl	disable_l2cache
bl	set_l2cache_auxctrl_cycle
bl	enable_l2cache
/*
* Invalidate L1 I/D
*/
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
/* Read booting information */
ldr	r0, =PRO_ID_BASE
ldr	r1, [r0,#OMR_OFFSET]
bic	r2, r1, #0xffffffc1
#ifdef CONFIG_VOGUES
/* PS_HOLD(GPH0_0) set to output high */
ldr	r0, =ELFIN_GPIO_BASE
ldr	r1, =0x00000001
str	r1, [r0, #GPH0CON_OFFSET]
ldr	r1, =0x5500
str	r1, [r0, #GPH0PUD_OFFSET]
ldr	r1, =0x01
str	r1, [r0, #GPH0DAT_OFFSET]
#endif
/* NAND BOOT */
cmp	r2, #0x0		@ 512B 4-cycle
moveq	r3, #BOOT_NAND
cmp	r2, #0x2		@ 2KB 5-cycle
moveq	r3, #BOOT_NAND
cmp	r2, #0x4		@ 4KB 5-cycle	8-bit ECC
moveq	r3, #BOOT_NAND
cmp	r2, #0x6		@ 4KB 5-cycle	16-bit ECC
moveq	r3, #BOOT_NAND
cmp	r2, #0x8		@ OneNAND Mux
moveq	r3, #BOOT_ONENAND
/* SD/MMC BOOT */
cmp     r2, #0xc
moveq   r3, #BOOT_MMCSD	
/* NOR BOOT */
cmp     r2, #0x14
moveq   r3, #BOOT_NOR	
/*以上代码判断启动方式,保存到r3中*/
#if 0	/* Android C110 BSP uses OneNAND booting! */
/* For second device booting */
/* OneNAND BOOTONG failed */
cmp     r2, #0x8
moveq   r3, #BOOT_SEC_DEV
#endif
/* Uart BOOTONG failed */
cmp     r2, #(0x1<<4)
moveq   r3, #BOOT_SEC_DEV
ldr	r0, =INF_REG_BASE
str	r3, [r0, #INF_REG3_OFFSET]     
/*
* Go setup Memory and board specific bits prior to relocation.
*/
ldr	sp, =0xd0036000 /* end of sram dedicated to u-boot */
sub	sp, sp, #12	/* set stack */
mov	fp, #0
bl	lowlevel_init	/* go setup pll,mux,memory *//*进入
/* To hold max8698 output before releasing power on switch,
* set PS_HOLD signal to high
*/
@ldr	r0, =0xE010E81C  /* PS_HOLD_CONTROL register */
@ldr	r1, =0x00005301	 /* PS_HOLD output high	*/
@str	r1, [r0]
/* get ready to call C functions */
ldr	sp, _TEXT_PHY_BASE	/* setup temp stack pointer */设置SP = 0x33e00000
sub	sp, sp, #12
mov	fp, #0			/* no previous frame, so fp=0 */
/* 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     after_copy		/* r0 == r1 then skip flash copy   */
这里判断当前是否已经正常启动,如果r1 = r2,说明uboot已完成自拷贝,则跳转到after_copy,在after_copy中设置MMU映射表之后,开始正常运行初始化板子。
after_copy:
#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 */
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
/* Enable the MMU */
mmu_on:
mrc	p15, 0, r0, c1, c0, 0
orr	r0, r0, #1
mcr	p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif
skip_hw_init:
/* Set up the stack						    */
stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
ldr	sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
#else
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                        */
#if defined(CONFIG_USE_IRQ)
sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub	sp, r0, #12		/* leave 3 words for abort-stack    */
#endif
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  /*进入启动程序*/
回头看如果r1 != r2,那么需要进行自拷贝:
#if defined(CONFIG_EVT1)
/* If BL1 was copied from SD/MMC CH2 */
ldr	r0, =0xD0037488  /*判断是否是SD卡启动*/
ldr	r1, [r0]
ldr	r2, =0xEB200000
cmp	r1, r2
beq     mmcsd_boot
#endif
ldr	r0, =INF_REG_BASE
ldr	r1, [r0, #INF_REG3_OFFSET]
cmp	r1, #BOOT_NAND		/* 0x0 => boot device is nand */
beq	nand_boot
cmp	r1, #BOOT_ONENAND	/* 0x1 => boot device is onenand */
beq	onenand_boot
cmp     r1, #BOOT_MMCSD
beq     mmcsd_boot
cmp     r1, #BOOT_NOR
beq     nor_boot
cmp     r1, #BOOT_SEC_DEV
beq     mmcsd_boot
nand_boot:
mov	r0, #0x1000
bl	copy_from_nand
b	after_copy
onenand_boot:
bl	onenand_bl2_copy
b	after_copy
mmcsd_boot:
#if DELETE
ldr     sp, _TEXT_PHY_BASE /*这里不会执行*/     
sub     sp, sp, #12
mov     fp, #0
#endif
bl      movi_bl2_copy
b       after_copy
nor_boot:
bl      read_hword
b       after_copy

这里判断当前是否已经正常启动,如果r1 = r2,说明uboot已完成自拷贝,则跳转到after_copy,在after_copy中设置MMU映射表之后,开始正常运行初始化板子。
after_copy:
after_copy:
#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 */
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
/* Enable the MMU */
mmu_on:
mrc	p15, 0, r0, c1, c0, 0
orr	r0, r0, #1
mcr	p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif
skip_hw_init:
/* Set up the stack						    */
stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
ldr	sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
#else
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                        */
#if defined(CONFIG_USE_IRQ)
sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub	sp, r0, #12		/* leave 3 words for abort-stack    */
#endif
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

我们直接看copy_from_nand

/** copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)* r0: size to be compared* Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size*/.globl copy_from_nand
copy_from_nand:push	{lr}		/* save return address */mov	r9, r0mov	r9, #0x100		/* Compare about 8KB */bl	copy_uboot_to_ramtst 	r0, #0x0bne	copy_failed#if defined(CONFIG_EVT1)ldr	r0, =0xd0020000
#else	ldr	r0, =0xd0030000
#endifldr	r1, _TEXT_PHY_BASE	/* 0x23e00000 */
1:	ldr	r3, [r0], #4ldr	r4, [r1], #4teq	r3, r4bne	compare_failed	/* not matched */subs	r9, r9, #4bne	1bpop	{pc}		/* all is OK */copy_failed:nop			/* copy from nand failed */b	copy_failedcompare_failed:nop			/* compare failed */b	compare_failed


看看copy_uboot_toram,因为已经设置栈,可以执行C程序了;

#define NAND_CONTROL_ENABLE()	(NFCONT_REG |= (1 << 0))
static void nand_readpage (ulong col, ulong row, uchar* buf, int len)
{
int i;
NAND_ENABLE_CE();
NFCMD_REG = NAND_CMD_READ0;
/* Write Column Address */
NFADDR_REG = (col) & 0xff;
NFADDR_REG = (col >> 8) & 0xff;
/* Write Row Address */
NFADDR_REG = (row) & 0xff;
NFADDR_REG = (row >> 8) & 0xff;
NFADDR_REG = (row >> 16) & 0xff;
NFCMD_REG = NAND_CMD_READSTART;
NF_TRANSRnB();
for (i = 0; i < len; i++) {
buf[i] = NFDATA8_REG;
}
NAND_DISABLE_CE();
}
static int nand_isbad (ulong addr)
{
int i;
int page_size = 2048;
uchar oob[2];
if (addr == 0)
return 0;
nand_readpage(page_size, addr, oob, 2);
if ((oob[0] == 0xFF) && (oob[1] == 0xFF))
return 0;
else
return 1;
}
/*
* address format
*              17 16         9 8            0
* --------------------------------------------
* | block(12bit) | page(5bit) | offset(9bit) |
* --------------------------------------------
*/
static int nandll_read_page (uchar *buf, ulong addr)
{
int i;
int page_size = 2048;
nand_readpage(0, addr, buf, page_size);
return 0;
}
/*
* Read data from NAND.
*/
static int nandll_read_blocks (ulong dst_addr, ulong size)
{
uchar *buf = (uchar *)dst_addr;
int i;
int skipped_page = 0;
uint page_shift = 11;
/* Read pages */
for (i = 0; i < (size>>page_shift); i++, buf+=(1<0x80)
large_block = 1;
else
return -1;	// Do not support small page (512B) any more
/* read NAND blocks */
return nandll_read_blocks(CFG_PHY_UBOOT_BASE, COPY_BL2_SIZE);
}

回过头来分析after_copy,在这之前的代码应该都是位置无关码,甚至bl copy_fram_nand都是位置无关的因此都可以正确执行。

ldr r5, =0x0000ffff
mcr p15, 0, r5, c3, c0, 0@load domain access register

这里使能域访问。关于协处理器编程的方法请参考协处理器编程

/* Set the TTB register */
ldr r0, _mmu_table_base
ldr r1, =CFG_PHY_UBOOT_BASE
ldr r2, =0xfff00000
bic r0, r0, r2 /*MMU表地址高位清零*/
orr r1, r0, r1/*uboot物理加载地址的 与MMU地址低字节相或,得到0x33exxxxx,及mmu_table的地址*/
mcr p15, 0, r1, c2, c0, 0    /*将r1存入CP15*/

这里将MMU映射表所在基址转换成物理地址,存入TTB寄存器中。考虑到之前dnw下载的那段初始程序(以下简写为usb_dnw_init),这里我也有点疑惑,当执行usb_dnw_init后,dnw就能在0x23e00000处下载uboot了,到底usb_dnw_init有没有做MMU的工作呢。

当我写到这里,发现已经有前辈分析过210的uboot了。可以看看:这里

但是网友没有对MMU机制进行分析,我这里说明一下,

可参考《S3C6410之uboot回炉再造(3)》这篇文章。

#ifdef CONFIG_ENABLE_MMU#ifdef CONFIG_MCP_SINGLE
/** MMU Table for SMDKC110* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF VA = PA* 0xC000_0000 -- 0xC7FF_FFFF => A:0x3000_0000 -- 0x37FF_FFFF 128M* 0xC800_0000 -- 0xDFFF_FFFF => Not Allowed* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF VA = PA*//* form a first-level section entry */
.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			//对应虚拟地址0 ~ 256MFL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr// Not Allowed.rept 0x200 - 0x100	//对应虚拟地址256M ~ 512M.word 0x00000000.endr.set __base,0x200// should be accessed.rept 0x600 - 0x200//对应虚拟地址512M ~ 1.5GFL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr.rept 0x800 - 0x600//对应虚拟地址1.5G ~ 2G.word 0x00000000.endr.set __base,0x800// should be accessed.rept 0xb00 - 0x800//对应虚拟地址2 ~ 2.75GFL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr/*	.rept 0xc00 - 0xb00.word 0x00000000.endr */.set __base,0xB00.rept 0xc00 - 0xb00//对应虚拟地址2.75G ~ 3G 256MBFL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr.set __base,0x300// 256MB for SDRAM with cacheable.rept 0xD00 - 0xC00//对应虚拟地址3G ~ 3.25G, 256MBFL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr// access is not allowed.@.rept 0xD00 - 0xC80//对应虚拟地址3G ~ 3.125G,128MB@.word 0x00000000@.endr.set __base,0xD00// 1:1 mapping for debugging with non-cacheable.rept 0x1000 - 0xD00//对应虚拟地址3.125G ~ 4G, 768MBFL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr	#else	// CONFIG_MCP_AC, CONFIG_MCP_H, CONFIG_MCP_B


经过MMU映射后,0xc000 0000~0xcfff ffff映射到了物理内存0x3000 0000 ~ 0x4FFF FFFF中,这样uboot就能通过dnw下载运行了。


http://www.ppmy.cn/news/157317.html

相关文章

三星系列NXP系列核心板设计研发-迅为嵌入式ARM方案提供商

多种核心板平台&#xff0c;从硬件原型设计、layout、硬件驱动&#xff0c;操作系统移植、中间到上层应用等方面。 三星系列核心板&#xff1a; 1. SCP-4412核心板 三星Exynos4412 四核 Cortex-A9 主频为1.4GHz-1.6GHz 内存&#xff1a;1GB/2GB DDR3 存储:8GB/16GB EMMC 2…

PEX高效装机

一、PXE概述 PXE(预启动执行环境)是由Inter公司开发的网络引导技术&#xff0c;工作在Client/Server模式&#xff0c;允许客户机通过网络从远程服务器下载引导镜像&#xff0c;并加载安装文件或整个操作系统。 二、PXE的优点 规模化&#xff1a;同时装配多台服务器 自动化&a…

盘点6款装机必备软件

整合网友们的评价&#xff0c;再经过自己的层层筛选后&#xff0c;我选出了5款打工人必备的办公软件&#xff0c;一起来看看&#xff1a; ▲IDM&#xff1a;提升网页下载速度 特点&#xff1a;无广告多线程下载 据说是可以下载网站一切的逆天神器。它会自动识别网页上的所有内…

科研用深度学习+有限元工作站的DIY装机配置(预算:5-6万)

科研用深度学习有限元工作站的DIY装机配置&#xff08;预算&#xff1a;5-6万&#xff09; 考虑实验室科研常用软件&#xff0c;尝试购置一台科研用深度学习有限元工作站&#xff0c;预算5-6万。 查找了目前市面上相关的整机产品&#xff1a; 1、例如 Dell 7920&#xff0c;GP…

深入理解Java虚拟机:JVM高级特性与最佳实践

深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践 一、简介二、JVM类加载子系统1. 类加载的过程2. 类加载器3. 双亲委派模型 三、内存管理与垃圾回收1. 内存模型2. 堆内存管理4. GC工具 四、JVM运行时数据区1. 程序计数器2. 虚拟机栈3. 本地方法栈4. Java堆5. 方法区 五、…

三星系列机型 刷机的一些基本常识

三星系列机型刷机资源也比较丰富。今天来给简单说下三星系列机型常见的刷机常识也相关选项说明 上图就是三星机型常见的线刷界面 .他的各自选项基本意思为 CURRENT BINARY&#xff1a;samsung official 当前的二进制&#xff1a;三星官方 说明&#xff1a;如果是三方系统&…

PS修图台式机装机方案

Photoshop官网要求说明&#xff1a; Photoshop 系统要求 您的计算机必须符合下面列出的最低技术规范&#xff0c;才能运行和使用 Photoshop。 适用于 2021 年 10 月版&#xff08;23.0 版&#xff09;及更高版本重要&#xff01;处理器和显卡的 Photoshop 硬件要求在 23.x 版中…

揭开三星手机CPU的神秘面纱

三星手机之所以在短短几年时间内&#xff0c;能够超越诺基亚成为全球市场份额最高的品牌&#xff0c;很大程度上还得归功于三星手机处理器的出色性能表现&#xff0c;本文将为大家细致解析包括蜂鸟、猎户座等广为人知的三星手机处理器。 网易手机原创稿件&#xff0c;转载请注明…