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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

一种通过U盘热插拔的升级方法

發布時間:2025/4/16 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一种通过U盘热插拔的升级方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊打開鏈接

在調試Android驅動中,有時會遇到無法使用adb的情況,如果能通過U盤的熱插拔能運行shell命令,就可解決adb無法使用的困境。

???????? 基本思路是是安裝一個驅動,該驅動負責監測usb的插拔事件,然后通過異步通知發給上層的應用,應用通過讀取u盤中的腳本,通過system運行腳本里面的函數。

  驅動文件如下 

[plain]?view plaincopy
  • #include?<linux/module.h>??
  • #include?<linux/usb.h>??
  • #include?<linux/miscdevice.h>??
  • ??
  • #define?DEVICE_NAME?"usbupdate"??
  • static?struct?fasync_struct?*usbupdate_async_queue;??
  • static?struct?miscdevice?usbupdate_dev;??
  • ??
  • ??
  • int?usbupdate_open(struct?inode?*node,?struct?file?*filp)??
  • {??
  • ????return?0;??
  • }??
  • ??
  • int?usbupdate_fasync(int?fd,?struct?file?*filp,?int?mode)??
  • {??
  • ????return?fasync_helper(fd,?filp,?mode,?&usbupdate_async_queue);??
  • }??
  • ??
  • int?usbupdate_release(struct?inode?*node,?struct?file?*filp)??
  • {??
  • ????usbupdate_fasync(-1,?filp,?0);??
  • ????return?0;??
  • }??
  • ??
  • static?struct?file_operations?usbupdate_dev_fops={??
  • ????.owner??????????=?THIS_MODULE,??
  • ????.open???????????=?usbupdate_open,??
  • ????.fasync?????????=?usbupdate_fasync,??
  • ????.release????????=?usbupdate_release,??
  • };??
  • ??
  • ??
  • static?struct?miscdevice?usbupdate_dev?=?{??
  • ????.minor??????????=?MISC_DYNAMIC_MINOR,??
  • ????.name???????????=?DEVICE_NAME,??
  • ????.fops???????????=?&usbupdate_dev_fops,??
  • };??
  • ??
  • ??
  • static?int?usbupdate_notify(struct?notifier_block?*self,?unsigned?long?action,?void?*dev)??
  • {??
  • ????switch?(action)?{??
  • ????case?USB_DEVICE_ADD:??
  • ????????????printk("usb?device?add\n");??
  • ????????????kill_fasync(&usbupdate_async_queue,?SIGIO,?POLL_IN);??
  • ????????break;??
  • ????case?USB_DEVICE_REMOVE:??
  • ????????????printk("usb?device?remove\n");??
  • ????????break;??
  • ????}??
  • ????return?NOTIFY_OK;??
  • }??
  • ??
  • static?struct?notifier_block?usbupdate_nb?=?{??
  • ????.notifier_call?=usbupdate_notify,??
  • };??
  • ??
  • static?int?__init?update_init(void)???
  • {??
  • ????int?ret;??
  • ????usb_register_notify(&usbupdate_nb);??
  • ????ret?=?misc_register(&usbupdate_dev);??
  • ????printk("%s\n",__func__);??
  • ????return?ret;??
  • }??
  • ??
  • static?void?__exit?update_exit(void)??
  • {??
  • ????misc_deregister(&usbupdate_dev);??
  • ????printk("%s\n",__func__);??
  • }??
  • ??
  • module_init(update_init);??
  • module_exit(update_exit);??
  • ??
  • MODULE_LICENSE("GPL");??
  • MODULE_AUTHOR("www");??

  • 應用層的文件為update.c

    [plain]?view plaincopy
  • #include?<stdio.h>??
  • #include?<stdlib.h>????
  • #include?<sys/types.h>??
  • #include?<sys/wait.h>??
  • #include?<sys/stat.h>??
  • #include?<sys/select.h>??
  • #include?<fcntl.h>??
  • #include?<unistd.h>??
  • #include?<signal.h>??
  • #include?<string.h>??
  • #include?<cutils/log.h>???
  • ??
  • #define?DEVICE_POINT?"/dev/usbupdate"??
  • #define?LOG_TAG??"usbupdate"??
  • #define?filename?"/mnt/udisk/update.sh"?//升級腳本的路徑,不同機型的u盤掛載路徑不同,需根據機型修改??
  • ??
  • ??
  • int?usb_update_state=0;??
  • int?fd;???
  • int?status;??
  • void?systemstatus(int?status){??
  • ????if?(-1?==?status)?{????
  • ????????SLOGE("system?error!");????
  • ????}????
  • ????else??{????
  • ????????SLOGE("exit?status?value?=?[0x%x]\n",?status);????
  • ????????if?(WIFEXITED(status)){????
  • ????????????if?(0?==?WEXITSTATUS(status)){????
  • ????????????????SLOGE("run?shell?script?successfully.\n");????
  • ????????????}????
  • ????????????else{????
  • ????????????????SLOGE("run?shell?script?fail,?script?exit?code:?%d\n",?WEXITSTATUS(status));????
  • ????????????}????
  • ????????}????
  • ????????else{????
  • ????????????SLOGE("exit?status?=?[%d]\n",?WEXITSTATUS(status));????
  • ????????}????
  • ????}?????
  • }???
  • ??
  • int?read_file(void)??
  • {??
  • ???FILE?*fp;??
  • ???char?str[1024];??
  • ???char?*buf;??
  • ???buf=(char?*)malloc(1024);??
  • ???if(buf==NULL){??
  • ???????SLOGE("malloc?memory?err\n");??
  • ???????return?-1;??
  • ???}??
  • ???SLOGE("malloc?memory?ok\n");??
  • ???fp=fopen(filename,"r");??
  • ???if(fp==NULL){??
  • ????????SLOGE("open?err!\n");??
  • ????????return?-1;??
  • ???}??
  • ???SLOGE("open?ok!\n");??
  • ???while(!feof(fp)){??
  • ???if(fgets(str,1024,fp)==NULL)??
  • ??????break;??
  • ????????SLOGE("the?msg?is?%s?and?the?length?is?%d?%d\n",str,strlen(str),sizeof(str));??
  • ????????status=system(str);??
  • ????????systemstatus(status);?????
  • ???}??
  • ???fclose(fp);??
  • ???return?0;??
  • }??
  • ??
  • ??
  • ??
  • void?sig_handler(int?sig)??
  • {??
  • ????SLOGE("%s\n",?__FUNCTION__);??
  • ????read_file();??
  • ????usb_update_state=1;??
  • }??
  • ??
  • void?open_usb_update_point(void)??
  • {?????
  • ????int?f_flags;??
  • ????fd=open(DEVICE_POINT,?O_RDWR);??
  • ????if(fd?<?0){??
  • ????????SLOGE("open");??
  • ????????return;??
  • ????}??
  • ????signal(SIGIO,?sig_handler);??
  • ????fcntl(fd,?F_SETOWN,?getpid());??
  • ????f_flags?=?fcntl(fd,?F_GETFL);??
  • ????fcntl(fd,?F_SETFL,?FASYNC?|?f_flags);??
  • }??
  • ??
  • int?main(int?argc,char?**argv)??
  • {??
  • ????open_usb_update_point();??
  • ????while(1){??
  • ????????sleep(1);??
  • ????//??if(usb_update_state)??
  • ????//??????break;??
  • ??????????
  • ????}??
  • ????SLOGE("usb?update?finish\n");??
  • ????close(fd);??
  • ????return?0;??
  • }??

  • 相應的Android.mk文件如下

    [plain]?view plaincopy
  • LOCAL_PATH?:=?$(call?my-dir)??
  • include?$(CLEAR_VARS)??
  • LOCAL_MODULE_TAGS?:=?optional??
  • LOCAL_PRELINK_MODULE?:=?false??
  • LOCAL_SHARED_LIBRARIES?:=?liblog??
  • LOCAL_MODULE?:=?update??
  • LOCAL_SRC_FILES?:=?$(call?all-subdir-c-files)??
  • include?$(BUILD_EXECUTABLE)??
  • 在Android源碼的根路徑,source build/envsetup.sh,lunch選擇具體機型,通過mmm -B 應用程序路徑編譯該應用程序成可執行文件,并丟進/system/bin/。

    在init.rc通過如下服務啟動update服務,由于需要可執行權限,需要在前面加上

    [plain]?view plaincopy
  • chmod?0777??/system/bin/update??
  • [plain]?view plaincopy
  • service?loaddriver?/system/bin/update????
  • ???????class?main????
  • ???????user?root????
  • ???????group?root????
  • ???????oneshot????
  • 當然,還必須保證驅動在該服務起來之前加載,否則該服務會由于打開節點錯誤而退出。

    然后將升級腳本拷貝到u盤,接上u盤,就可運行u盤上的腳本了。升級腳本示例如下

    [plain]?view plaincopy
  • mount?-o?remount?/system??
  • touch?/system/dddd??
  • mkdir?/system/gggg??
  • insmod?/system/wwww.ko??
  • cp?/system/update.ko?/system/??
  • reboot??

  • 總結

    以上是生活随笔為你收集整理的一种通过U盘热插拔的升级方法的全部內容,希望文章能夠幫你解決所遇到的問題。

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