當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]根據(jù)根目錄makefile文件得知系統(tǒng)從start.S啟動(dòng),在start.S里面看到函數(shù)跳轉(zhuǎn)到start_armboot 里面調(diào)用了flash_init ()初始化,這里我們知道是對(duì)flash進(jìn)行初始

根據(jù)根目錄makefile文件得知系統(tǒng)從start.S啟動(dòng),在start.S里面看到函數(shù)跳轉(zhuǎn)到start_armboot 里面調(diào)用了flash_init ()初始化,這里我們知道是對(duì)flash進(jìn)行初始化。那么這個(gè)函數(shù)在哪里呢? 在board/samsung/smdk2440/flash.c下。于是我們?cè)谶@個(gè)flash.c文件下分析flash

????????????? 我用的norflash是EN29LV160AB這個(gè)型號(hào),和uboot源碼里有些出入 所以在分析的過程中我們適當(dāng)更改部分配置

先從宏定義開始看

#define FLASH_BANK_SIZE?PHYS_FLASH_SIZE??? //從字面分析 應(yīng)該是定義flashBANK空間? 我們的flash是2M的 所有后面的PHYS_FLASH_SIZE???= 0x20000000

#define MAIN_SECT_SIZE? 0x8000?/*?32 KB */???? //定義了主要的sect(扇區(qū))大小,看EN29LV手冊(cè)? 我們總共有35個(gè)扇區(qū) 31個(gè)大小為32K

flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

//其中CONFIG_SYS_MAX_FLASH_BANKS在smdk2410.h里定義#define CONFIG_SYS_MAX_FLASH_SECT?(35)?/* max number of sectors on one chip */


#define CMD_READ_ARRAY??0x000000F0? //下面幾個(gè)宏定義在EN29LV里面都有說明 是常用的命令數(shù)據(jù)
#define CMD_UNLOCK1??0x000000AA
#define CMD_UNLOCK2??0x00000055
#define CMD_ERASE_SETUP??0x00000080
#define CMD_ERASE_CONFIRM?0x00000030
#define CMD_PROGRAM??0x000000A0
#define CMD_UNLOCK_BYPASS?0x00000020

//以下兩個(gè)宏為EN29LV手冊(cè)中提到的命令寫入的地址一個(gè)是0x555 一個(gè)是2AA 至于為什么左移一位,是設(shè)計(jì)時(shí) norflash的地址A0通常接ARM芯片地址的A1為 所以地址左移

#define MEM_FLASH_ADDR1??(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2??(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))

#define BIT_ERASE_DONE??0x00000080
#define BIT_RDY_MASK??0x00000080
#define BIT_PROGRAM_ERROR?0x00000020
#define BIT_TIMEOUT??0x80000000?/* our flag */

#define READY 1
#define ERR?? 2
#define TMO?? 4

//搞清楚了上面的宏定義 再看下面的幾個(gè)函數(shù)就好理解多了。。。。

ulong flash_init (void)????? //flash初始化函數(shù)
{
?int i, j;
?ulong size = 0;

?for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {?????? //對(duì)BANK區(qū)初始化 一般只用到BANK0 所以這里只循環(huán)一次? 這里是通用寫法
??ulong flashbase = 0;

??flash_info[i].flash_id =???????? //根據(jù)flash型號(hào) 賦予flashid號(hào) 我們也可以自定義
#if defined(CONFIG_AMD_LV400)
???(AMD_MANUFACT & FLASH_VENDMASK) |
???(AMD_ID_LV400B & FLASH_TYPEMASK);
#elif defined(CONFIG_AMD_LV800)
???(AMD_MANUFACT & FLASH_VENDMASK) |
???(AMD_ID_LV800B & FLASH_TYPEMASK);
#else
#error "Unknown flash configured"
#endif
???flash_info[i].size = FLASH_BANK_SIZE;????????????? //賦值當(dāng)前BANK中flash占用大小? 這里我們的norflash才2M? arm9一個(gè)bank有128M 我們只占用了2M

??flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;???????????????//有多少個(gè)扇區(qū)?前面提到 總共35個(gè)
??memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);??? //受保護(hù)的扇區(qū)
??if (i == 0)
???flashbase = PHYS_FLASH_1;???????????????????????????????? //flash起始地址? = 0x00000000
??else
???panic ("configured too many flash banks!n");
for (j = 0; j < flash_info[i].sector_count; j++)?
{
??? if (j <= 3)?
?? {
??????? /* 1st one is 8 KB */
?????? if (j == 0)?
????? {
???????????? flash_info[i].start[j] = flashbase + 0;?????? //由EN29LV手冊(cè) 第一個(gè)扇區(qū)大小為8K? 起始地址為0x00000000
????? }

????? /* 2nd and 3rd are both 4 KB */
????? if ((j == 1) || (j == 2))?
??? ?{
?????????? flash_info[i].start[j] = flashbase + 0x2000 + (j - 1) * 0x1000;??? //第二個(gè)和第三個(gè)扇區(qū)大小為4K 起始地址緊跟在8K后
?????}

???? /* 4th?16 KB */
???? if (j == 3)?
?? ?{
?????????? flash_info[i].start[j] = flashbase + 0x4000;
??? ?}
?}?
?else?
?{
????? ?flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE;??????//其余31個(gè)扇區(qū)皆為32K
?}
}
size += flash_info[i].size;?????? //獲得整個(gè)flash的大小 2M

?flash_protect (FLAG_PROTECT_SET,
???????? CONFIG_SYS_FLASH_BASE,
???????? CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
???????? &flash_info[0]);

?flash_protect (FLAG_PROTECT_SET,
???????? CONFIG_ENV_ADDR,
???????? CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);

?return size;
}

int flash_erase (flash_info_t * info, int s_first, int s_last)??? // flash擦除函數(shù)

{
?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;
?}????????????????????? //以上都是一些驗(yàn)證信息 flash不對(duì) 提示錯(cuò)誤

?prot = 0;
?for (sect = s_first; sect <= s_last; ++sect) {?????????????? //如果有受保護(hù)扇區(qū) 也擦除不成功
??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++) {????? //按扇區(qū)一個(gè)個(gè)擦除
??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]);??????????? //從第一個(gè)扇區(qū)開始擦除

???MEM_FLASH_ADDR1 = CMD_UNLOCK1;????????????????????? //前面提到過 這些EN29LV手冊(cè)里都有提示? 就是往flash里寫命令的格式
???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 () >
??????? CONFIG_SYS_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)
?????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;
}

static int write_hword (flash_info_t * info, ulong dest, ushort data)??? //向flash里寫一個(gè)半字 16bit
{
?vu_short *addr = (vu_short *) dest;???????????????????????? //dest表示flash里的地址
?ushort result;
?int rc = ERR_OK;
?int cflag, iflag;
?int chip;

?/*
? * Check if Flash is (sufficiently) erased
? */
?result = *addr;
?if ((result & data) != data)????????????????? //檢查flash是否擦除 擦除后就全是FFFF了
??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;?????????????????????? //手冊(cè)里的寫半字命令
?*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 () > CONFIG_SYS_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)????????????????? //flash寫?? 會(huì)調(diào)用上面的寫hword命令? 這個(gè)是寫一片
{
?ulong cp, wp;
?int l;
?int i, rc;
?ushort data;

?wp = (addr & ~1);?/* get lower word aligned address */

?/*
? * handle unaligned start bytes
? */
?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);
??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);
}

?

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉