【
思路:最好的方法是自己写两个.c的程序 1.一个程序调用另外一个.c程序里面函数,
2.编译好程序 3.用objdump -D看下反汇编,看看各个函数的地址,链接前后的地址编号。
例子:自己编译下文件“ \MINI2440源码\硬件部件实验代码\sdram”里面Makefile,make下看看
下面贴出代码:源文件有三个head.S leds.c Makefile
head.S:
@*************************************************************************
@ File:head.S
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@*************************************************************************
.equ MEM_CTL_BASE, 0x48000000
.equ SDRAM_BASE, 0x30000000
.text
.global _start
_start:
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
bl memsetup @ 设置存储控制器
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中继续执行
on_sdram:
ldr sp, =0x34000000 @ 设置堆栈
bl main
halt_loop:
b halt_loop
disable_watch_dog:
@ 往WATCHDOG寄存器写0即可
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
mov pc, lr @ 返回
copy_steppingstone_to_sdram:
@ 将Steppingstone的4K数据全部复制到SDRAM中去
@ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
mov r1, #0
ldr r2, =SDRAM_BASE
mov r3, #4*1024
1:
ldr r4, [r1],#4 @ 从Steppingstone读取4字节的数据,并让源地址加4
str r4, [r2],#4 @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
cmp r1, r3 @ 判断是否完成:源地址等于Steppingstone的未地址?
bne 1b @ 若没有复制完,继续
mov pc, lr @ 返回
memsetup:
@ 设置存储控制器以便使用SDRAM等外设
mov r1, #MEM_CTL_BASE @ 存储控制器的13个寄存器的开始地址
adrl r2, mem_cfg_val @ 这13个值的起始存储地址
add r3, r1, #52 @ 13*4 = 54
1:
ldr r4, [r2], #4 @ 读取设置值,并让r2加4
str r4, [r1], #4 @ 将此值写入寄存器,并让r1加4
cmp r1, r3 @ 判断是否设置完所有13个寄存器
bne 1b @ 若没有写成,继续
mov pc, lr @ 返回
.align 4
mem_cfg_val:
@ 存储控制器13个寄存器的设置值
.long 0x22011110 @ BWSCON
.long 0x00000700 @ BANKCON0
.long 0x00000700 @ BANKCON1
.long 0x00000700 @ BANKCON2
.long 0x00000700 @ BANKCON3
.long 0x00000700 @ BANKCON4
.long 0x00000700 @ BANKCON5
.long 0x00018005 @ BANKCON6
.long 0x00018005 @ BANKCON7
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE
.long 0x00000030 @ MRSRB6
.long 0x00000030 @ MRSRB7
leds.c
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
/*
* LED1,LED2,LED4对应GPB5、GPB6、GPB7、GPB8
*/
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(volatile unsigned long dly)
{
for(; dly > 0; dly--);
}
int main(void)
{
unsigned long i = 0;
// LED1,LED2,LED3,LED4对应的4根引脚设为输出
GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out;
while(1){
wait(30000);
GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1,2,3,4
if(++i == 16)
i = 0;
}
return 0;
}
Makefile
sdram.bin : head.S leds.c
arm-linux-gcc -c -o head.o head.S
arm-linux-gcc -c -o leds.o leds.c
arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
arm-linux-objcopy -O binary -S sdram_elf sdram.bin
arm-linux-objdump -D -m arm sdram_elf > sdram.dis
clean:
rm -f sdram.dis sdram.bin sdram_elf *.o
编译后head.o的ELF文件
head.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:
0: eb000005 bl 1c <disable_watch_dog>
4: eb000010 bl 4c <memsetup>
8: eb000007 bl 2c <copy_steppingstone_to_sdram>
c: e59ff090 ldr pc, [pc, #144] ; a4 <mem_cfg_val+0x34>
00000010 <on_sdram>:
10: e3a0d30d mov sp, #872415232 ; 0x34000000
14: ebfffffe bl 0 <main>
00000018 <halt_loop>:
18: eafffffe b 18 <halt_loop>
0000001c <disable_watch_dog>:
1c: e3a00453 mov r0, #1392508928 ; 0x53000000
20: e3a01000 mov r1, #0
24: e5801000 str r1, [r0]
28: e1a0f00e mov pc, lr
0000002c <copy_steppingstone_to_sdram>:
2c: e3a01000 mov r1, #0
30: e3a02203 mov r2, #805306368 ; 0x30000000
34: e3a03a01 mov r3, #4096 ; 0x1000
38: e4914004 ldr r4, [r1], #4
3c: e4824004 str r4, [r2], #4
40: e1510003 cmp r1, r3
44: 1afffffb bne 38 <copy_steppingstone_to_sdram+0xc>
48: e1a0f00e mov pc, lr
0000004c <memsetup>:
4c: e3a01312 mov r1, #1207959552 ; 0x48000000
50: e28f2018 add r2, pc, #24
54: e1a00000 nop ; (mov r0, r0)
58: e2813034 add r3, r1, #52 ; 0x34
5c: e4924004 ldr r4, [r2], #4
60: e4814004 str r4, [r1], #4
64: e1510003 cmp r1, r3
68: 1afffffb bne 5c <memsetup+0x10>
6c: e1a0f00e mov pc, lr
00000070 <mem_cfg_val>:
70: 22011110 andcs r1, r1, #4
74: 00000700 andeq r0, r0, r0, lsl #14
78: 00000700 andeq r0, r0, r0, lsl #14
7c: 00000700 andeq r0, r0, r0, lsl #14
80: 00000700 andeq r0, r0, r0, lsl #14
84: 00000700 andeq r0, r0, r0, lsl #14
88: 00000700 andeq r0, r0, r0, lsl #14
8c: 00018005 andeq r8, r1, r5
90: 00018005 andeq r8, r1, r5
94: 008c07a3 addeq r0, ip, r3, lsr #15
98: 000000b1 strheq r0, [r0], -r1
9c: 00000030 andeq r0, r0, r0, lsr r0
a0: 00000030 andeq r0, r0, r0, lsr r0
a4: 00000010 andeq r0, r0, r0, lsl r0
a8: e1a00000 nop ; (mov r0, r0)
ac: e1a00000 nop ; (mov r0, r0)
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00001941 andeq r1, r0, r1, asr #18
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 0000000f andeq r0, r0, pc
10: 00543405 subseq r3, r4, r5, lsl #8
14: 01080206 tsteq r8, r6, lsl #4
18: Address 0x00000018 is out of bounds.
leds.c的elf文件
leds.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <wait>:
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e24dd00c sub sp, sp, #12
c: e50b0008 str r0, [fp, #-8]
10: ea000002 b 20 <wait+0x20>
14: e51b3008 ldr r3, [fp, #-8]
18: e2433001 sub r3, r3, #1
1c: e50b3008 str r3, [fp, #-8]
20: e51b3008 ldr r3, [fp, #-8]
24: e3530000 cmp r3, #0
28: 1afffff9 bne 14 <wait+0x14>
2c: e28bd000 add sp, fp, #0
30: e8bd0800 pop {fp}
34: e12fff1e bx lr
00000038 <main>:
38: e92d4800 push {fp, lr}
3c: e28db004 add fp, sp, #4
40: e24dd008 sub sp, sp, #8
44: e3a03000 mov r3, #0
48: e50b3008 str r3, [fp, #-8]
4c: e59f304c ldr r3, [pc, #76] ; a0 <main+0x68>
50: e3a02b55 mov r2, #87040 ; 0x15400
54: e5832000 str r2, [r3]
58: ea000000 b 60 <main+0x28>
5c: e1a00000 nop ; (mov r0, r0)
60: e59f003c ldr r0, [pc, #60] ; a4 <main+0x6c>
64: ebfffffe bl 0 <wait>
68: e59f3038 ldr r3, [pc, #56] ; a8 <main+0x70>
6c: e51b2008 ldr r2, [fp, #-8]
70: e1a02282 lsl r2, r2, #5
74: e1e02002 mvn r2, r2
78: e5832000 str r2, [r3]
7c: e51b3008 ldr r3, [fp, #-8]
80: e2833001 add r3, r3, #1
84: e50b3008 str r3, [fp, #-8]
88: e51b3008 ldr r3, [fp, #-8]
8c: e3530010 cmp r3, #16
90: 1afffff1 bne 5c <main+0x24>
94: e3a03000 mov r3, #0
98: e50b3008 str r3, [fp, #-8]
9c: eaffffef b 60 <main+0x28>
a0: 56000010 undefined instruction 0x56000010
a4: 00007530 andeq r7, r0, r0, lsr r5
a8: 56000014 undefined instruction 0x56000014
Disassembly of section .comment:
00000000 <.comment>:
0: 43434700 movtmi r4, #14080 ; 0x3700
4: 6328203a teqvs r8, #58 ; 0x3a
8: 2d676e74 stclcs 14, cr6, [r7, #-464]! ; 0xfffffe30
c: 2e362e31 mrccs 14, 1, r2, cr6, cr1, {1}
10: 34202931 strtcc r2, [r0], #-2353 ; 0x931
14: 332e342e teqcc lr, #771751936 ; 0x2e000000
...
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00002941 andeq r2, r0, r1, asr #18
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 0000001f andeq r0, r0, pc, lsl r0
10: 00543405 subseq r3, r4, r5, lsl #8
14: 01080206 tsteq r8, r6, lsl #4
18: 04120109 ldreq r0, [r2], #-265 ; 0x109
1c: 01150114 tsteq r5, r4, lsl r1
20: 01180317 tsteq r8, r7, lsl r3
24: 021a0119 andseq r0, sl, #1073741830 ; 0x40000006
28: Address 0x00000028 is out of bounds.
链接后的文件的elf文件
sdram_elf: file format elf32-littlearm
Disassembly of section .text:
30000000 <_start>:
30000000: eb000005 bl 3000001c <disable_watch_dog>
30000004: eb000010 bl 3000004c <memsetup>
30000008: eb000007 bl 3000002c <copy_steppingstone_to_sdram>
3000000c: e59ff090 ldr pc, [pc, #144] ; 300000a4 <mem_cfg_val+0x34>
30000010 <on_sdram>:
30000010: e3a0d30d mov sp, #872415232 ; 0x34000000
30000014: eb000033 bl 300000e8 <main>
30000018 <halt_loop>:
30000018: eafffffe b 30000018 <halt_loop>
3000001c <disable_watch_dog>:
3000001c: e3a00453 mov r0, #1392508928 ; 0x53000000
30000020: e3a01000 mov r1, #0
30000024: e5801000 str r1, [r0]
30000028: e1a0f00e mov pc, lr
3000002c <copy_steppingstone_to_sdram>:
3000002c: e3a01000 mov r1, #0
30000030: e3a02203 mov r2, #805306368 ; 0x30000000
30000034: e3a03a01 mov r3, #4096 ; 0x1000
30000038: e4914004 ldr r4, [r1], #4
3000003c: e4824004 str r4, [r2], #4
30000040: e1510003 cmp r1, r3
30000044: 1afffffb bne 30000038 <copy_steppingstone_to_sdram+0xc>
30000048: e1a0f00e mov pc, lr
3000004c <memsetup>:
3000004c: e3a01312 mov r1, #1207959552 ; 0x48000000
30000050: e28f2018 add r2, pc, #24
30000054: e1a00000 nop ; (mov r0, r0)
30000058: e2813034 add r3, r1, #52 ; 0x34
3000005c: e4924004 ldr r4, [r2], #4
30000060: e4814004 str r4, [r1], #4
30000064: e1510003 cmp r1, r3
30000068: 1afffffb bne 3000005c <memsetup+0x10>
3000006c: e1a0f00e mov pc, lr
30000070 <mem_cfg_val>:
30000070: 22011110 andcs r1, r1, #4
30000074: 00000700 andeq r0, r0, r0, lsl #14
30000078: 00000700 andeq r0, r0, r0, lsl #14
3000007c: 00000700 andeq r0, r0, r0, lsl #14
30000080: 00000700 andeq r0, r0, r0, lsl #14
30000084: 00000700 andeq r0, r0, r0, lsl #14
30000088: 00000700 andeq r0, r0, r0, lsl #14
3000008c: 00018005 andeq r8, r1, r5
30000090: 00018005 andeq r8, r1, r5
30000094: 008c07a3 addeq r0, ip, r3, lsr #15
30000098: 000000b1 strheq r0, [r0], -r1
3000009c: 00000030 andeq r0, r0, r0, lsr r0
300000a0: 00000030 andeq r0, r0, r0, lsr r0
300000a4: 30000010 andcc r0, r0, r0, lsl r0
300000a8: e1a00000 nop ; (mov r0, r0)
300000ac: e1a00000 nop ; (mov r0, r0)
300000b0 <wait>:
300000b0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
300000b4: e28db000 add fp, sp, #0
300000b8: e24dd00c sub sp, sp, #12
300000bc: e50b0008 str r0, [fp, #-8]
300000c0: ea000002 b 300000d0 <wait+0x20>
300000c4: e51b3008 ldr r3, [fp, #-8]
300000c8: e2433001 sub r3, r3, #1
300000cc: e50b3008 str r3, [fp, #-8]
300000d0: e51b3008 ldr r3, [fp, #-8]
300000d4: e3530000 cmp r3, #0
300000d8: 1afffff9 bne 300000c4 <wait+0x14>
300000dc: e28bd000 add sp, fp, #0
300000e0: e8bd0800 pop {fp}
300000e4: e12fff1e bx lr
300000e8 <main>:
300000e8: e92d4800 push {fp, lr}
300000ec: e28db004 add fp, sp, #4
300000f0: e24dd008 sub sp, sp, #8
300000f4: e3a03000 mov r3, #0
300000f8: e50b3008 str r3, [fp, #-8]
300000fc: e59f304c ldr r3, [pc, #76] ; 30000150 <main+0x68>
30000100: e3a02b55 mov r2, #87040 ; 0x15400
30000104: e5832000 str r2, [r3]
30000108: ea000000 b 30000110 <main+0x28>
3000010c: e1a00000 nop ; (mov r0, r0)
30000110: e59f003c ldr r0, [pc, #60] ; 30000154 <main+0x6c>
30000114: ebffffe5 bl 300000b0 <wait>
30000118: e59f3038 ldr r3, [pc, #56] ; 30000158 <main+0x70>
3000011c: e51b2008 ldr r2, [fp, #-8]
30000120: e1a02282 lsl r2, r2, #5
30000124: e1e02002 mvn r2, r2
30000128: e5832000 str r2, [r3]
3000012c: e51b3008 ldr r3, [fp, #-8]
30000130: e2833001 add r3, r3, #1
30000134: e50b3008 str r3, [fp, #-8]
30000138: e51b3008 ldr r3, [fp, #-8]
3000013c: e3530010 cmp r3, #16
30000140: 1afffff1 bne 3000010c <main+0x24>
30000144: e3a03000 mov r3, #0
30000148: e50b3008 str r3, [fp, #-8]
3000014c: eaffffef b 30000110 <main+0x28>
30000150: 56000010 undefined instruction 0x56000010
30000154: 00007530 andeq r7, r0, r0, lsr r5
30000158: 56000014 undefined instruction 0x56000014
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00002541 andeq r2, r0, r1, asr #10
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 0000001b andeq r0, r0, fp, lsl r0
10: 00543405 subseq r3, r4, r5, lsl #8
14: 01080206 tsteq r8, r6, lsl #4
18: 04120109 ldreq r0, [r2], #-265 ; 0x109
1c: 01150114 tsteq r5, r4, lsl r1
20: 01180317 tsteq r8, r7, lsl r3
24: Address 0x00000024 is out of bounds.
Disassembly of section .comment:
00000000 <.comment>:
0: 3a434347 bcc 10d0d24 <SDRAM_BASE-0x2ef2f2dc>
4: 74632820 strbtvc r2, [r3], #-2080 ; 0x820
8: 312d676e teqcc sp, lr, ror #14
c: 312e362e teqcc lr, lr, lsr #12
10: 2e342029 cdpcs 0, 3, cr2, cr4, cr9, {1}
14: 00332e34 eorseq r2, r3, r4, lsr lr
】
6.1 存储器的基本概念
主存储器管理仍然是今天操作系统十分重要的内容;能否合理而有效的使用主存,在很大成度上反映了操作系统的性能,并直接影响到整个计算机系统作用的发挥。
6.1.1 存储器的层次
目前在许多计算机系统中,采用三级存储器结构,即高速缓冲存储器、主存储器和外部存储器。
三级存储器的比较
从高速缓存到外存,其容量愈来愈大,一般每级之间相差几个数量级。而访问数据的速度则愈来愈慢,价格也愈来愈便宜。
为了弄清什么是重定位,我们首先介绍相对地址、绝对地址和逻辑地址空间、存储空间的概念。
1.逻辑地址空间
名空间
用户在编程或编辑源程序时,不考虑作业之间的存储空间分配,而是将其源程序存于程序员建立的符号名字空间(简称名空间)内,如图6-1(a)所示。
逻辑地址空间
当对源程序进行编译时,编译后一个目标程序所限定的地址范围称为该作业的逻辑地址空间。
图6-1 名空间、地址空间和存储空间
如图6-1(b)所示。
2.物理空间
所谓物理空间(也称存储空间)是指主存中物理单元的集合。这些单元的编号称为物理地址或绝对地址。因此,物理空间的大小,是由主存的实际容量决定的。如图6-1(c)。
3.地址重定位
需要地址重定位的例子
如图6-2(a)是一个简单的程序段。第一条指令是把数据A取到1号寄存器中,第二条指令是把数据B同1号寄存中的内容相加,结果放在1号寄存器中,第三 条指令是把1号寄存器的内容送入相对地址10中去。如果这个程序原封不动地装入主存自100号单元起的存储区中(如图6-2(b)),就无法正确执行。
地址重定位
由于一个作业装入到与其地址空间不一致的存储空间所引起的,对有关地址部分的调整过程称为地址的重定位。这个调整过程就是把作业地址空间中使用的逻辑地址变换成主存中物理地址的过程。这种地址变换也称为地址映射.
图6-2 程序装入举例
4.重定位类型
根据对地址变换进行的时间及采用的技术手段的不同,可把地址重定位分为静态重定位和动态重定位两类。
静态重定位
(1)含义
静态重定位是在程序运行之前由装配程序完成的。例图5-2(a)中的情况,只需将与地址有关的项都加上100就可以了,见图5-2(c)。
(2)优点
它的主要优点是,无需增加硬件地址变换机构,因而可在一般计算机上实现。
(3)缺点
主要缺点有:
①要求给每个作业分配一个连续的存储空间,且在作业的整个执行期间不能再移动,因而也就不能实现重新分配主存。
②用户必须事先确定所需的存储量,若所需的存储量超过可用存储空间时,用户必须考虑覆盖结构。
③用户之间难以共享主存中的同一程序副本。
动态重定位
(1)含义
动态重定位是在程序执行过程中由硬件地址变换机构实现的。
(2)例子
最简单的办法是利用一个重定位寄存器。该寄存器的值由调度程序根据作业分配到的存储空间的起始地址来设定。在具有这种地址变换机构的计算机系统中,当作业 执行时,不是根据CPU给出的逻辑地址去访问主存,而是将逻辑地址与重定位寄存器中的内容相加后得到的地址作为访问主存的地址。其地址变换过程
如图6-3所示 重定位类型
图6-3 动态重定位
(3)动态重定位的主要优点有:
①用户作业不要求分配连续的存储空间。
②用户作业在执行过程中,可以动态申请存储空间和在主存中移动。
③有利于程序段的共享。
(4)动态重定位的主要缺点有:
①需要附加的硬件支持。
②实现存储管理的软件算法比较复杂。