由于 Boot Loader 的实现依赖于 CPU 的体系结构,因此大多数 Boot Loader 都分为 stage1 和 stage2
两大部分。
依赖于 CPU 体系结构的代码,比如设备初始化代码等,通常都放在 stage1 中,而且通常都用
汇编语言来实现,以达到短小精悍的目的。
而 stage2 则通常用C语言来实现,这样可以实现给复杂的功能,而且代码会具有更好的可读性可移植性.
Boot Loader 的 stage1 通常包括以下步骤(以执行的先后顺序):
·硬件设备初始化。
·为加载 BootLoader的stage2准备 RAM空间
·拷贝 Boot Loader 的 stage2 到 RAM 空间中
·设置好堆栈。
·跳转到 stage2 的 C 入口点。
Boot Loader 的 stage2 通常包括以下步骤(以执行的先后顺序):
·初始化
本阶段要使用到的硬件设备。
·检测系统内存映射(memory map)。
·将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中。
·为内核设置启动参数。
·调用内核。
//Boot-loader
unsigned long address;
unsigded long data;
unsigned long length;
void init_uart(void) //串口1初始化
{
IO_UBRLCR1=(IO_UBRLCR1 & ~BRDIV) | BR_115200; //串口频率
IO_UBRLCR1=IO_UBRLCR1 | FIFOEN;
IO_UBRLCR1=(IO_UBRLCR1 & ~WRDLEN) | (3<<WRDLEN_SHIFT);
IO_SYSCON1 |=UARTLEN;
}
unsigned char get_char(void)
{
while(IO_SYSFLG1 & UR5XFE1);
return IO_UBRLCR1 & 0xff;
}
void put_char(unsigned char data)
{
while(IO_SYSFLG & UTXFF1);
IO_UARTDR1=data;
}
void put_string(char *sp)
{
unsigned int i=0;
while(sp[i]!=0)
put_char(sp[i]++);
}
unsigned int wait(unsigned int i)
{
unsigned int sum=0;
for(;i>0;i--)
sum+=i;
return(sum);
}
void flash_erase()
{
SYSC_(0x70005555)=0xaa;
wait(1);
SYSC_(0x70002aaa)=0x55;
wait(1);
SYSC_(0x70005555)=0x80;
wait(1);
SYSC_(0x70005555)=0xaa;
wait(1);
SYSC_(0x70002aaa)=0x55;
wait(1);
SYSC_(0x70005555)=0x10;
wait(1);
while((SYSC_(0x70000000) & 0x80)==0); //确认已擦出
}
void flash_prog(unsigned long address,unsigned char data)
{
SYSC_(0x70005555)=0xaa;
wait(1);
SYSC_(0x70002aaa)=0x55;
wait(1);
SYSC_(0x70005555)=0xa0;
wait(1);
SYS_(address)=data;
while(SYS_(address)!=data); //确认已写入
}
void writein()
{
unsigned long i,data;
put_string("len:/n");
length=get_char();
length=(length<<8)+get_char();
length=(length<<8)+get_char();
length=(length<<8)+get_char();
for(i=0;i<length;i+=4)
{
data=get_char();
data+=get_char()<<8;
data+=get_char()<<16;
data+=get_char()<<24;
SDRAM_(i)=data;
}
put_string("OK!/n");
}
void flashload()
{
unsigned long i;
writein();
flash_erase();
for(i=0;i<length;i+=4)
{
data=SDRAM_(i);
flash_prog((0x70000000+i),data & 0xff);
flash_prog((0x70000000+i),(data>>8) & 0xff);
flash_prog((0x70000000+i),(data>>16) & 0xff);
flash_prog((0x70000000+i),(data>>24) & 0xff);
}
put_string("Done!/n");
}
void mymain(void)
{
unsigned char scomm,sdata;
unsigned char *addrp;
unsigned char *datap;
addrp=(unsigned char *)& address;
datap=(unsigned char *)& data;
put_string("ok!/n");
while(1)
{
scomm=get_char();
if(scomm==0xff)
{
scomm=get_char();
if(scomm!=0xff)
switch(scomm)
{
case 0xfa:flashload();break;
default:put_string("not support!/n");
}
else sdata=0xff;
}
else sdata=scomm;
}
}
void C_vMain(void)
{
unsigned char i;
unsigned short j;
init_uart();
while(1)
{
i=get_char();
if(i==0x79)
mymain();
else put_string(i);
}
}