U-Boot-C语言环境初始化
Posted _WILLPOWER_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了U-Boot-C语言环境初始化相关的知识,希望对你有一定的参考价值。
- 概念解析
- 栈
- 空/满栈
- 升/降栈
- 栈帧
- 栈作用
- 保存局部变量
- 参数传递
- 保存寄存器值
- 栈初始化编程
栈初始化
栈
栈是一种具有后进先出性质的数据组织方式,也就是说后存放的先取出,先存放的后取出。栈底是第一个进栈的数据所处的位置,栈顶是最后一个进栈的数据所处的位置。
满/空栈
根据SP指针指向的位置,栈.可以分为满栈
和空栈
。
- 满栈:当堆栈指针SP总是指向最后压入堆栈的数据
- 空栈:当堆栈指针SP总是指向下一个将要放入数据的空位置
ARM采用满栈!
生/降栈
根据P指针移动的方向,栈可以分为升栈
和降栈
。
- 升栈:随着数据的入栈,SP指针从低地址->高地址移动
- 降栈:随着数据的入栈,SP指针从高地址->低地址移动
ARM采用降栈!
栈帧
简单的讲,栈帧(stack frame)就是一个函数所使用的那部分栈,所有函数的栈帧串起来就组成了一个完整的栈。栈帧的两个边界分别由 fp(r11) 和 sp(r13) 来限定。
栈作用
保存局部变量
传递参数
C语言传递参数,如果参数小于等于4个的时候,用r0-r3来传递1-4个参数,大于4个的参数,用栈来保存。
保存寄存器的值
栈初始化编程
给64M(210的内存是从0x20000000开始的)
init_stack:
ldr sp, =0x24000000
mov pc, lr
初始化BSS段
Block Started bySymbol”的缩写,意为“以符号开始的块”
初始化的全局:数据段
局部变量:栈
malloc:堆
未初始化全局:BSS段
为什么要初始化
为了防止未初始化的全局变量在使用的时候,拿到了其不确定的值来使用,因此提前清零。
如何清零
只要我们找到bss段的起始地址,结束地址,然后清零即可。
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1
moveq pc, lr
clean_loop:
mov r2, #0
str r2, [r0], #4
cmp r0, r1
bne clean_loop
mov pc, lr
进入C语言
采用绝对跳转
注意,在ldr跳转后,直接就到内存的地址去运行命令去了
//@宏定义控制与数据寄存器
#define GPCCON (volatile unsigned long *)0xE0200060
#define GPCDAT (volatile unsigned long *)0xE0200064
int gboot_main()
{
*GPCCON = 0x11000;
*GPCDAT = 0x18;
return 0;
}
注意210中有加头操作,因此在复制代码到dram中的时候,需要跳过头!
这个头是16字节,因此不再是用0xd0020000
而是0xd0020010
注意指定的地址如果4字节对齐,那么起始地址不能0x20000000,至少为0x20000004,反正用0x20000000有问题
C与汇编混合编程
汇编语言
执行效率高;编写繁琐,能够更直接地控制处理器
C语言
可读性强,移植性好,调试方便
- 汇编调用C函数
- C调用汇编函数
- C内嵌汇编
- 格式
- 范例
- 优化
汇编调用C函数
C调用汇编函数
C内嵌汇编
格式
_asm_(
汇编语句部分
:输出部分(修改C语言的参数)
:输入部分(拿C语言中的参数)
:破坏描述部分
);
C内嵌汇编以关键字"_asm_“或"asm"开始,下面4个部分,各部分使用”:"分开,第一部分是必须写的,后面三部分是可以省略的,但是分号:不能省略
范例
void write_p15_c1(unsigned long value)
{
__asm__(
"mcr p15, 0, %0, c1, c0, 0\\n"
:
: "r"(value) @编译器选择一个R * 寄存器);
}
r表示通用寄存器,这里面的值从value参数而来
案例2
unsigned long read_p15_c1(void)
{
unsigned long value;
__asm__(
"mrc p15, 0, %0, c1, c0, 0\\n"
: "=r"(value) @‘=’表示只写操作数,用于输出部
:
: "memory");
return value;
}
memory表示内存的意思,表示value的值被修改了
优化
unsigned long old;
unsigned long temp;
__asm__ volatile(
"mrs %0, cpsr \\n"
"orr %1, %0, #128 \\n"
"msr cpsr_c, %1\\n"
: "=r"(old), "=r"(temp)
:
: "memory");
使用volatile来告诉编译器,不要对接下来的这部分代码进行优化。
如果在操作硬件的收,比如你代码如p1=0x01;然后又写p1=0x10;那么编译器可能认为你前一句是多余的,将前一句给删除.
使用内嵌汇编点亮LED
//@宏定义控制与数据寄存器
#define GPCCON (volatile unsigned long *)0xE0200060
#define GPCDAT (volatile unsigned long *)0xE0200064
int gboot_main()
{
// *GPCCON = 0x11000;
// *GPCDAT = 0x18;
// light_led();
__asm__(
"ldr r1, =0x11000\\n"
"str r1, [%0]\\n"
"ldr r1, =0x18\\n"
"str r1, [%1]\\n"
:
: "r"(GPCCON), "r"(GPCDAT)
: "r1");
return 0;
}
破坏部(修改了r1)因此还是需要写的
以上是关于U-Boot-C语言环境初始化的主要内容,如果未能解决你的问题,请参考以下文章
环境初始化 Build and Install the Apache Thrift IDL Compiler Install the Platform Development Tools(代码片段
如何使用 Swift 使用此代码片段为 iOS 应用程序初始化 SDK?