⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 u-boot代码记录.c

📁 本人移植 uboot后代码注释 注释很详细的
💻 C
📖 第 1 页 / 共 5 页
字号:
Void   flash_protect (int flag, ulong from, ulong to, flash_info_t *info)
{
	ulong b_end = info->start[0] + info->size - 1;	/* flash的最后地址 */
	short s_end = info->sector_count - 1;	/* 扇区的最后一个index */
	int i;

	debug ("flash_protect %s: from 0x%08lX to 0x%08lX\n",
		(flag & FLAG_PROTECT_SET) ? "ON" :(flag & FLAG_PROTECT_CLEAR) ? "OFF" : "???",
		from, to);

	/* Do nothing if input data is bad. */
	if (info->sector_count == 0 || info->size == 0 || to < from) 
	{
		return;
	}

	/* There is nothing to do if we have no data about the flash
	 * or the protect range and flash range don't overlap.
	 */
	if (info->flash_id == FLASH_UNKNOWN ||to < info->start[0] || from > b_end) 
	    {
		    return;
	    }

	for (i=0; i<info->sector_count; ++i) 
	{
		ulong end;		/* last address in current sect	*/

		end = (i == s_end) ? b_end : info->start[i + 1] - 1;   //条件表达式当i=0时得到的第一个扇区的最后地址

		/* Update protection if any part of the sector
		 * is in the specified range.
		 */
		if (from <= end && to >= info->start[i]) 
		{
			if (flag & FLAG_PROTECT_CLEAR) 
			{
#if defined(CFG_FLASH_PROTECTION)
				flash_real_protect(info, i, 0);
#else
				info->protect[i] = 0;
#endif	/* CFG_FLASH_PROTECTION */
				debug ("protect off %d\n", i);
			}
			else if (flag & FLAG_PROTECT_SET) 
			{
#if defined(CFG_FLASH_PROTECTION)
				flash_real_protect(info, i, 1);
#else
				info->protect[i] = 1;
#endif	/* CFG_FLASH_PROTECTION */
				debug ("protect on %d\n", i);
			}
		}
	}
}



















void env_relocate (void)
{
	DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,gd->reloc_off);

#ifdef CONFIG_AMIGAONEG3SE
	enable_nvram();
#endif

#ifdef ENV_IS_EMBEDDED
	/*
	 * The environment buffer is embedded with the text segment,
	 * just relocate the environment pointer
	 */
	env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
	DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#else
	/*
	 * We must allocate a buffer for the environment
	 */
	env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
	DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif

	/*
	 * After relocation to RAM, we can always use the "memory" functions
	 */
	env_get_char = env_get_char_memory;

	if (gd->env_valid == 0) 
	{
#if defined(CONFIG_GTH)	|| defined(CFG_ENV_IS_NOWHERE)	/* Environment not changable */
		puts ("Using default environment\n\n");
#else
		puts ("*** Warning - bad CRC, using default environment\n\n");
		SHOW_BOOT_PROGRESS (-1);
#endif

		if (sizeof(default_environment) > ENV_SIZE)
		{
			puts ("*** Error - default environment is too large\n\n");
			return;
		}

		memset (env_ptr, 0, sizeof(env_t));
		memcpy (env_ptr->data,
			default_environment,
			sizeof(default_environment));
#ifdef CFG_REDUNDAND_ENVIRONMENT
		env_ptr->flags = 0xFF;
#endif
		env_crc_update ();
		gd->env_valid = 1;
	}
	else 
	{
		env_relocate_spec ();
	}
	gd->env_addr = (ulong)&(env_ptr->data);

#ifdef CONFIG_AMIGAONEG3SE
	disable_nvram();
#endif
}







/***************************************************************************
 * find command table entry for a command
 */
cmd_tbl_t *find_cmd (const char *cmd)
{
	cmd_tbl_t *cmdtp;
	cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;	/*Init value */
	const char *p;
	int len;
	int n_found = 0;

	/*
	 * Some commands allow length modifiers (like "cp.b");
	 * compare command name only until first dot.
	 */
	len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);

	for (cmdtp = &__u_boot_cmd_start;cmdtp != &__u_boot_cmd_end; cmdtp++) 
	{
		if (strncmp (cmd, cmdtp->name, len) == 0) 
		{
			if (len == strlen (cmdtp->name))
				return cmdtp;	/* full match */

			cmdtp_temp = cmdtp;	/* abbreviated command ? */
			n_found++;
		}
	}
	if (n_found == 1) 
	{			/* exactly one match */
		return cmdtp_temp;
	}

	return NULL;	/* not found or ambiguous command */
}






int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	flash_info_t *info;
	ulong bank, addr_first, addr_last;
	int n, sect_first, sect_last;
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
	struct mtd_device *dev;
	struct part_info *part;
	u8 dev_type, dev_num, pnum;
#endif
	int rcode = 0;

	if (argc < 2)      //当命令行参数小于2时  输出使用说明
	{
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (strcmp(argv[1], "all") == 0)     //当第2个参数是 all的时候 搽掉整个bank
	{
		for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) 
		{
			printf ("Erase Flash Bank # %ld ", bank);
			info = &flash_info[bank-1];
			rcode = flash_erase (info, 0, info->sector_count-1);
		}
		return rcode;
	}
///////////////////////////如果参数的个数大于或则等于2//////////////////////////////////////////
	if ((n = abbrev_spec(argv[1], &info, &sect_first, &sect_last)) != 0) 
	{
		if (n < 0) 
		{
			puts ("Bad sector specification\n");
			return 1;
		}
		printf ("Erase Flash Sectors %d-%d in Bank # %d ",sect_first, sect_last, (info-flash_info)+1);
		rcode = flash_erase(info, sect_first, sect_last);
		return rcode;
	}



	if (argc != 3)    //如果参数不为3
	{
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (strcmp(argv[1], "bank") == 0) 
	{
		bank = simple_strtoul(argv[2], NULL, 16);
		if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) 
		{
			printf ("Only FLASH Banks # 1 ... # %d supported\n",
				CFG_MAX_FLASH_BANKS);
			return 1;
		}
		printf ("Erase Flash Bank # %ld ", bank);
		info = &flash_info[bank-1];
		rcode = flash_erase (info, 0, info->sector_count-1);
		return rcode;
	}

	if (addr_spec(argv[1], argv[2], &addr_first, &addr_last) < 0)
	{
		printf ("Bad address format\n");
		return 1;
	}

	if (addr_first >= addr_last) 
	{
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
  
	rcode = flash_sect_erase(addr_first, addr_last);//addr_first,和addr_last得到的是十进制的物理地址
	return rcode;
}

int flash_sect_erase (ulong addr_first, ulong addr_last)
{
	flash_info_t *info;
	ulong bank;
#ifdef CFG_MAX_FLASH_BANKS_DETECT
	int s_first[CFG_MAX_FLASH_BANKS_DETECT], s_last[CFG_MAX_FLASH_BANKS_DETECT];
#else
	int s_first[CFG_MAX_FLASH_BANKS], s_last[CFG_MAX_FLASH_BANKS];//定义两个数组
#endif
	int erased = 0;
	int planned;
	int rcode = 0;

	rcode = flash_fill_sect_ranges (addr_first, addr_last,s_first, s_last, &planned );//planned返回的是扇区的个数

	if (planned && (rcode == 0))   //只有要擦除的地址符合扇区边界的要求就可以执行
	{
		for (bank=0,info=&flash_info[0];(bank < CFG_MAX_FLASH_BANKS) && (rcode == 0);++bank, ++info) 
		     {
			     if (s_first[bank]>=0) 
			     {
				    erased += s_last[bank] - s_first[bank] + 1;
			     	debug ("Erase Flash from 0x%08lx to 0x%08lx ""in Bank # %ld ",info->start[s_first[bank]],(s_last[bank] == info->sector_count) ?info->start[0] + info->size - 1:info->start[s_last[bank]+1] - 1,bank+1);
				    rcode = flash_erase (info, s_first[bank], s_last[bank]);   //传递进去的是扇区的索引,从哪个扇区到那个扇区
			     }
	       }
		printf ("Erased %d sectors\n", erased);   //打印出擦除扇区的个数
	} 
	else if (rcode == 0) 
	{
		puts ("Error: start and/or end address"
			" not on sector boundary\n");
		rcode = 1;
	}
	return rcode;
}








/*
 * The user interface starts numbering for Flash banks with 1
 * for historical reasons.
 */

/*
 * this routine looks for an abbreviated flash range specification.
 * the syntax is B:SF[-SL], where B is the bank number, SF is the first
 * sector to erase, and SL is the last sector to erase (defaults to SF).
 * bank numbers start at 1 to be consistent with other specs, sector numbers
 * start at zero.
 *
 * returns:	1	- correct spec; *pinfo, *psf and *psl are
 *			  set appropriately
 *		0	- doesn't look like an abbreviated spec
 *		-1	- looks like an abbreviated spec, but got
 *			  a parsing error, a number out of range,
 *			  or an invalid flash bank.
 */
static int abbrev_spec (char *str, flash_info_t ** pinfo, int *psf, int *psl)
{
	flash_info_t *fp;
	int bank, first, last;
	char *p, *ep;

	if ((p = strchr (str, ':')) == NULL)
		return 0;
	*p++ = '\0';

	bank = simple_strtoul (str, &ep, 10);
	if (ep == str || *ep != '\0' ||bank < 1 || bank > CFG_MAX_FLASH_BANKS ||
		(fp = &flash_info[bank - 1])->flash_id == FLASH_UNKNOWN)
		return -1;

	str = p;
	if ((p = strchr (str, '-')) != NULL)
		*p++ = '\0';

	first = simple_strtoul (str, &ep, 10);
	if (ep == str || *ep != '\0' || first >= fp->sector_count)
		return -1;

	if (p != NULL) 
	{
		last = simple_strtoul (p, &ep, 10);
		if (ep == p || *ep != '\0' ||last < first || last >= fp->sector_count)
			return -1;
	} 
	else 
	{
		last = first;
	}

	*pinfo = fp;
	*psf = first;
	*psl = last;

	return 1;
}







static int flash_fill_sect_ranges (ulong addr_first, ulong addr_last,int *s_first, int *s_last,int *s_count )
{
	flash_info_t *info;
	ulong bank;
	int rcode = 0;

	*s_count = 0;

	for (bank=0; bank < CFG_MAX_FLASH_BANKS; ++bank) 
	{
		s_first[bank] = -1;	/* first sector to erase	*/
		s_last [bank] = -1;	/* last  sector to erase	*/
	}

	for (bank=0,info=&flash_info[0];(bank < CFG_MAX_FLASH_BANKS) && (addr_first <= addr_last);++bank, ++info) 
	{
		ulong b_end;
		int sect;
		short s_end;

		if (info->flash_id == FLASH_UNKNOWN) 
		{
			continue;
		}

		b_end = info->start[0] + info->size - 1;	/* bank end addr *///flash的最后地址
		s_end = info->sector_count - 1;			/* last sector   */     //最后一个扇区的索引


		for (sect=0; sect < info->sector_count; ++sect) 
		{
			ulong end;	/* last address in current sect	*/

			end = (sect == s_end) ? b_end : info->start[sect + 1] - 1;  //当前扇区的结束地址

			if (addr_first > end)   //如果erase 的第一个参数大于该扇区的结束地址,则查找下一个扇区
				continue;
			if (addr_last < info->start[sect])             //当前扇区的起始地址
				continue;
      //找出erase的两个地址位于 哪两个扇区之间
			if (addr_first == info->start[sect]) //判断其始地址是不是当前扇区的起始物理地址
			{
				s_first[bank] = sect;
			}
			if (addr_last  == end) 
			{
				s_last[bank]  = sect;
			}
		}
		if (s_first[bank] >= 0)    //如果成立,说明扇区的起始地址是符合要求的
		{
			if (s_last[bank] < 0)    //如果结束地址不在 某个扇区的结束地址
			{
				if (addr_last > b_end)   //还要判断结束地址是不是超出了flash地址的范围
				{
					s_last[bank] = s_end;  //超出,则赋予最后一个扇区的索引
				} 
				else                      //没有超出且  结束地址不在某个扇区的结束地址 
				{
					puts ("Error: end address" " not on sector boundary\n");
					rcode = 1;
					break;
				}
			}
			if (s_last[bank] < s_first[bank]) 
			{
				puts ("Error: end sector" " precedes start sector\n");
				rcode = 1;
				break;
			}
			sect = s_last[bank];     
			addr_first = (sect == s_end) ? b_end + 1: info->start[sect + 1];
			(*s_count) += s_last[bank] - s_first[bank] + 1;   //返回要插除扇区的个数
		} 
		else if (addr_first >= info->start[0] && addr_first < b_end) //如果地址在flash的地址范围内
		{
			puts ("Error: start address not on sector boundary\n");    //
			rcode = 1;
			break;
		} 
		else if (s_last[bank] >= 0) 
		{
			puts ("Error: cannot span across banks when they are"
			       " mapped in reverse order\n");
			rcode = 1;
			break;
		}
	}

	return rcode;
}






int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	ushort result;
	int iflag, cflag, prot, sect;
	int rc = ERR_OK;
	int chip;

	/* first look for protection bits */

	if (info->flash_id == FLASH_UNKNOWN)
		return ERR_UNKNOWN_FLASH_TYPE;

	if ((s_first < 0) || (s_first > s_last)) 
	{
		return ERR_INVAL;
	}

	if ((info->flash_id & FLASH_VENDMASK) !=(AMD_MANUFACT & FLASH_VENDMASK)) 
	{
		return ERR_UNKNOWN_FLASH_VENDOR;
	}

	prot = 0;
	for (sect = s_first; sect <= s_last; ++sect)    //判断哪些扇区受保护
	{
		if (info->protect[sect]) 
		{
			prot++;
		}
	}
	if (prot)
		return ERR_PROTECTED;               //如果擦除的扇区是受到保护的,则返回

	/*
	 * Disable interrupts which might cause a timeout
	 * here. Remember that our exception vectors are
	 * at address 0 in the flash, and we don't want a
	 * (ticker) exception to happen while the flash
	 * chip is in programming mode.
	 */
	cflag = icache_status ();
	icache_disable ();
	iflag = disable_interrupts ();

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) 
	{
		printf ("Erasing sector %2d ... ", sect);

		/* arm simple, non interrupt dependent timer */
		reset_timer_masked ();

		if (info->protect[sect] == 0) 
		{	/* not protected */
			vu_short *addr = (vu_short *) (info->start[sect]);

			MEM_FLASH_ADDR1 = CMD_UNLOCK1;
			MEM_FLASH_ADDR2 = CMD_UNLOCK2;
			MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;

			MEM_FLASH_ADDR1 = CMD_UNLOCK1;
			MEM_FLASH_ADDR2 = CMD_UNLOCK2;
			*addr = CMD_ERASE_CONFIRM;

			/* wait until flash is ready */
			chip = 0;

			do 
			{
				result = *addr;

				/* check timeout */
				if (get_timer_masked () >
				    CFG_FLASH_ERASE_TOUT) 
				{
					MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
					chip = TMO;
					break;
				}

				if (!chip&& (result & 0xFFFF) & BIT_ERASE_DONE)
					chip = READY;

				if (!chip&& (result & 0xFFFF) & BIT_PROGRAM_ERROR)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -