📄 u-boot代码记录.c
字号:
chip = ERR;
} while (!chip);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
if (chip == ERR)
{
rc = ERR_PROG_ERROR;
goto outahere;
}
if (chip == TMO)
{
rc = ERR_TIMOUT;
goto outahere;
}
printf ("ok.\n");
}
else
{ /* it was protected */
printf ("protected!\n");
}
}
if (ctrlc ())
printf ("User Interrupt!\n");
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked (10000);
if (iflag)
enable_interrupts ();
if (cflag)
icache_enable ();
return rc;
}
int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong bank;
#ifdef CONFIG_HAS_DATAFLASH
dataflash_print_info();
#endif
if (argc == 1) { /* print info for all FLASH banks */
for (bank=0; bank <CFG_MAX_FLASH_BANKS; ++bank)
{
printf ("\nBank # %ld: ", bank+1);
flash_print_info (&flash_info[bank]);
}
return 0;
}
bank = simple_strtoul(argv[1], 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 ("\nBank # %ld: ", bank);
flash_print_info (&flash_info[bank-1]);
return 0;
}
void flash_print_info (flash_info_t * info)
{
int i;
switch (info->flash_id & FLASH_VENDMASK)
{
case (AMD_MANUFACT & FLASH_VENDMASK):
printf ("AMD: ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK)
{
case (AMD_ID_LV400B & FLASH_TYPEMASK):
printf ("1x Amd29LV400BB (4Mbit)\n");
break;
case (AMD_ID_LV800B & FLASH_TYPEMASK):
printf ("1x Amd29LV800BB (8Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
goto Done;
break;
}
printf (" Size: %ld MB in %d Sectors\n",info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:;
}
volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
{
vu_short *addr = (vu_short *) dest;
ushort result;
int rc = ERR_OK;
int cflag, iflag;
int chip;
/*
* Check if Flash is (sufficiently) erased
*/
result = *addr;
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* 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 ();
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
*addr = CMD_PROGRAM;
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
/* wait until flash is ready */
chip = 0;
do {
result = *addr;
/* check timeout */
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT)
{
chip = ERR | TMO;
break;
}
if (!chip && ((result & 0x80) == (data & 0x80)))
chip = READY;
if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR))
{
result = *addr;
if ((result & 0x80) == (data & 0x80))
chip = READY;
else
chip = ERR;
}
} while (!chip);
*addr = CMD_READ_ARRAY;
if (chip == ERR || *addr != data)
rc = ERR_PROG_ERROR;
if (iflag)
enable_interrupts ();
if (cflag)
icache_enable ();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong cp, wp;
int l;
int i, rc;
ushort data;
wp = (addr & ~1); /* get lower word aligned address */ //把最低位清0,保持字对其,addr是目的地址
/*
* handle unaligned start bytes
*/
//处理addr为非字对其的情况
if ((l = addr - wp) != 0)
{
data = 0;
for (i = 0, cp = wp; i < l; ++i, ++cp)
{
data = (data >> 8) | (*(uchar *) cp << 8);
}
for (; i < 2 && cnt > 0; ++i)
{
data = (data >> 8) | (*src++ << 8);
--cnt;
++cp;
}
for (; cnt == 0 && i < 2; ++i, ++cp)
{
data = (data >> 8) | (*(uchar *) cp << 8);
}
if ((rc = write_hword (info, wp, data)) != 0)
{
return (rc);
}
wp += 2;
}
/*
* handle word aligned part
*/
//处理字对其的情况
while (cnt >= 2) {
data = *((vu_short *) src);//从源地址读出2字节的数据,wp为目的地址且为字对其
if ((rc = write_hword (info, wp, data)) != 0)
{
return (rc);
}
src += 2;
wp += 2;
cnt -= 2;
}
if (cnt == 0)
{
return ERR_OK;
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp)
{
data = (data >> 8) | (*src++ << 8);
--cnt;
}
for (; i < 2; ++i, ++cp) {
data = (data >> 8) | (*(uchar *) cp << 8);
}
return write_hword (info, wp, data);
}
int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, dest, count;
int size;
if (argc != 4) //如果参数个数不为4个
{
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
/* Check for size specification.
*/
if ((size = cmd_get_data_size(argv[0], 4)) < 0) //zize为4
return 1;
addr = simple_strtoul(argv[1], NULL, 16); //把开始地址装换成整数
addr += base_address;
dest = simple_strtoul(argv[2], NULL, 16); //把结束地址装换成整数
dest += base_address;
count = simple_strtoul(argv[3], NULL, 16); //把要复制的字节数装换成整数
if (count == 0)
{
puts ("Zero length ???\n");
return 1;
}
//copy to flash
#ifndef CFG_NO_FLASH
/* check if we are copying to Flash */
if ( (addr2info(dest) != NULL)) //判断是不是目的地址
{
int rc;
puts ("Copy to Flash... ");
rc = flash_write ((char *)addr, dest, count*size);//count*size为总的字节数
if (rc != 0)
{
flash_perror (rc);
return (1);
}
//只有rc返回0才会输出下面语句
puts ("done\n");
return 0;
}
#endif
//copy to ram
while (count-- > 0) {
if (size == 4)
*((ulong *)dest) = *((ulong *)addr);
else if (size == 2)
*((ushort *)dest) = *((ushort *)addr);
else
*((u_char *)dest) = *((u_char *)addr);
addr += size;
dest += size;
}
return 0;
}
flash_info_t * addr2info (ulong addr)
{
flash_info_t *info;
int i;
for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info)
{
if (info->flash_id != FLASH_UNKNOWN &&addr >= info->start[0] &&addr <= info->start[0] + info->size - 1)
{
return (info);
}
}
return (NULL);
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
* Make sure all target addresses are within Flash bounds,
* and no protected sectors are hit.
* Returns:
* ERR_OK 0 - OK
* ERR_TIMOUT 1 - write timeout
* ERR_NOT_ERASED 2 - Flash not erased
* ERR_PROTECTED 4 - target range includes protected sectors
* ERR_INVAL 8 - target address not in Flash memory
* ERR_ALIGN 16 - target address not aligned on boundary
* (only some targets require alignment)
*/
//rc = flash_write ((char *)addr, dest, count*size);//count*size为总的字节数
int flash_write (char *src, ulong addr, ulong cnt)
{
int i;
ulong end = addr + cnt - 1; //目的的结束地址
flash_info_t *info_first = addr2info (addr); //目的开始地址
flash_info_t *info_last = addr2info (end ); // 目的结束地址
flash_info_t *info;
if (cnt == 0)
{
return (ERR_OK);
}
if (!info_first || !info_last) {
return (ERR_INVAL);
}
for (info = info_first; info <= info_last; ++info)
{
ulong b_end = info->start[0] + info->size; /* bank end addr */ //flash的物理结束地址
short s_end = info->sector_count - 1; //最后一个扇区的索引
for (i=0; i<info->sector_count; ++i)
{
ulong e_addr = (i == s_end) ? b_end : info->start[i + 1]; //e_addr 表示的是扇区的结束地址
if ((end >= info->start[i]) && (addr < e_addr) && (info->protect[i] != 0) ) //如果结束地址
{
return (ERR_PROTECTED);
}
}
}
/* finally write data to flash */
for (info = info_first; info <= info_last && cnt>0; ++info)
{
ulong len;
len = info->start[0] + info->size - addr; //addr是dest目的地址,计算出从flash结束地址到当前地址的有多少空间
if (len > cnt) //如果剩余的空间大于要写的字节数
len = cnt;
if ((i = write_buff(info, (uchar *)src, addr, len)) != 0)
{
return (i);
}
cnt -= len;
addr += len;
src += len;
}
return (ERR_OK);//ERR_OK=0
}
//if ((size = cmd_get_data_size(argv[0], 4)) < 0)//
int cmd_get_data_size(char* arg, int default_size)
{
/* Check for a size specification .b, .w or .l.
*/
int len = strlen(arg);
if (len > 2 && arg[len-2] == '.')
{
switch(arg[len-1]) {
case 'b':
return 1;
case 'w':
return 2;
case 'l':
return 4;
case 's':
return -2;
default:
return -1;
}
}
return default_size;
}
int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, length;
ulong i, nbytes, linebytes;
u_char *cp;
int size;
int rc = 0;
/* We use the last specified parameters, unless new ones are
* entered.
*/
addr = dp_last_addr;
size = dp_last_size;
length = dp_last_length;
if (argc < 2) //如果参数下于2
{
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
if ((flag & CMD_FLAG_REPEAT) == 0) //#define CMD_FLAG_REPEAT 0x0001 /* repeat last command */
{
/* New command specified. Check for a size specification.
* Defaults to long if no or incorrect specification.
*/
if ((size = cmd_get_data_size(argv[0], 4)) < 0)
return 1;
/* Address is specified since argc > 1
*/
addr = simple_strtoul(argv[1], NULL, 16);
addr += base_address; //base_address=0;
/* If another parameter, it is the length to display.
* Length is the number of objects, not number of bytes.
*/
if (argc > 2)
length = simple_strtoul(argv[2], NULL, 16);
}
/* Print the lines.
*
* We buffer all read data, so we can make sure data is read only
* once, and all accesses are with the specified bus width.
*/
nbytes = length * size; //要读出的直接数
do
{
char linebuf[DISP_LINE_LEN];
uint *uip = (uint *)linebuf;
ushort *usp = (ushort *)linebuf;
u_char *ucp = (u_char *)linebuf;
printf("%08lx:", addr);
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; //如果mbytes大于16则去16
for (i=0; i<linebytes; i+= size) //打印出一行
{
if (size == 4)
{
printf(" %08x", (*uip++ = *((uint *)addr))); //取出地址的内容
}
else if (size == 2)
{
printf(" %04x", (*usp++ = *((ushort *)addr)));
}
else
{
printf(" %02x", (*ucp++ = *((u_char *)addr)));
}
addr += size;
}
puts (" ");
cp = (u_char *)linebuf;
for (i=0; i<linebytes; i++)
{
if ((*cp < 0x20) || (*cp > 0x7e))
putc ('.');
else
printf("%c", *cp);
cp++;
}
putc ('\n');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -