memsetup()函数写成与位置无关的代码的疑问

xiaobao 2013-07-15 11:26:05
嵌入式Linux应用开发完全手册
.text
.global _start
_start:
ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
bl memsetup @ 设置存储控制器以使用SDRAM
bl copy_2th_to_sdram @ 将第二部分代码复制到SDRAM
bl create_page_table @ 设置页表
bl mmu_init @ 启动MMU
ldr sp, =0xB4000000 @ 重设栈指针,指向SDRAM顶端(使用虚拟地址)
ldr pc, =0xB0004000 @ 跳到SDRAM中继续执行第二部分代码
halt_loop:
b halt_loop

/*
* 设置存储控制器以使用SDRAM,该程序用链接地址为0x30000000(sdram开始地址)
*/
void memsetup(void)
{
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;

/* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值
* 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到
* SDRAM之前就可以在steppingstone中运行
*/
/* 存储控制器13个寄存器的值 */
p[0] = 0x22011110; //BWSCON
p[1] = 0x00000700; //BANKCON0
p[2] = 0x00000700; //BANKCON1
p[3] = 0x00000700; //BANKCON2
p[4] = 0x00000700; //BANKCON3
p[5] = 0x00000700; //BANKCON4
p[6] = 0x00000700; //BANKCON5
p[7] = 0x00018005; //BANKCON6
p[8] = 0x00018005; //BANKCON7

/* REFRESH,
* HCLK=12MHz: 0x008C07A3,
* HCLK=100MHz: 0x008C04F4
*/
p[9] = 0x008C04F4;
p[10] = 0x000000B1; //BANKSIZE
p[11] = 0x00000030; //MRSRB6
p[12] = 0x00000030; //MRSRB7
}
对应反汇编
30000104 <memsetup>:
30000104: e52de004 str lr, [sp, #-4]!
30000108: e3a01422 mov r1, #570425344 ; 0x22000000
3000010c: e3a0c723 mov ip, #9175040 ; 0x8c0000
30000110: e2811a11 add r1, r1, #69632 ; 0x11000
30000114: e3a03312 mov r3, #1207959552 ; 0x48000000
30000118: e3a02c07 mov r2, #1792 ; 0x700
3000011c: e28cce4f add ip, ip, #1264 ; 0x4f0
30000120: e3a00906 mov r0, #98304 ; 0x18000
30000124: e2811e11 add r1, r1, #272 ; 0x110
30000128: e2800005 add r0, r0, #5 ; 0x5
3000012c: e3a0e030 mov lr, #48 ; 0x30
30000130: e5831000 str r1, [r3]
30000134: e28cc004 add ip, ip, #4 ; 0x4
30000138: e5832004 str r2, [r3, #4]
3000013c: e5832008 str r2, [r3, #8]
30000140: e583200c str r2, [r3, #12]
30000144: e5832010 str r2, [r3, #16]
30000148: e5832014 str r2, [r3, #20]
3000014c: e5832018 str r2, [r3, #24]
30000150: e3a020b1 mov r2, #177 ; 0xb1
30000154: e583001c str r0, [r3, #28]
30000158: e5830020 str r0, [r3, #32]
3000015c: e583c024 str ip, [r3, #36]
30000160: e5832028 str r2, [r3, #40]
30000164: e583e02c str lr, [r3, #44]
30000168: e583e030 str lr, [r3, #48]
3000016c: e49df004 ldr pc, [sp], #4


位置有关的代码
/*
* 设置存储控制器以使用SDRAM,该程序用链接地址为0x0
*/
void memsetup(void)
{
/* SDRAM 13个寄存器的值 */
unsigned long const mem_cfg_val[]={ 0x22011110, //BWSCON
0x00000700, //BANKCON0
0x00000700, //BANKCON1
0x00000700, //BANKCON2
0x00000700, //BANKCON3
0x00000700, //BANKCON4
0x00000700, //BANKCON5
0x00018005, //BANKCON6
0x00018005, //BANKCON7
0x008C07A3, //REFRESH
0x000000B1, //BANKSIZE
0x00000030, //MRSRB6
0x00000030, //MRSRB7
};
int i = 0;
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
for(; i < 13; i++)
p[i] = mem_cfg_val[i];
}
对应反汇编
00000038 <memsetup>:
38: e92d40f0 stmdb sp!, {r4, r5, r6, r7, lr}
3c: e59fc054 ldr ip, [pc, #84] ; 98 <firtst+0x98>
40: e1a0400c mov r4, ip
44: e8b4000f ldmia r4!, {r0, r1, r2, r3}
48: e3a05000 mov r5, #0 ; 0x0
4c: e3a07312 mov r7, #1207959552 ; 0x48000000
50: e24dd034 sub sp, sp, #52 ; 0x34
54: e1a0e00d mov lr, sp
58: e8ae000f stmia lr!, {r0, r1, r2, r3}
5c: e8b4000f ldmia r4!, {r0, r1, r2, r3}
60: e28d6034 add r6, sp, #52 ; 0x34
64: e8ae000f stmia lr!, {r0, r1, r2, r3}
68: e8b4000f ldmia r4!, {r0, r1, r2, r3}
6c: e594c000 ldr ip, [r4]
70: e8ae000f stmia lr!, {r0, r1, r2, r3}
74: e58ec000 str ip, [lr]
78: e5163034 ldr r3, [r6, #-52]
7c: e7873105 str r3, [r7, r5, lsl #2]
80: e2855001 add r5, r5, #1 ; 0x1
84: e355000c cmp r5, #12 ; 0xc
88: e2866004 add r6, r6, #4 ; 0x4
8c: dafffff9 ble 78 <memsetup+0x40>
90: e28dd034 add sp, sp, #52 ; 0x34
94: e8bd80f0 ldmia sp!, {r4, r5, r6, r7, pc}
98: 00000168 andeq r0, r0, r8, ror #2

这个二个memsetup()函数怎么看出与位置无关了?
...全文
253 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
浙妞 2013-08-11
  • 打赏
  • 举报
回复
请问楼主知道答案了吗,能告诉我吗?我也搞不懂这块。谢谢!

21,600

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧