BootLoader
是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的
BootLoader
设计与实现。
BootLoader
都分为
stage1
体系结构的代码,比如设备初始化代码等,通常都放在
stage1
语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。
BootLoader
为加载
Boot Loader
空间;
Ø
的
stage2
跳转到
stage2
的
stage2
初始化本阶段要使用到的硬件设备;
Ø
;
Ø
映像和根文件系统映像从
flash
调用内核。
公司的vivi我们购买了武汉创维特信息技术有限公司开发的具有自主知识产权的应用于嵌入式软件开发的集成软、硬件开发平台ADT核的嵌入式应用提供了一整套完备的开发方案,包括程序编辑、工程管理和设置、程序编译、程序调试等。
ADT
组成。
ADT Emulator for ARM
芯片的
JTAG
调试接口等。其界面同
Microsoft Visual Studio
嵌入式软件开发环境采用主机-目标机交叉开发模型。
ADT IDE for ARM
与目标机之间的连接。开发时,首先由
ADT IDE for ARM
中通过
ADT Emulator for ARM
汇编
ARM
等高级语言为主,我们仅需要在
Bootloader
)
+-
――
r3 := r3 + 1
)位运算
AND r0, r1, r2
―― r0 := r1 or r2
EOR r0, r1, r2
―― r0 := r1 and not r2
―― r0 := r2
MVN r0, r2
(4寄存器中的 (N, Z, C, V) )内存操作
LDR r0, [r1]
―― mem [r1] := r0
LDR r0, [r1, #4]
―― r0 := mem [r1+4] r1 := r1 + 4
LDR r0, [r1], #4
―― r0 := mem8 [r1]
LDMIA r1, {r0, r2, r5}
可以包括r0~r15(6例2:
CMP r0, #5
ADDNE r1, r1, r0
SUBNE r1, r1, r2
第一阶段
3.1 设置CPU初始化;
Ø
的中断向量表设置在
0
每当其中的某个异常发生后即将
PC
设置系统时钟:
@init clk
@ 1:2:4
mov r1, #CLK_CTL_BASE
mov r2, #0x3
str r2, [r1, #oCLKDIVN]
mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
orr r1, r1, #0xc0000000 @ Asynchronous
mcr p15, 0, r1, c1, c0, 0 @ write ctrl register
@ now, CPU clock is 200 Mhz
mov r1, #CLK_CTL_BASE
ldr r2, mpll_200mhz
str r2, [r1, #oMPLLCON]
设置(初始化)内存映射:
ENTRY(memsetup)
@ initialise the static memory
@ set memory control registers
mov r1, #MEM_CTL_BASE
adrl r2, mem_cfg_val
add r3, r1, #52
1: ldr r4, [r2], #4
str r4, [r1], #4
cmp r1, r3
bne 1b
mov pc, lr
此外,vivi和PrintHexWord配置为从NAND FLASH代码copy进入C,堆栈指针的设置是为了执行C函数:
@ get read to call C functions
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
mov a2, #0 @ set argv to NULL
bl main @ call main
mov pc, #FLASH_BASE @ otherwise, reboot
4. BootLoader函数中分别调用这几个小阶段的相关函数:
int main(int argc, char *argv[])
{
int ret;
/*
* Step 1:
*/
putstr("\r\n");
putstr(vivi_banner);
reset_handler();
/*
* Step 2:
*/
ret = board_init();
if (ret) {
putstr("Failed a board_init() procedure\r\n");
error();
}
/*
* Step 3:
*/
mem_map_init();
mmu_init();
putstr("Succeed memory mapping.\r\n");
/*
* Now, vivi is running on the ram. MMU is enabled.
*/
/*
* Step 4:
*/
/* initialize the heap area*/
ret = heap_init();
if (ret) {
putstr("Failed initailizing heap region\r\n");
error();
}
/* Step 5:
*/
ret = mtd_dev_init();
/* Step 6:
*/
init_priv_data();
/* Step 7:
*/
misc();
init_builtin_cmds();
/* Step 8:
*/
boot_or_vivi();
return 0;
}
STEP1的版本、作者等信息,vivi_banner会clear口:
int board_init(void)
{
init_time();
set_gpios();
return 0;
}
STEP3的MMU<span times="" new="" roman';="" mso-hansi-font-family:="" 'times="" roman'"="" style="padding: 0px; margin: 0px; font-family: 宋体;">初始化只需要调用通用的arm920 MMU进行mtd设置私有数据;STEP7,等待用户输出命令并进行相应处理。在SHELL电路板调试
文件,修改Link开始的4KB,并将vivi。如果板电路的原理与三星公司DEMO源代码,重新编译vivi了。
小结
的功能,Bootloader<span times="" new="" roman';="" mso-hansi-font-family:="" 'times="" roman'"="" style="padding: 0px; margin: 0px; font-family: 宋体;">的调试环境及ARM<span times="" new="" roman';="" mso-hansi-font-family:="" 'times="" roman'"="" style="padding: 0px; margin: 0px; font-family: 宋体;">电路板的调试方法。