u-boot-1.1.4修改启动地址

下面的修改针对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;
}

你可能感兴趣的:(嵌入式)