uboot

从零开始进行官方uboot移植到x210(cpu:s5pv210)

@从零开始进行官方uboot移植到x210(cpu:s5pv210)


以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除

前言

在前面进行了一系列对于uboot中各个文件夹,还有各个文件中参数的设置,在此进行零基础从零开始对uboot进行移植


一、前期准备

1.在官网下载了一个全新的uboot后,解压得到这个是解压得到的文件包
2.由于一个uboot中适配了很多其他开发板,我们需要对其他无关的内容进行删除,这里得先从中找到我们的cpu,并且把其他无关的给删除了
在这里插入图片描述
这里便是我们的cpu,对应为s5pc110
在这里插入图片描述
在删除了除了arm架构以外的文件夹后,我们需要进入arm,发现里面很多对应于arm不同的架构,因此我们得判断我们使用的cpu是具体属于什么架构的,我们在mkconfig脚本中会创建很多符号链接,通过这些符号链接去寻找对应的文件目录,我们之前的makefile中就有对这里直接进行配置,但是我们现在换了,将这个makefile中配置的文件进行分离,组成了boards.cfg文件,所以我们可以去这个文件找到我们的cpu对应的架构,我们的想移植的是s5p_goni,因此这里我们的具体架构是armv7,因此可以把arm文件夹中其他无关的给删了

在这里插入图片描述
在这里插入图片描述
在进入armv7后发现了很多其他不同的cpu,所以我们进行也把其他无关的给删除了
在这里插入图片描述
返回上级目录中,include目录底下也有许多无关的文件,除了我们要的其他也一并删除
在这里插入图片描述
3.除了把cpu无关的一并删除外,还需要对其他无关板子进行删除,但是由于uboot官方没有对我们使用的x210进行单独的适配,所以我们以相似度比较高的s5p_goni进行移植,因此删除除了s5_goni外的板子文件夹
在这里插入图片描述
在这里插入图片描述
4.最后通过sourceinsight,将剩下的所有文件一并读取到这里面的新工程中,可以发现,由于我们删除了其他无关的,所以这里我们找文件方便了许多,少了很多其他板子重复的函数文件
在这里插入图片描述
5.在主目录include下的config配置文件中,删除与我们板子无关的配置文件
在这里插入图片描述

二、移植前分析

1.Makefile与mkconfig脚本分析

Makefile中给mkconfig脚本传参$1= -A ,$2 = $(@:_config=)

%_config::	unconfig				//这里的%是万能匹配符,我们到时候在命令行中输入make xxx_config后,会被下面的$(@:_config=)引用
	@$(MKCONFIG) -A $(@:_config=)	//这里传参$(@:_config=)实际上传的是xxx,后面的_config被替换了

mkconfig脚本中,先对boards.cfg进行进行解析,通过$2去到boards.cfg中对进行查找到对应的开发板,这里$2便是s5p_goni

if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
	# Automatic mode
	line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' boards.cfg`
	if [ -z "$line" ] ; then
		echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
		exit 1
	fi

	set ${line}
	# add default board name if needed
	[ $# = 3 ] && set ${line} ${1}
fi

在这里插入图片描述
解析完上面后,会在mkconfig脚本中对我们我们的S$1-$8重新进行赋值
在这里插入图片描述

我们在linux底下命令行中,对整个uboot进行配置make s5_goni_config,后会输出什么就是在mkconfig脚本下面代码实现的

if [ "$options" ] ; then
	echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
	echo "Configuring for ${BOARD_NAME} board..."//显然我们实现的是这里
fi

mkconfig脚本中还创建了许多符号链接

if [ "$SRCTREE" != "$OBJTREE" ] ; then				//这里判断的是我们实现的是否为静默编译
	mkdir -p ${OBJTREE}/include
	mkdir -p ${OBJTREE}/include2
	cd ${OBJTREE}/include2
	rm -f asm
	ln -s ${SRCTREE}/arch/${arch}/include/asm asm
	LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
	cd ../include
	mkdir -p asm
else												//我们在主目录(进入uboot后的第一个目录)下的include目录中,创建一个符号链接,这个符号
	cd ./include									//这个符号链接指向了我们的主目录/arch/arm/include/asm
	rm -f asm
	ln -s ../arch/${arch}/include/asm asm
fi


这里举例创建的符号的链接,这些符号链接只有在配置时,才会生成
在这里插入图片描述

最后创建一个config.h文件

# Create board specific header file
#
if [ "$APPEND" = "yes" ]	# Append to existing config file
then
	echo >> config.h
else
	> config.h		# Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h

for i in ${TARGETS} ; do
	i="`echo ${i} | sed '/=/ {s/=/	/;q; } ; { s/$/	1/; }'`"
	echo "#define CONFIG_${i}" >>config.h ;
done

echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h
echo "#define CONFIG_SYS_CPU   \"${cpu}\""   >> config.h
echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h

[ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h

[ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    \"${soc}\""    >> config.h

生成的config.h在主目录的include中,里面的内容也是由上面代码生成的,分别定义一些宏还有头文件的包含,在以后的很多文件中都可以看到这些
在这里插入图片描述

从这里开始我们就可以进行
make distclean
make s5p_goni_config
make
来产生u-boot.bin文件
在这里插入图片描述

sd_fusing分析

echo "BL1 fusing"
./mkbl1 ../u-boot.bin SD-bl1-8k.bin 8192								//执行mkbl1,这将我们上面生成的
dd iflag=dsync oflag=dsync if=SD-bl1-8k.bin of=$1 seek=$bl1_position	//u-boot.bin,截取8192字节(8k)
rm SD-bl1-8k.bin														//生成SD-bl1-8k.bin文件

而我们的这个mkbl1是由sd_fusing中C110-EVT1-mkbl1.c文件生成的,这个文件会计算校验和(16字节)并且填充到我们的uboot中去,所以我们在start.S中需要在最开始定义出16字节占位,然后面的有关uboot内容能够往后挪一下,这样才可以使得我们的校验和成功通过
在这里插入图片描述

在start.S中添加16字节进行占位
在这里插入图片描述

2.start.S分析


#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#include <asm/system.h>
#include <linux/linkage.h>

.globl _start


	.word 0x2000	//前面说的16字节占位
	.word 0x0
	.word 0x0
	.word 0x0

_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
#ifdef CONFIG_SPL_BUILD
_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
_pad:			.word 0x12345678 /* now 16*4=64 */
#else
_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
_pad:			.word 0x12345678 /* now 16*4=64 */
#endif	/* CONFIG_SPL_BUILD */

.global _end_vect
_end_vect:

	.balignl 16,0xdeadbeef		//16字节对齐
*************************************************************************
 


.globl _TEXT_BASE			//这个函数里面定义了CONFIG_SPL_TEXT_BASE这个宏定义,这个宏定义定义了我们uboot的
_TEXT_BASE:					//链接地址
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
	.word	CONFIG_SPL_TEXT_BASE
#else
	.word	CONFIG_SYS_TEXT_BASE
#endif

/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start_ofs			//这里是一堆符号的声明
_bss_start_ofs:
	.word __bss_start - _start

.globl _bss_end_ofs
_bss_end_ofs:
	.word __bss_end - _start

.globl _end_ofs
_end_ofs:
	.word _end - _start

#ifdef 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

/* IRQ stack memory (calculated at run-time) + 8 bytes */
.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
	.word	0x0badc0de

/*
 * the actual reset code				//真正的复位代码,我们复位后执行的就是这里的代码
 */

reset:		
	bl	save_boot_params				//这里调用了stars.S中的一个空函数,没什么用,留给我们自行添加
	/*
	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
	 * except if in HYP mode already
	 */
	mrs	r0, cpsr						//这里设置cpu为svc模式,禁止fiq和irq
	and	r1, r0, #0x1f		@ mask mode bits
	teq	r1, #0x1a		@ test for HYP mode
	bicne	r0, r0, #0x1f		@ clear all mode bits
	orrne	r0, r0, #0x13		@ set SVC mode
	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
	msr	cpsr,r0

/*
 * Setup vector://与我们开发板无关,不用搭理
 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
 * Continue to use ROM code vector only in OMAP4 spl)
 */
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
	/* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTRL Register
	bic	r0, #CR_V		@ V = 0
	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTRL Register

	/* Set vector address in CP15 VBAR register */
	ldr	r0, =_start
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
#endif

	/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT				//这两个函数的定义也在start.S函数中,函数1设置,mmu和cache
	bl	cpu_init_cp15							//这个uboot不用mmu,这里直接禁止,后面也不会用到
	bl	cpu_init_crit							//函数2跳转到了lowlevel.init函数,这个函数存在于
#endif											//board/samsung/goni中,不在arch/arm/cpu/armv7中																			
												//这个判断可以在两个文件夹中的makefile中看有没有包含
												//或者可以查看的编译出的这两个文件夹中,有没有编译出.o文件
												//函数2实现的是时钟设置、串口设置、复位状态,是s5pc100和
												s5pc110公用的,这个函数在lowlevel_init.S中,实现:关看门狗、
												初始化串口,有定义了时钟初始化函数但是没有用,因为irom中已经对
												时钟进行了初始化,这里便没有再次使用
	
	bl _main                               		//这个函数在arch/arm/lib/crt0.S中
------------------------------------------------------------------------------

ENTRY(c_runtime_cpu_setup)
/*
 * If I-cache is enabled invalidate it
 */
#ifndef CONFIG_SYS_ICACHE_OFF
	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
	mcr     p15, 0, r0, c7, c10, 4	@ DSB
	mcr     p15, 0, r0, c7, c5, 4	@ ISB
#endif
/*
 * Move vector table
 */
	/* Set vector address in CP15 VBAR register */
	ldr     r0, =_start
	mcr     p15, 0, r0, c12, c0, 0  @Set VBAR

	bx	lr

ENDPROC(c_runtime_cpu_setup)



ENTRY(save_boot_params)
	bx	lr			@ back to my caller
ENDPROC(save_boot_params)
	.weak	save_boot_params

/*************************************************************************
 *
 * cpu_init_cp15
 *
 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
 * CONFIG_SYS_ICACHE_OFF is defined.
 *
 *************************************************************************/
ENTRY(cpu_init_cp15)
	/*
	 * 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
	mcr	p15, 0, r0, c7, c5, 6	@ invalidate BP array
	mcr     p15, 0, r0, c7, c10, 4	@ DSB
	mcr     p15, 0, r0, c7, c5, 4	@ ISB

	/*
	 * 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 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
#else
	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
#endif
	mcr	p15, 0, r0, c1, c0, 0

#ifdef CONFIG_ARM_ERRATA_716044
	mrc	p15, 0, r0, c1, c0, 0	@ read system control register
	orr	r0, r0, #1 << 11	@ set bit #11
	mcr	p15, 0, r0, c1, c0, 0	@ write system control register
#endif

#ifdef CONFIG_ARM_ERRATA_742230
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 4		@ set bit #4
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_743622
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 6		@ set bit #6
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_751472
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 11	@ set bit #11
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

	mov	pc, lr			@ back to my caller
ENDPROC(cpu_init_cp15)

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************/
ENTRY(cpu_init_crit)
	/*
	 * Jump to board specific initialization...
	 * The Mask ROM will have already initialized
	 * basic memory. Go here to bump up clock rate and handle
	 * wake up conditions.
	 */
	b	lowlevel_init		@ go setup pll,mux,memory		//这里就跳转到了lowlevel_init.S文件中,在里面进行初
															//始化,所以这里相当于uboot第一阶段的入口
ENDPROC(cpu_init_crit)
#endif

#ifndef CONFIG_SPL_BUILD
/*
 *************************************************************************
 *
 * 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
	sub	sp, sp, #S_FRAME_SIZE		@ carve out a frame on current
						@ user stack
	stmia	sp, {r0 - r12}			@ Save user registers (now in
						@ svc mode) r0-r12
	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort
						@ stack
	ldmia	r2, {r2 - r3}			@ get values for "aborted" pc
						@ and cpsr (into parm regs)
	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
	add	r8, sp, #S_PC			@ !! R8 NEEDS to be saved !!
						@ a reserved stack spot would
						@ be good.
	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

	.macro get_bad_stack
	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter
						@ in banked mode)

	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

	.macro get_bad_stack_swi
	sub	r13, r13, #4			@ space on current stack for
						@ scratch reg.
	str	r0, [r13]			@ save R0's value.
	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
						@ spots for abort stack
	str	lr, [r0]			@ save caller lr in position 0
						@ of saved stack
	mrs	lr, spsr			@ get the spsr
	str	lr, [r0, #4]			@ save spsr in position 1 of
						@ saved stack
	ldr	lr, [r0]			@ restore lr
	ldr	r0, [r13]			@ restore r0
	add	r13, r13, #4			@ pop stack entry
	.endm

	.macro get_irq_stack			@ setup IRQ stack
	ldr	sp, IRQ_STACK_START
	.endm

	.macro get_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_swi
	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 effective 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 /* CONFIG_USE_IRQ */
#endif /* CONFIG_SPL_BUILD */

3.lowlevel_init.S文件分析

	.globl lowlevel_init
lowlevel_init:
	mov	r11, lr

	/* r5 has always zero */
	mov	r5, #0

	ldr	r7, =S5PC100_GPIO_BASE
	ldr	r8, =S5PC100_GPIO_BASE
	/* Read CPU ID */
	ldr	r2, =S5PC110_PRO_ID
	ldr	r0, [r2]
	mov	r1, #0x00010000
	and	r0, r0, r1
	cmp	r0, r5
	beq	100f
	ldr	r8, =S5PC110_GPIO_BASE
100:
	/* Turn on KEY_LED_ON [GPJ4(1)] XMSMWEN */
	cmp	r7, r8
	beq	skip_check_didle			@ Support C110 only

	ldr	r0, =S5PC110_RST_STAT
	ldr	r1, [r0]
	and	r1, r1, #0x000D0000
	cmp	r1, #(0x1 << 19)			@ DEEPIDLE_WAKEUP
	beq	didle_wakeup
	cmp	r7, r8

skip_check_didle:
	addeq	r0, r8, #0x280				@ S5PC100_GPIO_J4
	addne	r0, r8, #0x2C0				@ S5PC110_GPIO_J4
	ldr	r1, [r0, #0x0]				@ GPIO_CON_OFFSET
	bic	r1, r1, #(0xf << 4)			@ 1 * 4-bit
	orr	r1, r1, #(0x1 << 4)
	str	r1, [r0, #0x0]				@ GPIO_CON_OFFSET

	ldr	r1, [r0, #0x4]				@ GPIO_DAT_OFFSET
	bic	r1, r1, #(1 << 1)
	str	r1, [r0, #0x4]				@ GPIO_DAT_OFFSET

	
	beq	100f

	/*
	 * Initialize Async Register Setting for EVT1
	 * Because we are setting EVT1 as the default value of EVT0,
	 * setting EVT0 as well does not make things worse.
	 * Thus, for the simplicity, we set for EVT0, too
	 *
	 * The "Async Registers" are:
	 *	0xE0F0_0000
	 *	0xE1F0_0000
	 *	0xF180_0000
	 *	0xF190_0000
	 *	0xF1A0_0000
	 *	0xF1B0_0000
	 *	0xF1C0_0000
	 *	0xF1D0_0000
	 *	0xF1E0_0000
	 *	0xF1F0_0000
	 *	0xFAF0_0000
	 */
	ldr     r0, =0xe0f00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xe1f00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1800000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1900000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1a00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1b00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1c00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1d00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1e00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1f00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xfaf00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	/*
	 * Diable ABB block to reduce sleep current at low temperature
	 * Note that it's hidden register setup don't modify it
	 */
	ldr	r0, =0xE010C300
	ldr	r1, =0x00800000
	str	r1, [r0]

100:
	/* IO retension release */
	ldreq	r0, =S5PC100_OTHERS			@ 0xE0108200
	ldrne	r0, =S5PC110_OTHERS			@ 0xE010E000
	ldr	r1, [r0]
	ldreq	r2, =(1 << 31)				@ IO_RET_REL
	ldrne	r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28))
	orr	r1, r1, r2
	/* Do not release retention here for S5PC110 */
	streq	r1, [r0]

	/* Disable Watchdog */									//关看门狗
	ldreq	r0, =S5PC100_WATCHDOG_BASE		@ 0xEA200000
	ldrne	r0, =S5PC110_WATCHDOG_BASE		@ 0xE2700000
	str	r5, [r0]

	ldr r0, =0xE010E81C										//我们自己添加的开发板置锁
	ldr r1, =0x301
	str r1, [r0]
	
	/* setting SRAM */
	ldreq	r0, =S5PC100_SROMC_BASE
	ldrne	r0, =S5PC110_SROMC_BASE
	ldr	r1, =0x9
	str	r1, [r0]

	/* S5PC100 has 3 groups of interrupt sources */
	ldreq	r0, =S5PC100_VIC0_BASE			@ 0xE4000000
	ldrne	r0, =S5PC110_VIC0_BASE			@ 0xF2000000
	add	r1, r0, #0x00100000
	add	r2, r0, #0x00200000

	/* Disable all interrupts (VIC0, VIC1 and VIC2) */
	mvn	r3, #0x0
	str	r3, [r0, #0x14]				@ INTENCLEAR
	str	r3, [r1, #0x14]				@ INTENCLEAR
	str	r3, [r2, #0x14]				@ INTENCLEAR

	/* Set all interrupts as IRQ */
	str	r5, [r0, #0xc]				@ INTSELECT
	str	r5, [r1, #0xc]				@ INTSELECT
	str	r5, [r2, #0xc]				@ INTSELECT

	/* Pending Interrupt Clear */
	str	r5, [r0, #0xf00]			@ INTADDRESS
	str	r5, [r1, #0xf00]			@ INTADDRESS
	str	r5, [r2, #0xf00]			@ INTADDRESS

	/* for UART */
	bl	uart_asm_init							//这里我们只初始化了串口的GPIO,没初始化寄存器,但是我们到这里还能
												输出的原因就是我们的irom中已经帮我们进行了初始化,所以我们才可以成
												功输出,事实上就算这里我们没有进行初始化依旧可以实现串口的输出

	bl	internal_ram_init

	cmp	r7, r8
	/* Clear wakeup status register */
	ldreq	r0, =S5PC100_WAKEUP_STAT
	ldrne	r0, =S5PC110_WAKEUP_STAT
	ldr	r1, [r0]
	str	r1, [r0]

	/* IO retension release */
	ldreq	r0, =S5PC100_OTHERS			@ 0xE0108200
	ldrne	r0, =S5PC110_OTHERS			@ 0xE010E000
	ldr	r1, [r0]
	ldreq	r2, =(1 << 31)				@ IO_RET_REL
	ldrne	r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28))
	orr	r1, r1, r2
	str	r1, [r0]

	b	1f

didle_wakeup:
	/* Wait when APLL is locked */
	ldr	r0, =0xE0100100			@ S5PC110_APLL_CON
lockloop:
	ldr	r1, [r0]
	and	r1, r1, #(1 << 29)
	cmp	r1, #(1 << 29)
	bne	lockloop

	ldr	r0, =S5PC110_INFORM0
	ldr	r1, [r0]
	mov	pc, r1
	nop
	nop
	nop
	nop
	nop

1:
	mov	lr, r11
	mov	pc, lr
	
/*
 * system_clock_init: Initialize core clock and bus clock.
 * void system_clock_init(void)
 */
system_clock_init:
	ldr	r0, =S5PC110_CLOCK_BASE		@ 0xE0100000

	/* Check S5PC100 */
	cmp	r7, r8
	bne	110f
100:
	/* Set Lock Time */
	ldr	r1, =0xe10			@ Locktime : 0xe10 = 3600
	str	r1, [r0, #0x000]		@ S5PC100_APLL_LOCK
	str	r1, [r0, #0x004]		@ S5PC100_MPLL_LOCK
	str	r1, [r0, #0x008]		@ S5PC100_EPLL_LOCK
	str	r1, [r0, #0x00C]		@ S5PC100_HPLL_LOCK

	/* S5P_APLL_CON */
	ldr	r1, =0x81bc0400		@ SDIV 0, PDIV 4, MDIV 444 (1333MHz)
	str	r1, [r0, #0x100]
	/* S5P_MPLL_CON */
	ldr	r1, =0x80590201		@ SDIV 1, PDIV 2, MDIV 89 (267MHz)
	str	r1, [r0, #0x104]
	/* S5P_EPLL_CON */
	ldr	r1, =0x80870303		@ SDIV 3, PDIV 3, MDIV 135 (67.5MHz)
	str	r1, [r0, #0x108]
	/* S5P_HPLL_CON */
	ldr	r1, =0x80600603		@ SDIV 3, PDIV 6, MDIV 96
	str	r1, [r0, #0x10C]

	ldr     r1, [r0, #0x300]
	ldr     r2, =0x00003fff
	bic     r1, r1, r2
	ldr     r2, =0x00011301

	orr	r1, r1, r2
	str	r1, [r0, #0x300]
	ldr     r1, [r0, #0x304]
	ldr     r2, =0x00011110
	orr     r1, r1, r2
	str     r1, [r0, #0x304]
	ldr     r1, =0x00000001
	str     r1, [r0, #0x308]

	/* Set Source Clock */
	ldr	r1, =0x00001111			@ A, M, E, HPLL Muxing
	str	r1, [r0, #0x200]		@ S5PC1XX_CLK_SRC0

	b	200f
110:
	ldr	r0, =0xE010C000			@ S5PC110_PWR_CFG

	/* Set OSC_FREQ value */
	ldr	r1, =0xf
	str	r1, [r0, #0x100]		@ S5PC110_OSC_FREQ

	/* Set MTC_STABLE value */
	ldr	r1, =0xffffffff
	str	r1, [r0, #0x110]		@ S5PC110_MTC_STABLE

	/* Set CLAMP_STABLE value */
	ldr	r1, =0x3ff03ff
	str	r1, [r0, #0x114]		@ S5PC110_CLAMP_STABLE

	ldr	r0, =S5PC110_CLOCK_BASE		@ 0xE0100000

	/* Set Clock divider */
	ldr	r1, =0x14131330			@ 1:1:4:4, 1:4:5
	str	r1, [r0, #0x300]
	ldr	r1, =0x11110111			@ UART[3210]: MMC[3210]
	str	r1, [r0, #0x310]

	/* Set Lock Time */
	ldr	r1, =0x2cf			@ Locktime : 30us
	str	r1, [r0, #0x000]		@ S5PC110_APLL_LOCK
	ldr	r1, =0xe10			@ Locktime : 0xe10 = 3600
	str	r1, [r0, #0x008]		@ S5PC110_MPLL_LOCK
	str	r1, [r0, #0x010]		@ S5PC110_EPLL_LOCK
	str	r1, [r0, #0x020]		@ S5PC110_VPLL_LOCK

	/* S5PC110_APLL_CON */
	ldr	r1, =0x80C80601			@ 800MHz
	str	r1, [r0, #0x100]
	/* S5PC110_MPLL_CON */
	ldr	r1, =0x829B0C01			@ 667MHz
	str	r1, [r0, #0x108]
	/* S5PC110_EPLL_CON */
	ldr	r1, =0x80600602			@  96MHz VSEL 0 P 6 M 96 S 2
	str	r1, [r0, #0x110]
	/* S5PC110_VPLL_CON */
	ldr	r1, =0x806C0603			@  54MHz
	str	r1, [r0, #0x120]

	/* Set Source Clock */
	ldr	r1, =0x10001111			@ A, M, E, VPLL Muxing
	str	r1, [r0, #0x200]		@ S5PC1XX_CLK_SRC0

	/* OneDRAM(DMC0) clock setting */
	ldr	r1, =0x01000000			@ ONEDRAM_SEL[25:24] 1 SCLKMPLL
	str	r1, [r0, #0x218]		@ S5PC110_CLK_SRC6
	ldr	r1, =0x30000000			@ ONEDRAM_RATIO[31:28] 3 + 1
	str	r1, [r0, #0x318]		@ S5PC110_CLK_DIV6

	/* XCLKOUT = XUSBXTI 24MHz */
	add	r2, r0, #0xE000			@ S5PC110_OTHERS
	ldr     r1, [r2]
	orr	r1, r1, #(0x3 << 8)		@ CLKOUT[9:8] 3 XUSBXTI
	str	r1, [r2]

	/* CLK_IP0 */
	ldr	r1, =0x8fefeeb			@ DMC[1:0] PDMA0[3] IMEM[5]
	str	r1, [r0, #0x460]		@ S5PC110_CLK_IP0

	/* CLK_IP1 */
	ldr	r1, =0xe9fdf0f9			@ FIMD[0] USBOTG[16]
						@ NANDXL[24]
	str	r1, [r0, #0x464]		@ S5PC110_CLK_IP1

	/* CLK_IP2 */
	ldr	r1, =0xf75f7fc			@ CORESIGHT[8] MODEM[9]
						@ HOSTIF[10] HSMMC0[16]
						@ HSMMC2[18] VIC[27:24]
	str	r1, [r0, #0x468]		@ S5PC110_CLK_IP2

	/* CLK_IP3 */
	ldr	r1, =0x8eff038c			@ I2C[8:6]
						@ SYSTIMER[16] UART0[17]
						@ UART1[18] UART2[19]
						@ UART3[20] WDT[22]
						@ PWM[23] GPIO[26] SYSCON[27]
	str	r1, [r0, #0x46c]		@ S5PC110_CLK_IP3

	/* CLK_IP4 */
	ldr	r1, =0xfffffff1			@ CHIP_ID[0] TZPC[8:5]
	str	r1, [r0, #0x470]		@ S5PC110_CLK_IP3

200:
	/* wait at least 200us to stablize all clock */
	mov	r2, #0x10000
1:	subs	r2, r2, #1
	bne	1b
	mov	pc, lr

internal_ram_init:
	ldreq	r0, =0xE3800000
	ldrne	r0, =0xF1500000
	ldr	r1, =0x0
	str	r1, [r0]

	mov	pc, lr

uart_asm_init:
	/* set GPIO to enable UART0-UART4 */
	mov	r0, r8
	ldr	r1, =0x22222222
	str	r1, [r0, #0x0]			@ S5PC100_GPIO_A0_OFFSET
	ldr	r1, =0x00002222
	str	r1, [r0, #0x20]			@ S5PC100_GPIO_A1_OFFSET

	/* Check S5PC100 */
	cmp	r7, r8
	bne	110f

	/* UART_SEL GPK0[5] at S5PC100 */
	add	r0, r8, #0x2A0			@ S5PC100_GPIO_K0_OFFSET
	ldr	r1, [r0, #0x0]			@ S5PC1XX_GPIO_CON_OFFSET
	bic	r1, r1, #(0xf << 20)		@ 20 = 5 * 4-bit
	orr	r1, r1, #(0x1 << 20)		@ Output
	str	r1, [r0, #0x0]			@ S5PC1XX_GPIO_CON_OFFSET

	ldr	r1, [r0, #0x8]			@ S5PC1XX_GPIO_PULL_OFFSET
	bic	r1, r1, #(0x3 << 10)		@ 10 = 5 * 2-bit
	orr	r1, r1, #(0x2 << 10)		@ Pull-up enabled
	str	r1, [r0, #0x8]			@ S5PC1XX_GPIO_PULL_OFFSET

	ldr	r1, [r0, #0x4]			@ S5PC1XX_GPIO_DAT_OFFSET
	orr	r1, r1, #(1 << 5)		@ 5 = 5 * 1-bit
	str	r1, [r0, #0x4]			@ S5PC1XX_GPIO_DAT_OFFSET

	b	200f
110:
	/*
	 * Note that the following address
	 * 0xE020'0360 is reserved address at S5PC100
	 */
	/* UART_SEL MP0_5[7] at S5PC110 */
	add	r0, r8, #0x360			@ S5PC110_GPIO_MP0_5_OFFSET
	ldr	r1, [r0, #0x0]			@ S5PC1XX_GPIO_CON_OFFSET
	bic	r1, r1, #(0xf << 28)		@ 28 = 7 * 4-bit
	orr	r1, r1, #(0x1 << 28)		@ Output
	str	r1, [r0, #0x0]			@ S5PC1XX_GPIO_CON_OFFSET

	ldr	r1, [r0, #0x8]			@ S5PC1XX_GPIO_PULL_OFFSET
	bic	r1, r1, #(0x3 << 14)		@ 14 = 7 * 2-bit
	orr	r1, r1, #(0x2 << 14)		@ Pull-up enabled
	str	r1, [r0, #0x8]			@ S5PC1XX_GPIO_PULL_OFFSET

	ldr	r1, [r0, #0x4]			@ S5PC1XX_GPIO_DAT_OFFSET
	orr	r1, r1, #(1 << 7)		@ 7 = 7 * 1-bit
	str	r1, [r0, #0x4]			@ S5PC1XX_GPIO_DAT_OFFSET
200:

	
	ldr r1, =0x4f4f4f4f							//这是自己加的打印一个字母‘O’,为了测试看前面的串口初始化是否成功
	ldr r2, =0xE2900820							//查数据手册,这个是串口二的地址
	str r1, [r2]							
	
	mov	pc, lr

	

另外,我们得避免重复将这个lowlevel_init.S文件重复编译

第一次这个在board\samsung\goni中的makefile编译时链接了一次,为了生成这个libgoni.o,所以这个libgoni.o中就链接了这个一次

第二次是arch\arm\cpu中的u-boot.lds中为了形成uboot进行连接时又重新连接了一次,因此会导致重复定义出错

在这里插入图片描述
解决方法
1.由于我们在makefile中链接了,而且我们要保证u-boot.lds中能够把我们的这个脚本放在前面,所以这个不能动,所以我们把makefile中的链接给删除了,这样生成的libgoni.o文件中就没有链接我们的lowlevel_init.o文件,但是这样导致了一个结果,由于我们把这东西给删了,导致我们makefile中没有生成lowlevel_init.o文件,也就导致了我们图二中我们想把这段放前面根本没有这个文件,同样出错。
2.解决方法:我们要成功在makefile中生成一个libgoni.o文件,同时不包含lowlevel_init.o文件,又同时能够保证我们这个lowlevel_init.o文件能够成功被生成,所以解决方法如下:
在这里插入图片描述
我们直接重新定义一个all目标,这个目标会依赖我们的LOW,这样我们的文件就可以成功得到编译生成对应.o文件

4.u-boot.lds文件分析

这个文件在arch\arm\cpu中,通过链接我们的脚本,形成uboot,但是我们的uboot要求把uboot的第一阶段的代码放在我们的前8k中,如果我们的没有声明如下这一句,那么将随机存放,不一定能够成功将我们第一阶段的代码成功放在前面,所以我们这里需要手动添加
在这里插入图片描述


5.crt0.S文件分析

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 */

#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
	ldr	sp, =(CONFIG_SPL_STACK)
#else
	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)						//设置栈,并且把sp指向ddr的栈地址
#endif
	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */
	sub	sp, #GD_SIZE	/* allocate one GD above SP */
	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */
	mov	r9, sp		/* GD is above SP */
	mov	r0, #0
	bl	board_init_f										//这里函数进行了板级的初始化,这个函数和board_init_r
															//共同构成了uboot的第二阶段,所以这个board_init_r
															应该是进入uboot的命令行,所以这里就算uboot第二阶段的
															函数入口

#if ! defined(CONFIG_SPL_BUILD)

/*
 * Set up intermediate environment (new sp and gd) and call
 * relocate_code(addr_moni). Trick here is that we'll return
 * 'here' but relocated.
 */

	ldr	sp, [r9, #GD_START_ADDR_SP]	/* sp = gd->start_addr_sp */
	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */
	ldr	r9, [r9, #GD_BD]		/* r9 = gd->bd */
	sub	r9, r9, #GD_SIZE		/* new GD is below bd */

	adr	lr, here
	ldr	r0, [r9, #GD_RELOC_OFF]		/* r0 = gd->reloc_off */
	add	lr, lr, r0
	ldr	r0, [r9, #GD_RELOCADDR]		/* r0 = gd->relocaddr */
	b	relocate_code
here:

/* Set up final (full) environment */

	bl	c_runtime_cpu_setup	/* we still call old routine here */

	ldr	r0, =__bss_start	/* this is auto-relocated! */
	ldr	r1, =__bss_end		/* this is auto-relocated! */

	mov	r2, #0x00000000		/* prepare zero to clear BSS */

clbss_l:cmp	r0, r1			/* while not at end of BSS */
	strlo	r2, [r0]		/* clear 32-bit BSS word */
	addlo	r0, r0, #4		/* move to next */
	blo	clbss_l

	bl coloured_LED_init
	bl red_led_on

	/* call board_init_r(gd_t *id, ulong dest_addr) */
	mov     r0, r9                  /* gd_t */
	ldr	r1, [r9, #GD_RELOCADDR]	/* dest_addr */
	/* call board_init_r */
	ldr	pc, =board_init_r	/* this is auto-relocated! */

	/* we should not return here. */

#endif

ENDPROC(_main)

三、移植

1.ddr初始化相关移植

现状:从start.S出发,遇到了uboot第一阶段初始函数cpu_init_crit,这个函数跳转到board\samsung\goni\lowlevel_init.S中的lowlevel.init函数中,而这个lowlevel.init函数就算具体实现第一阶段各种初始化:关看门狗,设置时钟等,但是还没有进行ddr初始化和重定位,执行完第一阶段后出来继续执行,到了_main函数,这个函数在arch\arm\lib\crt0.S 文件中,而第二阶段的入口就是_main 函数
问题:因为我们这个uboot中没有对ddr进行初始化,所以我们现在的目标:就是在整个start.S执行到_main之前完成ddr初始化和重定位,另外,如果我们原uboot如果带有ddr初始化,那是最好的,但是我们这个uboot中,没有对ddr进行任何的初始化,所以我们的安排:在之前移植的uboot中得到cpu_init.S文件,这个文件之前用于对我们的ddr进行初始化,所以我们利用这个完成ddr初始化,在start.S中完成重定位

1.将之前的uboot中进行了ddr初始化文件uboot/cpu/s5pc11x/s5pc110/cpu_init.S文件copy到\board\samsung\goni中,然后在makefile中修改(联系之前的lowlevel_init.S,避免重复链接)
在这里插入图片描述
在对应的makefile文件中添加,实现可以生成cpu_init.o文件但是又不会被这个makefile编译链接进去
在这里插入图片描述
在u-boot.lds文件实现最终链接,保证这能够在前8k中作为第一阶段

2.由于我们复制过来的文件cpu_init.S中头文件包含了
#include <config.h> //这个不用怕,我们通过/include/configs编译也有生成,这也解释了我们在后 面/include/configs/s5p_goni.h中添加那些ddr初始相关宏的时候,不用包含s5p_goni.h头文件。
#include <s5pc110.h> //这个没有我们也得去复制过来
在这里插入图片描述
从旧uboot主目录中的include文件夹中copy到新的uboot中主目录的include文件夹中即可

3.我们的cpu_init.S中还定义了很多来自旧uboot的宏,处理这些宏要么把条件编译的相关宏,然后再删除其中一个情况的代码,剩下直接执行我们想要的内容,要么把他的宏给copy过来,这里选择删除
在这里插入图片描述

4.将我们新加入的两个文件导入到source insight中,然后查看其中相关宏,这里的处理方法:看我们的宏有哪些需要哪些不需要,进行各种删除或者各种添加宏,这个cpu_init.S中要初始化ddr,缺少了在原uboot中的include/configs/smdkv210single.h中定义的宏,这里我们把这些宏copy到我们uboot中/include/configs/s5p_goni.h中

在这里插入图片描述

5.剩下就是我们之前移植的cpu_init.S中包含的一个头文件s5pc110.h,这个文件需要进行很多删改
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里是在我们的include/asm-arm/s5pc11x/中把里面的hardwawre.h中这个_reg这个宏定义给copy过来
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

6.最后编译成功后,进行我们的调试,现在我们在lowlevel_init.S中,调用我们移植的ddr初始化函数,原来我们在串口初始化函数中打印了一个字符O,现在我们在ddr初始化后打印一个K,如果到时候我们看到了一个OK,那就代表我们成功了
在这里插入图片描述

最终进行我们开发板验证,出现了OK,代表我们的代码成功!
在这里插入图片描述

2.重定位相关初始化移植

现状:我们已经完成了ddr相关的初始化,从lowlevel_init.S跳回我们的start.S,主函数,现在可以进行重定位
问题:1.我们重定位需要在ddr完成后,才可以进行ddr初始化,同时又得保证我们重定位需要第二阶段开始之前,而且完成了ddr初始化和重定位的这第一阶段的代码加起来不能超过8kb,
2.由于我们之前还没有进行重定位,所以我们函数跳转可以用bl位置无关码来进行,但是一旦我们实现了重定位,我们就应该使用位置有关码来进行跳转,所以这里的bl _main得变

1.改变我们的第二阶段跳转指令,将原本的位置无关码变成位置有关码ldr pc,__main
在这里插入图片描述

2.从我们之前移植的开发板中的start.S中将重定位代码copy过来
在这里插入图片描述
在这里插入图片描述

	ldr	sp, _TEXT_PHY_BASE	    setup temp stack pointer  这个宏追到底发现就算原uboot的链接起始地址,这里不一样
	sub	sp, sp, #12
	mov	fp, #0			                                   所以可以将上面的宏代替这个宏定义

在这里插入图片描述
这里因为就是我们到时候会把uboot烧写到sd卡,所以这里bil1从外部sd卡获取,如果我们烧写到其他介质,那么就选择跳转到相应函数去执行获取bl1
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
由于移植了movi.c那么就得分析movi.c中的各种文件包含,还有各种宏定义,看看我们是不是没进行移植
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.接下来进行编译,解决编译出现的错误
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结果编译正确,烧写进sd卡,然后开发板进行验证在这里插入图片描述

3.cpu时钟信息显示进行移植

现状:我们已经完成了代码的重定位,发现开发板运行成功串口输出了我们之前设置的OKA,而且还多了部分我们的开发板信息,但是这些信息是错误的,回到strat.S中就是到了这就表明我们在uboot第一阶段已经完成,可以开始进入第二阶段即进入_main函数,而这个函数在于crt0.S中,这个函数又调用了board.c中的board_init.c函数所以我们需要将这个东西配置好
问题:由于我们之前最开始进行的时钟配置是在irom中进行的,而我们时钟配置相关是在lowlevel_init.S中,由于我们没有调用这个函数,所以我们现在这里的时钟寄存器配置是在irom中的,但是这个irom中自己配置的不是按照我们相要的进行的,它配置成了800Mhz,所以我们要把在lowlevel_init.S中进行配置,并且重新lowlevel_init.S在中进行调用,才可以正确得到我们要的时钟。

在这里插入图片描述

4.board和ddr显示配置移植

现状:我们从start.S中进入了_main,从_main进入了crt0.S,再从crt0.S进入了board_init_f,再从board_init_f进入到board.c中,而这个board.c中这个board_init_f函数里面有一个init_sequence,这个是上面的大部分的初始化代码,
,然后执行完之后,这里并没有返回,所以会继续往下执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

到这里 board_init_f就已经完成了,接下来跳出来board.c返回到crt0.S,然后从这里跳到我们的board_init_r函数,y又进入board.c,然后从这里进行其他的配置初始化
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
goni.h中定义的宏的含义:就是说我们一旦定义了这个宏,那么我们就会去配置,即我们makefile中是否编译生成.o文件由这里的宏来确定,一旦定义了,那么就代表我们想makefile编译出我们想要的对应文件,由于这个东西是跟我们无关的,所以我们直接注释

4.sd_mmc驱动移植

现状:现在我们已经成功进入了命令行这里,我们处在board.c中的board_init_r函数中
问题:到这里后发现我们的sd卡还是没有办法读取,即我们读取sd卡的函数有问题需要解决

在这里插入图片描述

总结

提示:这里对文章进行总结:

1.在共享文件夹里面不能直接进行make 编译等操作,但是可以在windows下改变makefile,从而在linux下可以得到响应的改变,由于不知道是什么原因,排查了许久后将问题确定在了u-boot-2013.10\arch\arm\include\asm底下,应该是删除了一些不该删除的,导致了编译出现错误(问题解决:在我们的arch\arm\include\asm\下有一个目录arch-s5pc1xx不得删除,否则会提示出错)
在这里插入图片描述
2.在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值