A20硬盤格式化

1>fdisk_shell.sh文件需在linux下用vim生成 不然會出不少意想不到的問題,     若在win下生成該文件在導入linux需用busybox dos2unix fdisk_shell.sh命令轉化爲linux文件。 2>總體思路:在應用層調用fdisk_shell.sh腳本實現格式化功能。 3>實踐中發現,應用層經過system方法調用的. /fdisk_shell.sh語句只能執行fdisk_shell.sh腳本中的簡單語句   像echo命令,可是system/bin下的其餘命令及BUSYBOX命令是沒法執行的;這行命令的執行須要ROOT權限,其實   system方法是能夠實現ROOT身份的轉換,但只能執行具體的命令,或是運行腳本的命令system(". /fdisk_shell.sh");   可是要想運行腳本中的busybox命令是不成功的,只有另闢蹊徑;   最終思路是在init.rc中開啓一個守護進程rootexec,實現腳本的執行工做,應用層經過進程間通訊,實現腳本的執行。   應用層經過JNI調用startRootExec()方法,startRootExec()方法經過bind機制使rootexec實現執行腳本的任務。   也能夠用非正式的方法shocket,這樣能夠避開JNI層的調用; 4>重要代碼分析:   \root\cmds\rootexec\RootExecService.cpp:   if (-1 == status)       {           ALOGD("system error!");         return 0;       }       else       {           ALOGD("exit status value = [0x%x]\n", status);             if (WIFEXITED(status))           {               if (0 == WEXITSTATUS(status))               {                   ALOGD("run shell script successfully.\n");                 return 1;               }               else               {                   ALOGD("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));                 return 0;               }           }           else           {               ALOGD("exit status = [%d]\n", WEXITSTATUS(status));                return 0;           }       }     此段代碼是檢測system方法執行腳本完成狀況,弱弱的講講system方法的返回值的問題:     system函數對返回值的處理,涉及3個階段:         階段1:建立子進程等準備工做。若是失敗,返回-1。         階段2:調用/bin/sh拉起shell腳本,若是拉起失敗或者shell未正常執行結束(參見備註1),         緣由值被寫入到status的低8~15比特位中。system的man中只說明瞭會寫了127這個值,但實測發現還會寫126等值。         階段3:若是shell腳本正常執行結束,將shell返回值填到status的低8~15比特位中。         備註1:         只要可以調用到/bin/sh,而且執行shell過程當中沒有被其餘信號異常中斷,都算正常結束。         好比:無論shell腳本中返回什麼緣由值,是0仍是非0,都算正常執行結束。即便shell腳本不存在或沒有執行權限,         也都算正常執行結束。         若是shell腳本執行過程當中被強制kill掉等狀況則算異常結束。         如何判斷階段2中,shell腳本是否正常執行結束呢?系統提供了宏:WIFEXITED(status)。若是WIFEXITED(status)爲真,         則說明正常結束。         如何取得階段3中的shell返回值?你能夠直接經過右移8bit來實現,         但安全的作法是使用系統提供的宏:WEXITSTATUS(status)。         因爲咱們通常在shell腳本中會經過返回值判斷本腳本是否正常執行,若是成功返回0,失敗返回正數。         因此綜上,判斷一個system函數調用shell腳本是否正常結束的方法應該是以下3個條件同時成立:         (1)-1 != status         (2)WIFEXITED(status)爲真         (3)0 == WEXITSTATUS(status)         注意:         根據以上分析,當shell腳本不存在、沒有執行權限等場景下時,以上前2個條件仍會成立,         此時WEXITSTATUS(status)爲127,126等數值。     因此,咱們在shell腳本中不能將127,126等數值定義爲返回值,不然沒法區分中是shell的返回值,     仍是調用shell腳本異常的緣由值。shell腳本中的返回值最好多1開始遞增。     腳本執行成功返回0,失敗1;     \myTest\jni\fdisk.cpp:     static jstring run(JNIEnv *env,jobject obj,jstring comd,jint num)             {                    char* tmpstr1 = "successed";                 char* tmpstr2 = "failed";                                  jstring jstr1 = env->NewStringUTF(tmpstr1);                 jstring jstr2 = env->NewStringUTF(tmpstr2);                                  ALOGE("fdiskShelljni.so");                 if(startRootExec(2,2))                 {                      ALOGE("startRootExec success!\n");                     return jstr1;                         }else{                     ALOGE("startRootExec failed!\n");                     return jstr2;                 }             }             此段代碼爲jni的主體,做用很簡單,執行startRootExec()方法,成功返回successed,失敗返回failed;             改文件中還實現了其餘方法,應用層調用JNI庫所需。             \myTest\src\com\fdisk\FdiskActivity.java:             改文件爲測試程序。格式化一個500G的硬盤須要很長時間,這麼,漫長的等待,花兒會不會謝呢?只有在另外的線程完成,             主線程只負責啓動thread,在thread中實現FLAG狀態的改變,             腳本執行成功JNI會返回successed,此時將FLAG置1,失敗返回failed,將FLAG置0,;             主線程根據值得變化判斷格式化是否成功。開始將FLAG置2,處理很好,讀者本身琢磨;             fdisk_shell.sh:             這個腳本所要完成的工做就是判斷目前硬盤(/dev/block/sda)裏的分區狀況,而後去刪除分區,再從新建立一個sda1的             分區。該腳本花了我很長時間,但功能很完善,除了能夠刪除主分區還能刪除擴展分區,固然這個工做能夠在RootExecService.cpp中用刪除             表頭的方法實現,我認爲這樣更好;             /system/fdisk/1.0保存的是整個硬盤的分區狀況,共有幾個分區;             /system/fdisk/1.1保存的是整個硬盤的主分區狀況,共有幾個主分區;             /system/fdisk/1.2保存的是整個硬盤的擴展分區狀況,共有幾個擴展分區;             這3個文件保存的信息是給後面命令提供參數依據;             若是你很熟悉FDISK命令的話,就會明白爲何在刪除最後一個分區的時候要另外echo?             也會明白要umount vfat格式自動掛載的8_*目錄的緣由,不然是mount不上的;             致使mount命令失敗的緣由大體爲二:1,格式化未成功;2,以前已經mount。             因此該腳本爲了保險用力的umount.             這腳本花的精力不少,讀者如果以爲有更好的方法能夠聯繫:424758702(qq) 5>整個代碼的編譯:             myTest文件要放在android4.2/package/app/下,jni庫的生成和測試apk的生成只要在myTest文件夾下mm便可。             生成的so庫會出現android/out/target/product/win_k70/system/lib/下,改庫須要的librootexec.so,若是你徹底按root目錄             下的Read文檔作了就會在android/out/target/product/win_k70/system/lib/下生成;librootexec.so這個庫和             android/out/target/product/win_k70/system/bin/下的rootexec二進制文件我是自動打包進固件裏的,             會出如今板子的system/lib和system/bin裏的(若是你徹底按文檔作了);             個人郵件wangjian1937@live.cn             文檔很粗糙,願君自琢磨。             源碼不提供,思路很重要(保密,公司要求我不得不服)。                            
相關文章
相關標籤/搜索