日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

u-boot分析三

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 u-boot分析三 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

繼續分析,u-boot怎么實現從網頁加載固件實現web升級呢!是嵌入式了uip小型web服務器,可以參看manfeel的博文,在u-boot上移植uip的過程: https://blog.csdn.net/manfeel/article/details/13096075

現分析u-boot_mod中的httpd的代碼:

u-boot上電初始化之后,進入board_init_r,如果想要通過web加載內核鏡像,則需要初始化網絡設備,在初始化完成后進入main_loop循環中:

#if defined(CONFIG_CMD_NET)all_led_on();eth_initialize(gd->bd);all_led_off(); #endif/* main_loop() can return to retry autoboot, if so just run it again */for (;;)main_loop(); 復制代碼

在main_loop ,沒有u-boot命令執行,則加載網絡循環NetLoopHttpd();:

#if defined(CONFIG_CMD_HTTPD)puts(" Starting web server for update...\n\n");NetLoopHttpd(); #elseputs("\n"); #endif 復制代碼

NetLoopHttpd()函數,對網絡進行初始化,加入uip web服務器,連接終端:

/* *************************************** HTTP web server for web failsafe mode****************************************/ int NetLoopHttpd(void){bd_t *bd = gd->bd;unsigned short int ip[2];unsigned char ethinit_attempt = 0;struct uip_eth_addr eaddr;#ifdef CONFIG_NET_MULTINetRestarted = 0;NetDevExists = 0; #endif/* XXX problem with bss workaround *///初始化網絡參數NetArpWaitPacketMAC = NULL;NetArpWaitTxPacket = NULL;NetArpWaitPacketIP = 0;NetArpWaitReplyIP = 0;NetArpWaitTxPacket = NULL;NetTxPacket = NULL;if(!NetTxPacket){int i;// Setup packet buffers, aligned correctly.NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;for(i = 0; i < PKTBUFSRX; i++){NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN;}}if(!NetArpWaitTxPacket){NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;NetArpWaitTxPacketSize = 0;}// restart labelrestart:eth_halt();#ifdef CONFIG_NET_MULTIeth_set_current(); #endif // eth_init初始化網絡設備while(ethinit_attempt < 10){if(eth_init(bd)){ethinit_attempt = 0;break;} else {ethinit_attempt++;eth_halt();milisecdelay(1000);}}if(ethinit_attempt > 0){eth_halt();printf_err("couldn't initialize eth (cable disconnected?)!\n\n");return(-1);}// get MAC address //獲取mac地址 #ifdef CONFIG_NET_MULTImemcpy(NetOurEther, eth_get_dev()->enetaddr, 6); #elseeth_getenv_enetaddr("ethaddr", NetOurEther); #endifeaddr.addr[0] = NetOurEther[0];eaddr.addr[1] = NetOurEther[1];eaddr.addr[2] = NetOurEther[2];eaddr.addr[3] = NetOurEther[3];eaddr.addr[4] = NetOurEther[4];eaddr.addr[5] = NetOurEther[5];// set MAC address 設置uip web的mac地址uip_setethaddr(eaddr);// set ip and other addresses// TODO: do we need this with uIP stack?NetCopyIP(&NetOurIP, &bd->bi_ip_addr);NetOurGatewayIP = getenv_IPaddr("gatewayip");NetOurSubnetMask = getenv_IPaddr("netmask");NetOurVLAN = getenv_VLAN("vlan");NetOurNativeVLAN = getenv_VLAN("nvlan");// start server...printf("HTTP server is starting at IP: %ld.%ld.%ld.%ld\n", (bd->bi_ip_addr & 0xff000000) >> 24, (bd->bi_ip_addr & 0x00ff0000) >> 16, (bd->bi_ip_addr & 0x0000ff00) >> 8, (bd->bi_ip_addr & 0x000000ff));HttpdStart(); // HttpdStart()函數初開始進入web的http服務// set local host ip address 為連接的主機終端分配IP地址ip[0] = ((bd->bi_ip_addr & 0xFFFF0000) >> 16);ip[1] = (bd->bi_ip_addr & 0x0000FFFF);uip_sethostaddr(ip);// set network mask (255.255.255.0 -> local network)ip[0] = ((0xFFFFFF00 & 0xFFFF0000) >> 16);ip[1] = (0xFFFFFF00 & 0x0000FFFF);uip_setnetmask(ip);// should we also set default router ip address?//uip_setdraddr();// show current progress of the processdo_http_progress(WEBFAILSAFE_PROGRESS_START);webfailsafe_is_running = 1;int led_off = 0;int cnt_up = 1;int cnt = 0;// infinite loopfor(;;){if (cnt == led_off)all_led_off();else if (cnt == 0)all_led_on();cnt++;if (cnt == 1024) {cnt = 0;if (cnt_up) {led_off++;if (led_off == 1024)cnt_up = 0;} else {led_off--;if (led_off == 0)cnt_up = 1;}}/** Check the ethernet for a new packet.* The ethernet receive routine will process it.*/if(eth_rx() > 0){HttpdHandler();}// if CTRL+C was pressed -> return!if(ctrlc()){eth_halt();// reset global variables to default statewebfailsafe_is_running = 0;webfailsafe_ready_for_upgrade = 0;webfailsafe_upgrade_type = WEBFAILSAFE_UPGRADE_TYPE_FIRMWARE;/* Invalidate the last protocol */eth_set_last_protocol(BOOTP);all_led_off();printf("\nWeb failsafe mode aborted!\n\n");return(-1);}// until upload is not completed, get back to the start of the loopif(!webfailsafe_ready_for_upgrade){continue;}// stop eth interfaceeth_halt();// show progressdo_http_progress(WEBFAILSAFE_PROGRESS_UPLOAD_READY);// try to make upgrade!if(do_http_upgrade(NetBootFileXferSize, webfailsafe_upgrade_type) >= 0){milisecdelay(500);do_http_progress(WEBFAILSAFE_PROGRESS_UPGRADE_READY);milisecdelay(500);/* reset the board */do_reset(NULL, 0, 0, NULL);}break;}// reset global variables to default statewebfailsafe_is_running = 0;webfailsafe_ready_for_upgrade = 0;webfailsafe_upgrade_type = WEBFAILSAFE_UPGRADE_TYPE_FIRMWARE;NetBootFileXferSize = 0;do_http_progress(WEBFAILSAFE_PROGRESS_UPGRADE_FAILED);all_led_off();// go to restartgoto restart;return(-1); }復制代碼

HttpdStart()函數,啟動了uip http服務的初始化:

// start http daemon void HttpdStart(void){uip_init(); //初始化uip的基本屬性和參數httpd_init(); // } 復制代碼

httpd_init()函數開始初始化web服務器,并設置端口號80:

// http server init void httpd_init(void){fs_init();uip_listen(HTONS(80)); } 復制代碼

初始化完成之后,使用函數do_http_progress()監控當前進程的運行狀態, WEBFAILSAFE_PROGRESS_START為啟動進程:

// show current progress of the processdo_http_progress(WEBFAILSAFE_PROGRESS_START); 復制代碼

進入for(;;)循環之后,在HttpdHandler()函數中調用uip_periodic()函數,從這個函數開始,啟動web服務器,向終端發送數據,進行交互操作:

for(i = 0; i < UIP_CONNS; i++){uip_periodic(i);if(uip_len > 0){uip_arp_out();NetSendHttpd();}}if(++arptimer == 20){uip_arp_timer();arptimer = 0;} 復制代碼

而實際uip_periodic()開啟了uip TCP的網絡進程uip_process :

#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \uip_process(UIP_TIMER); } while (0) 復制代碼

uip_process()中進行一些列檢測后通過調用回調函數http_appcall,從主機終端獲取通過tftp傳輸過來的固件數據。

// called for http server appvoid httpd_appcall(void) 復制代碼

httpd_appcall()中httpd_findandstore_firstchunk()加載固件,

if(httpd_findandstore_firstchunk()){data_start_found = 1;} else {data_start_found = 0;} 復制代碼

如果能夠獲取固件,并進行檢測和校驗成功,則在繼續在NetLoopHttpd中執行下一步,將有效固件NetBootFileXferSize傳入do_http_upgrade開始執行upgrade

// try to make upgrade!if(do_http_upgrade(NetBootFileXferSize, webfailsafe_upgrade_type) >= 0){milisecdelay(500);do_http_progress(WEBFAILSAFE_PROGRESS_UPGRADE_READY);milisecdelay(500);/* reset the board */do_reset(NULL, 0, 0, NULL);} 復制代碼

do_http_progress()通過執行u-boot命令行命令erase擦除數據,cp.d 命令寫入數據,至此,upgrade完成,

總結

以上是生活随笔為你收集整理的u-boot分析三的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。