这两个概念有联系又有区别:
1.copyFromSDtoDDR讲的是booloader代码从sd卡(49扇区,32K大小)拷贝到内存23e00000处
需要修改的地方有
A)link.lds
SECTIONS
{
. = 0x23E00000; (代码将来要运行的位置)
.text : {
start.o
sdram_init.o
* (.text)
}
.data : {
* (.data)
}
bss_start = .;
.bss : {
* (.bss)
}
bss_end = .;
B)start.S
#define WTCON 0xE2700000
#define SVC_STACK 0xd0037d80
#define IRQ_STACK 0xd0037f80
#define CR_V (1<<13)
.global IRQ_handle
.global _start
_start:
//
mrs r0, cpsr
bic r0 ,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
// 关wtg
ldr r0, =WTCON
ldr r1, =0x0
str r1, [r0]
bl disable_interrupt
bl disable_mmu
ldr sp, =SVC_STACK
//icache
mrc p15,0,r0,c1,c0,0;
//bic r0, r0, #(1<<12)
orr r0, r0, #(1<<12)
mcr p15,0,r0,c1,c0,0;
// init
bl clock_init
bl buzzer_init
bl sdram_asm_init
//mov r0, #1
//swi 1
// ldr r0 ,=0x12345
// ldr r1 ,=0x20000080
// str r0,[r1]
// bl stack_init
//比较是否在内存,必须的,因为代码会运行两次,第一次在isam,第二次在DDR
adr r0, _start
ldr r1, =_start
ldr r2, =bss_start
cmp r0, r1
beq clean_bss
bl copy_bl2_2_ddr //只运行在sram一次,之后在内存时,直接跳到clean_bss
/*这里不需要代码搬移,因为不是重定位,拷贝到内存直接运行就是
copy_loop:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bne copy_loop
*/
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1
beq run_on_dram
mov r2, #0
clear_loop:
str r2, [r0], #4
cmp r0, r1
bne clear_loop
run_on_dram:
//ldr r0,=fmt
//mov r1, #8
//bl printf
ldr pc, =main //在 copy_bl2_2_ddr之后,只运行在sram一次
C)sd_relocate.c
void copy_bl2_2_ddr(void)
{ void (*BL2)(void);
pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)(*(unsigned int *)(0xD0037F98));
p1(2, SD_START_BLOCK, SD_BLOCK_CNT, (unsigned int *)DDR_START_ADDR, 0);
//必须注释掉,不同于朱老师教程,因为他是用BL1/BL2,用p2();是为了跳转到BL2的第一 句 ldr pc ,=main
//pBL2Type p2 = (pBL2Type)DDR_START_ADDR;
//p2();
led3();
delay();
}
2.重定位讲的是代码搬运到新位置,可以不重定位,在uboot中是从sd卡拷贝到内存后,又在内存中重定位,目的是避免和内核位置冲突。而朱老师视频sdram_relocate中示例是讲的从sram到DDR(1.5.9.代码重定位实战2_1.5.SDRAM和重定位relocate-ARM裸机第五部分_其他视频-51CTO学堂)中,并且拆分为两阶段,而且加载地址不一样
代码地址:
news5pv210/noOS/sdtoddr at master · jimingkang/news5pv210 · GitHub