1、Bootloader的概念
系统上电后需要一段程序来进行初始化:关闭WATCHDOG、改变系统时钟、初始化存储控制器、将更多的代码复制到内存中等。如果能将操作系统的内核复制到内存中运行,无论从本地(比如flash)还是从远端(比如网络),就称这段程序为Bootloader。
简单来说,Bootloader就是这么一段小程序,它在系统上电时开始运行,初始化硬件设备、准备好软件环境,最后调用操作系统内核。
常用的Bootloader有LILO 、GRUB、U-Boot、Vivi等。
同为开发板选用的Bootloader是U-boot。
2、U-boot简介
U-Boot,全称为Universal Boot Loader,即通用Bootloader,是遵循GPL条款的开放源代码项目。支持如下操作系统:Linux、NetBSD、VxWorks、QNX、RTEMS等,支持如下架构的CPU:PowerPC、MIPS、x86、ARM、NIOS、XScale等。
源码获得方式:http://ftp.denx.de/pub/u-boot
我们选用的版本是U-boot-1.1.6,下面以该版本为基础进行修改。
3、U-boot修改
同为开发板CPU为AT91RM9200,因此U-boot中以at91rm9200dk板为基础进行修改。
需要修改的文件分别位于以下几个目录:
/board/at91rm9200dk/config.mk /include/flash.h /board/at91rm9200dk/flash.c /include/configs/at91rm9200dk.h
/board/at91rm9200dk/at91rm9200dk.c
(1) /board/at91rm9200dk/config.mk
TEXT_BASE = 0x21f00000
修改为:
TEXT_BASE = 0x20f00000
(2) /board/at91rm9200dk/at91rm9200dk.c
gd->bd->bi_arch_number = MACH_TYPE_AT91RM9200;
修改为:
gd->bd->bi_arch_number = MACH_TYPE_AT91RM9200DK;
(3) /include/flash.h
#define SST_ID_xF6402 0x236A236A /* 39xF6402 ID (64M = 4M x 16 ) */
#define SST_ID_xF020 0xBFD6BFD6 /* 39xF020 ID (256KB = 2Mbit x 8) */
#define SST_ID_xF040 0xBFD7BFD7 /* 39xF040 ID (512KB = 4Mbit x 8) */
增加定义:
#define SST39VF6401B 0x236D236D /* 开发板上的Norflash在此处没有定义,需要自己添加 */
(4) /include/configs/at91rm9200dk.h
#define SDRC_CR_VAL 0x2188c155 /* set up the SDRAM */
修改为:
#define SDRC_CR_VAL 0x2188c154 /* set up the SDRAM */
#define PHYS_FLASH_SIZE 0x200000 /* 2 megs main flash */
修改为:
#define PHYS_FLASH_SIZE 0x800000 /* 8 megs main flash */
#define CFG_MAX_FLASH_SECT 256
修改为:
#define CFG_MAX_FLASH_SECT 2048
(5) /board/at91rm9200dk/flash.c
增加对Norflash的定义:
OrgDef Org39VF6401B[] =
{
{2048, 4*1024}
};
void flash_identification (flash_info_t * info)
{
info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
修改为:
info->flash_id = SST_MANUFACT & FLASH_VENDMASK;
printf ("Atmel: ");
修改为:
printf ("SST: ");
增加:
else if ((device_code & FLASH_TYPEMASK) == (SST39VF6401B & FLASH_TYPEMASK)) {
info->flash_id |= SST39VF6401B & FLASH_TYPEMASK;
printf ("SST39VF6401B (64Mbit)\n");
}
}
ulong flash_init (void)
{
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
(ATM_ID_BV1614 & FLASH_TYPEMASK)) {
pOrgDef = OrgAT49BV16x4;
flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
修改为:
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
(SST39VF6401B & FLASH_TYPEMASK)) {
pOrgDef = Org39VF6401B;
flash_nb_blocks = sizeof (Org39VF6401B) / sizeof (OrgDef);
size += flash_info[i].size;
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==(ATM_ID_BV6416 & FLASH_TYPEMASK))
修改为:
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==(SST39VF6401B & FLASH_TYPEMASK))
}
void flash_print_info (flash_info_t * info)
{
switch (info->flash_id & FLASH_VENDMASK) {
case (ATM_MANUFACT & FLASH_VENDMASK):
printf ("Atmel: ");
break;
修改为:
case (SST_MANUFACT & FLASH_VENDMASK):
printf ("SST: ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
增加:
case (SST39VF6401B & FLASH_TYPEMASK):
printf ("SST39VF6401B (64Mbit)\n");
break;
}
}
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
if ((info->flash_id & FLASH_VENDMASK) !=
(ATM_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
修改为:
if ((info->flash_id & FLASH_VENDMASK) !=
(SST_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
}
4、Uboot编译
(1)make clean
(2)make at91rm9200dk_config
(3)make