下面的修改针对PPC8548
NOR Flash。跑Linux带文件系统
修改文件u-boot-1.1.4\common\cmd_bootm.c
do_bootm_linux
在没有加命令行参数启动的时候,此函数可以通过解析环境变量中的默认启动地址,来引导内核。环境变量所在文件include/configs/MPC8548PC.h
也可以通过命令行指定内核启动地址和文件系统地址
下面,将在代码中修改为从NOR Flash中读取启动地址,来尝试引导。并且支持启动地址自动切换
#ifdef CONFIG_PPC
#define APP1_DEV_NAME "/dev/mtd5"
#define APP1_FLASH_ADDR 0xff000000 /* 实际物理起始地址 */
#define APP1_FLASH_OFFSET 0 /* 使用/dev/mtd5 */
#define APP1_FLASH_BYTES 0x00400000 /* 分配前一半空间 */
#define APP2_DEV_NAME "/dev/mtd5"
#define APP2_FLASH_ADDR 0xff400000 /* 实际物理起始地址 */
#define APP2_FLASH_OFFSET 0x00400000 /* 使用/dev/mtd5 */
#define APP2_FLASH_BYTES 0x00400000 /* 分配后一半空间 */
#define APP3_DEV_NAME "/dev/mtd2"
#define APP3_FLASH_ADDR 0xff9c0000 /* 实际物理起始地址 */
#define APP3_FLASH_OFFSET 0 /* 使用/dev/mtd2,默认boot分区 */
#define APP3_FLASH_BYTES 0x00300000 /* 默认分区大小 */
#define APP_BOOT_ADDR_NAME "/dev/mtd3"
#define APP_BOOT_ADDR 0xffcc0000 /* 实际物理起始地址(保存文件系统引导地址) */
#define APP_BOOT_ADDR_OFFSET 0 /* 使用/dev/mtd3 */
#define APP_BOOT_ADDR_BYTES 0x00020000 /* 默认erasesize大小 */
/* 开始引导的时候,从flash地址中读取引导地址,并且判断引导地址是否合法 */
if(argc == 2)
{
addr = image_loadaddr_get();
if(addr != APP1_FLASH_ADDR &&
addr != APP2_FLASH_ADDR &&
addr != APP3_FLASH_ADDR)
{
addr = APP3_FLASH_ADDR;
}
}
/* 如果校验失败,按指定顺序切换下一个引导地址,再次尝试启动 */
if (hdr->ih_magic != IH_MAGIC) {
puts ("Bad Magic Number\n");
SHOW_BOOT_PROGRESS (-10);
image_loadaddr_set(addr);
do_reset (cmdtp, flag, argc, argv);
}
函数单独实现
/* flash读取函数,读取文件系统引导地址 */
static ulong
image_loadaddr_get(void)
{
ulong addr, count;
ulong dest = 0;
int size;
addr = APP_BOOT_ADDR;
count = 0x1;
size = sizeof(dest);
printf("image_loadaddr_get:\r\n");
while (count-- > 0) {
if (size == 4)
{
dest = *((ulong *)addr);
printf("0x%08x ", dest);
}
else if (size == 2)
{
dest = *((ushort *)addr);
printf("0x%04x ", dest);
}
else
{
dest = *((u_char *)addr);
printf("0x%02x ", dest);
}
addr += size;
}
printf("\r\n");
return dest;
}
/* flash写入函数,引导地址写入,按默认顺序,写入下一次启动引导地址 */
static int
image_loadaddr_set(ulong load_addr)
{
int ret;
ulong addr;
/*
用于通知飞行软件从哪个程序存储区启动代码,
默认启动顺序为2-0-1
*/
if(load_addr == APP1_FLASH_ADDR)
{
load_addr = APP2_FLASH_ADDR;
}
else if(load_addr == APP2_FLASH_ADDR)
{
load_addr = APP3_FLASH_ADDR;
}
else if(load_addr == APP3_FLASH_ADDR)
{
load_addr = APP1_FLASH_ADDR;
}
else
{
printf("flash_sect_erase load_addr err 0x%08x\r\n", load_addr);
return -1;
}
addr = APP_BOOT_ADDR;
if(flash_sect_erase (addr, addr + APP_BOOT_ADDR_BYTES - 1))
{
printf("flash_sect_erase err\r\n");
return -1;
}
ret = flash_write((char*)&load_addr, addr, sizeof(load_addr));
if(ret != 0)
{
printf("flash_write err %d\r\n", ret);
return -1;
}
return 0;
}