“第013课 代码重定位”的版本间的差异

来自百问网嵌入式Linux wiki
(创建页面,内容为“<categorytree mode=all style="float:right; clear:right; margin-left:1ex; border:1px solid gray; padding:0.7ex; background-color:white;">ARM裸机加强版</categoryt...”)
 
第1行: 第1行:
<categorytree mode=all style="float:right; clear:right; margin-left:1ex; border:1px solid gray; padding:0.7ex; background-color:white;">ARM裸机加强版</categorytree>
+
=第001节_段的概念_重定位的引入 =
 +
S3C2440的CPU可以直接给SDRAM发送命令、给Nor Flash发送命令、给4K的片上SDRAM发送命令,但是不能直接给Nand Flsh发送命令
 +
 
 +
假如把程序烧写到Nand Flsh上,即向Nand Flsh烧入** bin** 文件,CPU是无法从Nand Flsh中取代码执行的。
 +
 
 +
为什还可以使用NAND启动?
 +
1. 上电后,Nand启动硬件会自动把Nand Flsh前4K复制到SRAM;
 +
2. CPU从0地址运行SRAM;
 +
 
 +
如果我的程序大于4K怎么办?
 +
前4K的代码需要把整个程序读出来放到SDRAM(即代码重定位)。
 +
 
 +
如果从Nor Flash启动,会出现什么问题?
 +
将拨动开关拨到Nor Flash启动时,此时CPU认为的** 0地址 **在Nor Flash上面,片内内存SRAM的基地址就变成了0x40000000(Nand启动时片内内存SRAM的基地址基地址是0),由于Nor Flash特性:**可以像内存一样读,但不能像内存直接写**,因此需要把全局变量和静态变量重定位 放到SDRAM里。
 +
 
 +
 
 +
例如执行如下几条汇编指令
 +
 +
MOV R0, #0
 +
LDR R1, [R0] @读有效
 +
STR R1, [R0] @写无效
 +
 +
当程序中含有需要写的全局变量或静态变量时,假如是在Nand Flash可以正常操作,如果是在Nor Flash,修改无效。因此我们需要把全局变量和静态变量重定位 放到SDRAM
 +
 
 +
<syntaxhighlight lang="c" >
 +
 +
#include "s3c2440_soc.h"
 +
#include "uart.h"
 +
#include "init.h"
 +
 
 +
char g_Char = 'A';  //定义一个全局变量
 +
const char g_Char2 = 'B'; //定义固定的全局变量
 +
int g_A = 0;
 +
int g_B;
 +
 
 +
int main(void)
 +
{
 +
uart0_init();
 +
 
 +
while (1)
 +
{
 +
putchar(g_Char); /*让g_Char输出*/
 +
g_Char++;        /* nor启动时, 此代码无效 */
 +
delay(1000000);
 +
}
 +
 
 +
 +
return 0;
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
编译运行查看是否有效果
 +
 
 +
查看sdram.dis文件 发现data数据段放在了0x00008474这个地址导致 程序太大
 +
 
 +
在makefile中加入这么一句话
 +
 
 +
arm-linux-ld -Ttext 0 ** -Tdata 0x800 ** start.o led.o uart.o init.o main.o -o sdram.elf
 +
 
 +
16进制的800就是十进制的2048
 +
这时我们的bin文件就变为2049
 +
 
 +
 
 +
烧写程序
 +
 
 +
烧写在NORFlash
 +
烧写在NANDFlash观察这两种的效果
 +
 
 +
设置成NANDFlash启动没有问题 显示ABCDE...
 +
设置成NORFlash启动显示AAA...
 +
对于NOR启动时g_Char++;        /* nor启动时, 此代码无效 */
 +
 
 +
 
 +
<syntaxhighlight lang="c" >
 +
Disassembly of section .data:
 +
 
 +
00000800 <__data_start>:
 +
800: Address 0x800 is out of bounds.  //数据段
 +
 
 +
Disassembly of section .rodata:
 +
//放在只读数据段内
 +
00000474 <g_Char2>:  //const char g_Char2 = 'B';
 +
474: Address 0x474 is out of bounds.
 +
 
 +
Disassembly of section .bss: //bss段
 +
 
 +
00000804 <g_A>: //int g_A = 0;
 +
 
 +
804: 00000000 andeq r0, r0, r0
 +
 
 +
00000808 <g_B>: //int g_B;
 +
808: 00000000 andeq r0, r0, r0
 +
Disassembly of section .comment:
 +
 
 +
</syntaxhighlight>
 +
 
 +
 
 +
一个程序里面有
 +
* .text 代码段
 +
* .data 数据段
 +
* rodata 只读数据段(const全局变量)
 +
* bss段 (初始值为0,无初始值的全局变量)
 +
* commen 注释
 +
 
 +
其中bss段和commen 注释不保存在bin文件中。
 +
 
 +
                                                                                                                           
 +
='''《《所有章节目录》》'''=
 +
<categorytree mode=all background*color:white;">ARM裸机加强版</categorytree>
 
[[Category:ARM裸机加强版 ]]
 
[[Category:ARM裸机加强版 ]]

2018年1月17日 (三) 17:07的版本

第001节_段的概念_重定位的引入

S3C2440的CPU可以直接给SDRAM发送命令、给Nor Flash发送命令、给4K的片上SDRAM发送命令,但是不能直接给Nand Flsh发送命令

假如把程序烧写到Nand Flsh上,即向Nand Flsh烧入** bin** 文件,CPU是无法从Nand Flsh中取代码执行的。

为什还可以使用NAND启动? 1. 上电后,Nand启动硬件会自动把Nand Flsh前4K复制到SRAM; 2. CPU从0地址运行SRAM;

如果我的程序大于4K怎么办? 前4K的代码需要把整个程序读出来放到SDRAM(即代码重定位)。

如果从Nor Flash启动,会出现什么问题? 将拨动开关拨到Nor Flash启动时,此时CPU认为的** 0地址 **在Nor Flash上面,片内内存SRAM的基地址就变成了0x40000000(Nand启动时片内内存SRAM的基地址基地址是0),由于Nor Flash特性:**可以像内存一样读,但不能像内存直接写**,因此需要把全局变量和静态变量重定位 放到SDRAM里。


例如执行如下几条汇编指令

MOV R0, #0
LDR R1, [R0] @读有效
STR R1, [R0] @写无效

当程序中含有需要写的全局变量或静态变量时,假如是在Nand Flash可以正常操作,如果是在Nor Flash,修改无效。因此我们需要把全局变量和静态变量重定位 放到SDRAM

 
#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"

char g_Char = 'A';  //定义一个全局变量
const char g_Char2 = 'B'; //定义固定的全局变量
int g_A = 0;
int g_B;

int main(void)
{
	uart0_init();

	while (1)
	{
		putchar(g_Char); /*让g_Char输出*/
		g_Char++;         /* nor启动时, 此代码无效 */
		delay(1000000);
	}

	
	return 0;
}

编译运行查看是否有效果

查看sdram.dis文件 发现data数据段放在了0x00008474这个地址导致 程序太大

在makefile中加入这么一句话

arm-linux-ld -Ttext 0 ** -Tdata 0x800 ** start.o led.o uart.o init.o main.o -o sdram.elf

16进制的800就是十进制的2048 这时我们的bin文件就变为2049


烧写程序

烧写在NORFlash 烧写在NANDFlash观察这两种的效果

设置成NANDFlash启动没有问题 显示ABCDE... 设置成NORFlash启动显示AAA... 对于NOR启动时g_Char++; /* nor启动时, 此代码无效 */


Disassembly of section .data:

00000800 <__data_start>:
 800:	Address 0x800 is out of bounds.  //数据段

Disassembly of section .rodata:
							//放在只读数据段内
00000474 <g_Char2>:   		//const char g_Char2 = 'B';
 474:	Address 0x474 is out of bounds.

Disassembly of section .bss:	//bss段

00000804 <g_A>:				//int g_A = 0;

 804:	00000000 	andeq	r0, r0, r0

00000808 <g_B>:				//int g_B;
 808:	00000000 	andeq	r0, r0, r0
Disassembly of section .comment:


一个程序里面有

  • .text 代码段
  • .data 数据段
  • rodata 只读数据段(const全局变量)
  • bss段 (初始值为0,无初始值的全局变量)
  • commen 注释

其中bss段和commen 注释不保存在bin文件中。