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("
");
putstr(vivi_banner);
reset_handler();
/*
* Step 2:
*/
ret = board_init();
if (ret) {
putstr("Failed a board_init() procedure
");
error();
}
/*
* Step 3:
*/
mem_map_init();
mmu_init();
putstr("Succeed memory mapping.
");
/*
* 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
");
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初始化只需要调用通用的arm920 MMU进行mtd设置私有数据;STEP7,等待用户输出命令并进行相应处理。在SHELL电路板调试
文件,修改Link开始的4KB,并将vivi。如果板电路的原理与三星公司DEMO源代码,重新编译vivi了。
小结
的功能,Bootloader的调试环境及ARM电路板的调试方法。