浏览模式: 标准 | 列表
11月
04

WiFi激活

WiFi激活不是本人首创,该方法在WebOS还只是1.0.2的时候,就已经被开发出来了,并被记录在了 http://www.webos-internals.org/wiki/Patch_webOS_Bypassing_Activation 上。

但是上面写的都是手工修改的方法,做起来比较麻烦,用MetaDoctor就会简单的多:

第一步,在patches目录下找到你需要修改的版本的目录,然后在里面创建一个空的patch文件,比如叫wifi-activation.patch。

第二步,用MetaDoctor的scripts目录下面的unpack-doctor或者unpack-rootfs把WebOS Doctor解开。

第三步,找到/usr/palm/applications/com.palm.app.firstuse/app/controllers/firstuse-util.js,复制一份,比如叫firstuse-util.new.js,然后对其修改保存。

第四步,运行diff –u firstuse-util.js firstuse-util.new.js > firstuse-util.patch,生成补丁。

第五步,同样方法修改并生成account-service.patch。

第六步,把这两个patch里的内容复制到patches目录下创建的那个wifi-activation.patch文件中,每个文件开头那两行的格式,可以按照bypass-activation.patch里面的格式改一下(我没试过不改可不可以用)。

最后,修改Makefile,在其中加上WIFI_ACTIVATION这个选项,修改方法可以参考它原来的BYPASS_ACTIVATION的代码,具体修改那几行这里就不列出来了。 上面的说明中,细心的读者也许会发现,我把Wiki里面关于app-assistant.js的修改给忽略了。不是我忘记了,而是故意的,下面就来解释为何忽略。关于app-assistant.js的修改其实就是bypass-activation.patch做的事情,不同版本的webOS的bypass-activation.patch并不相同,所以按照那个修改并不是最好的方法,最好的方法是直接在Makefile中把BYPASS_ACTIVATION这一项打开就一样了。另外,WIFI_ACTIVATION跟BYPASS_ACTIVATION并没有直接的关系,只是打开BYPASS_ACTIVATION之后,你可以在刷机之后不用插卡,但是不能用其它方式激活,只能用WIFI激活。而不打开BYPASS_ACTIVATION的话则必须插卡,但是除了可以用WIFI激活意外,也可以用2G、3G方式激活。

好了,现在运行一下MetaDoctor的make命令,你的带WIFI激活的ROM就生成了。

刷机之后,在紧急拨号菜单里就可以打开WIFI设置页了。

但这个WIFI设置有一点点小问题,就是设置完成之后,你会发现无法退出这个设置界面,要想继续激活的过程,就需要用“方块+Sym+R”来重启手机才能继续。

那如何才能让让WIFI设置界面可以在设置完成之后正常退出呢?这个思路可以参考紧急拨号界面。

在account-service.js这个文件中,有一个方法是用来打开紧急拨号界面的,我们来看一下它的代码:

JavaScript代码
 
  1. makeEmergencyCall: function (emergencyNumber) {  
  2.     Mojo.Log.info("Emegerncy call to phone app -------------------------------------------------: ",emergencyNumber);  
  3.     return new Mojo.Service.Request("palm://com.palm.applicationManager/open", {  
  4.            parameters: {  
  5.                id: 'com.palm.app.phone',  
  6.                params: {  
  7.                    "prefill": emergencyNumber,  
  8.                 "firstuse":true,  
  9.                 "locale": Account.language + '_' + Account.country   
  10.                }  
  11.            }  
  12.        });  
  13.       
  14. },  

这段代码中,我们可以看到firstuse和locale这两个参数,也就是说紧急拨号调用的就是电话程序,只不过是传入了一个firstuse参数让其可以作特殊处理(locale则是可以在调用它时设置语言)。所以,我们在紧急拨号界面下可以看到取消按钮,而普通情况下打电话则没有这个按钮。

所以,我们也可以给WIFI设置程序增加一个firstuse参数,如果要让他也能根据调用环境设置语言,我们也可以给它增加一个locale参数,不过com.palm.app.wifi本身是不支持这两个参数的,因此我们要对它进行修改。下面是对com.palm.app.wifi相关文件进行的修改:

JavaScript代码
 
  1. --- .orig/usr/palm/applications/com.palm.app.wifi/app/controllers/app-assistant.js  
  2. +++ /usr/palm/applications/com.palm.app.wifi/app/controllers/app-assistant.js  
  3. @@ -9,6 +9,16 @@  
  4.     var dashboardStage = this.controller.getStageProxy('wifidashboard');  
  5.     var networkListStage = this.controller.getStageProxy('networklist');  
  6.    
  7. +   if (params) {  
  8. +       this.firstuse = PalmSystem.isMinimal || params.firstuse === true;  
  9. +       //If the First Use passes the locale different than the current one, change the Mojo.Locale(Framework)  
  10. +       if (this.firstuse) {  
  11. +           if (params.locale && params.locale.length === 5 && params.locale != Mojo.Locale.current) {  
  12. +               Mojo.Locale.set(params.locale);  
  13. +           }  
  14. +       }  
  15. +    }  
  16. +  
  17.     if (networkListStage)  
  18.     {  
  19.         Mojo.Log.info("Wifi launch reactivate");  
  20. --- .orig/usr/palm/applications/com.palm.app.wifi/app/controllers/networklist-assistant.js  
  21. +++ /usr/palm/applications/com.palm.app.wifi/app/controllers/networklist-assistant.js  
  22. @@ -3,6 +3,7 @@  
  23.  var list_label_toggle_off = $L("Off");  
  24.  var list_label_list_other_network = $L("Join other network");  
  25.  var list_label_list_network = $L("Join network");  
  26. +var list_label_done_button = $L("Done");  
  27.    
  28.  var list_label_status_associating = $L("Connecting......");  
  29.  var list_label_status_associated = $L("...Connecting...");  
  30. @@ -70,7 +71,7 @@  
  31.              Mojo.Log.info("initialize(): called via wifi preferences with params - " + Object.toJSON(params));  
  32.              this.bRunViaPreferencesMenu = true;  
  33.              this.params = params;  
  34. -        } else if (params.hotspot) {  
  35. +        } else if (params.hotspot || params.firstuse) {  
  36.              this.params = params;  
  37.          }  
  38.          this.findNetworksHandle = undefined;  
  39. @@ -170,6 +171,17 @@  
  40.              }  
  41.          });  
  42.    
  43. +        this.doneButtonModel = {buttonLabel: list_label_done_button};        
  44. +        this.controller.setupWidget('doneButton', {type:Mojo.Widget.activityButton}, this.doneButtonModel);  
  45. +        this.doneButton = this.controller.get('doneButton');  
  46. +        if (this.params && this.params.firstuse) {  
  47. +            this.doneButton.style.display = "block";  
  48. +        }  
  49. +        else {  
  50. +            this.doneButton.style.display = "none";  
  51. +        }  
  52. +        Mojo.Event.listen(this.doneButton, 'mojo-tap'this.closeAllStages.bind(this))  
  53. +  
  54.          timing.pause('scene#networklist#setup');  
  55.  //        Mojo.Log.info("setup(): leaving");  
  56.      },  
  57. @@ -976,6 +988,10 @@  
  58.             template: 'joinwapicerts/joinwapicerts-scene',  
  59.             assistant: new JoinwapicertsAssistant(this, item)  
  60.          });  
  61. +    },  
  62. +  
  63. +    closeAllStages: function() {  
  64. +        this.controller.stageController.getAppController().closeAllStages();  
  65.      }  
  66.    
  67.  });  
  68. --- .orig/usr/palm/applications/com.palm.app.wifi/app/views/networklist/networklist-scene.html  
  69. +++ /usr/palm/applications/com.palm.app.wifi/app/views/networklist/networklist-scene.html  
  70. @@ -18,4 +18,5 @@  
  71.      <div id="wifiOffText" style="display:none;" class="palm-text-wrapper">  
  72.             <div class="palm-body-text" x-mojo-loc=''>Wi-Fi is turned off.</div>  
  73.      </div>  
  74. +    <div x-mojo-element="Button" style="display:none;" id="doneButton"></div>  
  75.  </div>  

其实很简单就是增加一个Done的按钮,这个按钮在com.palm.app.wifi启动时,如果带有firstuse这个参数就设置为可见,而这个按钮的用处就是关闭WIFI设置程序。另外,开头还会根据locale参数来设置一下语言。

那现在我们在com.palm.app.firstuse里面再调用它,只要带上这两个参数就可以了。接下来我们可能还希望在刷机第一次启动时,选择语言之前就能进行WIFI配置。最简单的方法当然就是在设置语言的页面里面也调用这个打开WIFI设置程序的方法咯。但如果你真的这样做的话,会发现你并看不到WIFI设置程序。原因是最开始执行时,被放在后面了,只有当它完全启动之后,再调用一次,他才会显示到前面来。但是我们不知道它需要多久才能启动完毕,所以我们设置几个定时器,每隔一段时间调用一次就可以啦:

JavaScript代码
 
  1. --- .orig/usr/palm/applications/com.palm.app.firstuse/app/controllers/language-assistant.js  
  2. +++ /usr/palm/applications/com.palm.app.firstuse/app/controllers/language-assistant.js  
  3. @@ -34,6 +34,7 @@  
  4.           
  5.         // Listen to ## key presses  
  6.         this.controller.listen(this.controller.sceneElement, Mojo.Event.keydown, FirstUseUtil.handleKeyPressEvent.bind(this));  
  7. +       AppAssistant.accountService.enableWifi();  
  8.     },  
  9.       
  10.     powerDownDevice: function () {  
  11. --- .orig/usr/palm/applications/com.palm.app.firstuse/app/controllers/firstuse-util.js  
  12. +++ /usr/palm/applications/com.palm.app.firstuse/app/controllers/firstuse-util.js  
  13. @@ -197,11 +197,13 @@  
  14.         }  
  15.         else{  
  16.             labels = [{label: $L('Emergency call'), command: 'emergency-call'},   
  17. +               {label: $L('Enable WiFi'), command: 'enable-wifi'},  
  18.                 {label: $L('Cancel'), command: 'cancel'}  
  19.                 ];  
  20.             if(FirstUseUtil.customerCareNumber && FirstUseUtil.customerCareNumber.length > 0) {  
  21.                 labels = [{label: $L('Emergency call'), command: 'emergency-call'},   
  22.                     {label: $L('Call customer service'), command: 'customer-care'},  
  23. +                   {label: $L('Enable WiFi'), command: 'enable-wifi'},  
  24.                     {label: $L('Cancel'), command: 'cancel'}  
  25.                 ];  
  26.             }  
  27. @@ -220,6 +222,8 @@  
  28.             Mojo.Log.info("----------------- FirstUseUtil.carrierName ----------------", FirstUseUtil.carrierName());  
  29.             var carrierName = Mojo.Environment.DeviceInfo.carrierName || (FirstUseUtil.carrierString && typeof FirstUseUtil.carrierString === "string" ? FirstUseUtil.carrierString.toUpperCase() : "");  
  30.             AppAssistant.accountService.callCustomerCare(FirstUseUtil.customerCareNumber, $L(carrierName));  
  31. +       } else if (value == "enable-wifi") {  
  32. +           AppAssistant.accountService.enableWifi();  
  33.         } else if(value == "exit"){  
  34.             if (isDemoMode){  
  35.                 new Mojo.Service.Request('palm://com.palm.oddService', {  
  36. --- .orig/usr/palm/applications/com.palm.app.firstuse/app/models/account-service.js  
  37. +++ /usr/palm/applications/com.palm.app.firstuse/app/models/account-service.js  
  38. @@ -408,6 +408,33 @@  
  39.         });  
  40.     },  
  41.       
  42. +   enableWifi: function() {  
  43. +       var method = function() {  
  44. +           return new Mojo.Service.Request("palm://com.palm.applicationManager/open", {  
  45. +               parameters: {  
  46. +                   id: 'com.palm.app.wifi',  
  47. +                   params: {  
  48. +                       "firstuse"true,  
  49. +                       "locale": Account.language + '_' + Account.country  
  50. +                   }  
  51. +               }  
  52. +           });  
  53. +       };  
  54. +       var t1 = setTimeout(function() {  
  55. +           clearTimeout(t1);  
  56. +           method();  
  57. +       }, 8000);  
  58. +       var t2 = setTimeout(function() {  
  59. +           clearTimeout(t2);  
  60. +           method();  
  61. +       }, 4000);  
  62. +       var t3 = setTimeout(function() {  
  63. +           clearTimeout(t3);  
  64. +           method();  
  65. +       }, 2000);  
  66. +       return method();  
  67. +   },  
  68. +  
  69.     makeEmergencyCall: function (emergencyNumber) {  
  70.         Mojo.Log.info("Emegerncy call to phone app -------------------------------------------------: ",emergencyNumber);  
  71.         return new Mojo.Service.Request("palm://com.palm.applicationManager/open", {  

经过这样的修改,我们就可以实现完美的开机WIFI设置了。

上面两段加起来就是WIFI激活的补丁了。我们用这个补丁来替换最开始那个wifi-activation.patch就可以啦。

不过我们还需要作一点小小的工作,那就是要把com.palm.app.wifi这个包的处理部分也要加入到Makefile中,我们可以在Makefile中寻找这段代码:

  1. ifeq (${ADD_EXTRA_CARRIERS},1)  
  2.     OLDIPKGS += pmcarrierdb  
  3. endif  

然后再它前面加入:

  1. ifeq (${WIFI_ACTIVATION},1)  
  2.     OLDIPKGS += com.palm.app.wifi  
  3. endif  

就可以啦,接下来的工作,Makefile就可以正确处理了。

最后我们运行:

make DEVICE=veer CARRIER=att all

就可以生成带有WIFI激活功能的ROM了。

11月
04

WebOS ROM修改工具

工欲善其事,必先利其器。所以,我们要先把用于修改WebOS ROM的工具找好,其实工具不多,下面先列一下这些工具:

  1. Linux(例如Ubuntu或Debian)或Mac OS X
  2. JRE
  3. Palm SDK
  4. MetaDoctor

接下来,我们就有细细讲解了。

Linux或Mac OS X

必须的!

Windows不行,因为后面要介绍的主力工具MetaDoctor不支持Windows,就算在Windows上装了Cygwin也不支持。至于是不是真是这样,我倒没有亲自验证过,www.webos-internals.org上是这样写的。具有科学态度的同学如果有时间,可以自己验证一下。

用Linux的话,它的shell是现成的,定制ROM需要到一些命令和工具在系统装好之后也都有了,比如tar、ar、unzip、make等等。另外,推荐用Ubuntu或Debian。因为就算缺少什么命令没有安装,直接用apt-get或者图形界面的软件包管理器安装就可以啦,非常方便。

用Mac OS X的话,需要把XCode一起安装一下,虽然用不到XCode本身,但需要用到它带的一些开发用的工具。另外,还需要安装MacPorts,它也依赖XCode。所以,用Mac OS X的话,比起用Ubuntu或Debian来还是比较麻烦的。

至于这两个系统怎么用这里就不再详解了,否则就跑题了。

JRE

必须的!

后面介绍的工具需要调用它来完成一些工作。

这个怎么安装,干啥用的也不介绍了。我想用webOS手机的同学应该没有不知道它的。而且资料多的很,就算真的不了解的同学也可以自己去查嘛。我就不再废话了。

Palm SDK

必须的吗?不是。它是webOS的开发包,虽然我们并不是要用它来做开发,但它在我们用于定制ROM的调试过程中会很有用。另外,MetaDoctor中也有调用它的地方,不过也不是在定制ROM的环节上。但我们装了它总没坏处。

MetaDoctor

定制WebOS ROM的主力工具。虽然它只是几个不算怎么长的脚本的集合,但是有了它,可以让你在定制ROM上做到事半功倍,比纯手工打造要方便太多了。当然,它本身内置的脚本并不一定能满足你所有的要求,但你可以扩展修改它,至于怎么扩展修改,我们下一节再举例说明。

现在先介绍它的基本功能。

http://www.webos-internals.org/wiki/Application:MetaDoctor上有关于MetaDoctor的一些英文介绍,大致涵盖了安装,基本运行方法,和一些杂七杂八的东西。所以,这些也不详细讲解了,不过为了保持文章完整性,还是要大体说一下。

安装

很简单。

只有Windows的同学,需要安装一下Linux,推荐是Ubuntu最新版。安装方式上面的英文介绍里说的是用Wubi方式,其实装在虚拟机里也一样用。

然后呢,就是安装git,安装jre,之后用git来把meta-doctor从服务器上下载下来,这样你就有了。

在Mac OS X上也差不多,不过要先安装XCode、再安装MacPorts,再用MacPorts安装md5sha1sum、gnutar、git-core、wget、gpatch这些基本工具,最后也是用git把meta-doctor从服务器上下载下来。

目录结构

从服务器上下载的meta-doctor目录下面有一个Makefile和三个目录。

这个Makefile是定制ROM的最关键的主文件,后面详解其中的关键。先说说那三个目录:

patches目录

这个目录下,保存的是一些补丁。

其中carriers目录下是某些运营商的网络配置的定制文件,doctor目录下是对刷机工具的几个补丁文件。

webos-x.x.x这些目录下面是对具体版本的ROM的一些补丁,自带的里面只有一个bypass-activation的补丁。

这些文件都是供Makefile调用的,如果有需要我们也可以把自己写的补丁放在它下面,然后对Makefile做相应修改之后,我们自己的补丁也就可以用了。

hashes目录

这个目录下,保存的是一些运营商(carriers)和手机制式(models)的散列数据。用于设置自定义ROM的运营商和手机制式用。它们也是供Makefile调用的。

scripts目录

这个目录下保存了很多宝贝脚本。

一部分是供Makefile调用的,一部分是单独使用的,还有一部分是例子。

这里面replace-md5sums.py是供Makefile调用的。

preware-ca-bundle.crt和preware-install.db也是供Makefile调用的,不过已经过时,没啥用了。

decode-hashes是解码刷机文件中recoverytool.config这个文件里面那些运营商、手机制式等Hash值用的工具。

encode-hash是教你如何实现自定义运营商、手机制式等Hash值的编码的一个例子。

unpack-doctor可以帮你把刷机的doctor的jar分解成目录和文件的工具。

unpack-rootfs跟unpack-doctor功能类似,但它只分解rootfs。

WebOS-Internals.tga是Makefile用来替换手机启动时的第一个启动画面的文件。你也可以把它替换掉。

剩下的那些xxx-xxx-1.4.5.1是用来自制某些运营商发布的某些制式的手机的1.4.5.1的刷机ROM的。xxx-xxx-2.1.0当然就是定制2.1.0的刷机ROM的咯。关于这些2.1.0的脚本的使用方法,可以参见:http://www.webos-internals.org/wiki/WebOS_2_Upgrade。因为这不是本文的重点,这里就不做更进一步的介绍了。

Makefile

这个文件才是重点要介绍的。

该文件开头有许多选项,这些是基本功能定制的开关。下面先把这些选项作个简单说明。

BYPASS_ACTIVATION

该选项的功能说明是去掉刷机后第一次启动时的激活过程。而实际上它的作用仅仅是让第一次启动的运营商网络变得无效,以至于无法激活。另外,它还有一个作用就是让机器不检查Sim卡状态。这时,你就是插一张坏卡也能开机,不插卡也能开机。但不能激活你就进不了系统啊。那怎么办呢?

如果是2.x的系统,那好办,可以在紧急拨号界面里,输入#*3386633#来启动开发者模式开关程序,打开开发者模式之后重启,第二次启动就自动进入系统了。

但如果是1.x的系统,那就麻烦了。因为上面的方法对1.x系统不适用啊。那该怎么办呢?

一种办法当然就是我们下一节介绍的WIFI激活。另一种方法则是跳过第一次启动时运行的First Use程序,也就是第二个选项。

BYPASS_FIRST_USE_APP

这个选项做的事情正如上面所说,是跳过第一次启动时运行的First Use程序,如何实现的呢?

他在rootfs(就是ROM的根分区)的/var/luna/preferences下建了两个空文件,一个是ran-first-use,另一个是first-use-profile-created,这样就可以欺骗系统在第一次运行时就认为已经运行过firstuse程序了,所以,第一次运行就进入了桌面。

2.x系统的firstuse程序跟手势教程是同一个,想要激活profile,直接运行手势教程就好了。所以就不存在什么问题。但对于1.x的系统来说,firstuse程序默认是不可见的,所以进入桌面之后,想再激活profile就难了。这一点其实开发meta-doctor的大婶们早就想到了。所以,这个选项做的第二件事情就是将/usr/palm/applications/com.palm.app.firstuse下面的appinfo.json和它的资源目录下所有语言的appinfo.json中的visible选项从false改为true。

所以,一般要实现免激活的ROM,只要打开上面两个选项就好了。

注意:BYPASS_FIRST_USE_APP这个选项在修改程序可见性时,有点小问题。使得它跟1.x的advanced configuration for app laucher这个补丁有冲突,使其无法正确安装。解决方法有很多,比如用户安装advanced configuration for app laucher前先把原始的appinfo.json文件替换回去。或者把Makefile中关于appinfo.json的修改的那一段代码注释掉。更多方法大家可以自己琢磨。

ENABLE_DEVELOPER_MODE

第三个选项是默认打开开发者模式,这样在第一次启动时,WQI就可以跟手机连接啦。这个选项打开是安全的。它的实现也很简单,就是在根分区的/var/gadget目录下建立一个novacom_enabled的空文件。

该选项只对刷机后未运行删除应用程序和数据(或完全清除)前有效。如果日后在系统的“重设选项”中选择了任何上述按钮的话,则该文件也会被清除,这样系统启动时,再次进入First Use界面时,开发者模式就关闭了。

ENABLE_BETA_FEEDS、ENABLE_ALPHA_FEEDS

第四个选项是针对preware的,该选项打开之后,可以允许preware载入测试版本的程序和补丁列表。

这两个选项的实现是在rootfs(根分区)的/var/preferences/org.webosinternals.preware目录下面建立enable-beta-feeds或enable-alpha-feeds这两个空文件。所以它们并不依赖于是否在ROM中集成preware。

INSTALL_SSH_AUTH_KEYS

这个选项不用于定制通用ROM,仅用于定制个人使用的ROM时使用。它的作用是将SSH的authorized_keys文件导入到设备的用户目录下,这样当在设备上安装了ssh监听程序后,就可以直接从自己的电脑上通过ssh来登录到设备上了。

INSTALL_WIFI_PROFILES

这个选项跟上面一样不能用于定制通用ROM,仅用于定制个人使用的ROM。它的作用是让用户刷机之后第一次启动就可以连接上WiFi,这个功能听上去很神奇,但如果你知道该怎么做才能实现时,你就会觉得很没用了。你需要先把现在设备上设置好的WiFi配置文件(/var/preferences/com.palm.wifi/ prefsDB.sl)复制到自己PC(Linux)上,路径是:~/.ssh/com.palm.wifi.prefsDB.sl 或 to ./config/com.palm.wifi.prefsDB.sl,然后开启这个选项后,在运行make时,meta-doctor会把这个文件放到你的ROM中的那个目录下。而每个人的WiFi配置各不相同,所以它不是一个通用的选项。

AUTO_INSTALL_PREWARE

这个选项的本意是系统启动后,自动通过网络安装preware。但很不幸,这个选项已经不好用了。所以你只能在注释中看到它。在下面的主要开关列表部分你并看不到它的身影。所以如果你想实现在ROM中集成preware,不要使用这个选项,后面我会介绍如何集成软件到ROM中。

DISABLE_UPLOAD_DAEMON

这是一个很有用的选项。官方ROM里有个自动上传数据到PALM服务器的功能。这个自动上传数据的功能会在后台悄悄地自动地上传系统或应用程序崩溃的相关调试信息,用户的GPS信息,每个应用程序所使用的数据,以及它们的运行时长。关掉它可以节省大量的流量。

这个选项的实现很简单,就是把/usr/bin下面的uploadd、contextupload、rdxd这三个程序的可执行权限去掉了。这样当你真的需要恢复时,只要改一下权限就好了。所以即使在刷机之后,用同样的方法也可以关闭上传功能。

DISABLE_UPDATE_DAEMON

这个是用来关闭升级服务的。通常用于定制比较旧的,官方不再提供升级的ROM时使用,在定制较新的ROM时,如果开启这个选项,对于不懂下面这段话的用户会影响后续的正常升级。

这个选项的实现跟上面那个选项差不多,它是把/usr/bin目录下的UpdateDaemon和OmaDm这两个程序的可执行权限去掉了。所以如果到时候真的系统真的有升级,用户其实也是可以通过修改这两个文件的权限来恢复升级服务功能的。同样,如果没有开启这个选项,用户在刷机后,也可以用这个方法来关闭升级服务。

DISABLE_MODEM_UPDATE

该选项的作用是禁止刷写设备的MODEM。因为对于同一款手机的同一个版本的ROM来说,MODEM通常是不会单独升级的,只有大版本升级时,MODEM才会有可能升级(例如从1.4.5到2.1),通常忽略MODEM刷写是安全的。而且它可以节省刷机的时间,刷写MODEM时,大约需要4-5分钟,禁止刷写MODEM可以节省将近1/3的刷机时间。不过,要是为了保险的话,这个选项还是不要开启的好。

它的实现方式是修改webOS.tar里面的installer.xml,将其中ModemUpdater开头的这行删除掉。

ENABLE_USB_NETWORKING

该选项的作用是激活USB网络功能。因为这个功能需要电脑上单独安装驱动。所以一般不打开。

它的实现方式是在/var/gadget下建立一个名为usbnet_enabled的空文件。

REMOVE_MODEL_CHECK

该选项的作用是移除手机型号检查。例如将P130UNA的ROM刷到P130UEU的设备上时,可以使用该选项。但你如果把P101UNA刷到P121UNA的设备上时,也是可以使用该选项的,但这真的很有风险,因为没有人可以保证任何两个不同型号的手机的ROM一定会兼容,所以,如果你不知道你在干什么,就不要随便打开这个选项。

这个选项的实现其实很简单,将doctor里面的resources目录下的recoverytool.config文件中的ApprovalMikeHash那一行删除就可以啦。

REMOVE_CARRIER_CHECK

该选项的作用是移除运营商检测。例如你打算将ATT的ROM刷到O2上(当然因为这两个手机的型号也不同,所以你还需要把上面那个选项也打开),你就应该打开这个选项。不过它会带来很多副作用,因为开启这个选项之后,刷机时将不会为你安装运营商提供的系统级的ipk,而这些ipk有几个还是相当重要的,完全忽略安装的情况下,你会得到一个很纯的系统,而这个很纯的系统还会有些功能上的缺失,例如壁纸、铃声设置不能保存,应用商店可能无法使用,也无法升级程序等等。所以,通常我们也不会打开这个选项。要实现刷写其它运营商更高版本的ROM,我们其实还有更好的方法。

这个选项的实现比上面的选项稍微复杂些,除了将doctor里面的resources目录下的recoverytool.config文件中的ApprovalCharlieHash和CustomizationBuild这两行删除外,对正常的关于运营商提供的安装包的操作也都忽略不做了。这个功能其实没啥用,所以就不做更详细解释了。如果大家感兴趣,还是自己读代码吧。

CHANGE_KEYBOARD_TYPE

这个选项很有用,主要用于给德国键盘、法国键盘的手机替换为正键键盘时制作ROM使用。它有三个选项,z表示QWERTY键盘,y或者y1表示QWERTZ键盘,w1表示AZERTY键盘。

它是通过修改webOS.tar中的intaller.xml以外的另一个xml文件实现的,那个文件的名字对于不同的手机有所差别。它是在这个文件的tokens这个段中,插入<Val name="KEYoBRD" action="overwrite" value="${CHANGE_KEYBOARD_TYPE}"/>这个选项来实现的,其中${CHANGE_KEYBOARD_TYPE}就是上面列出的三个选项值。

ADD_EXTRA_CARRIERS

这个选项是用来增加运营商网络配置信息的,还记得上面提到的patches/carriers目录吗?

这个选项就是将这个目录中的文件信息都加到根分区的/etc/carrierdb/carrierdb.json文件中,这样就可以实现自定义网络运营商的网络参数了。虽然这个选项的注释中说仅对2.0.0系统有效,其实是对2.0.0及其以上的版本都有效。只不过我们用不到,因为中国移动、中国联通和中国电信这三大运营商的配置早就写在这个配置文件里了。根本不需要我们去添加,这也是我们为什么拿到手机,插卡就能上网的主要原因。

VAR_PARTITION_SIZE

该选项可以让你更改/var分区的大小。这个分区用于保存一些用户数据,不过它下面还有几个目录实际上也是独立的分区都有自己固定的大小,单纯扩大/var分区不能够改变那些目录的空间大小,比如/var/log,/var/db,/var/file-cache等。

该选项的实现也是通过修改webOS.tar中的那个xml文件实现的。

SWAP_PARTITION_SIZE

该选项可以让你更改交换分区的大小。实现方式同上。

EXT3FS_PARTITION_SIZE

该选项可以增加一个/media/ext3fs的分区。安装ubuntu、debian、android到webOS中时,创建这样一个分区可以让系统更快速稳定一些(跟没有创建这个分区时比,不是跟没有安装上述系统时比)。实现方式同上。

总结

上面的修改中,有些修改涉及到根分区下的文件,这些文件中有些不属于某个包(ipk),添加之后只需要计算它的md5值,然后将该值增加到根分区根目录下的md5sum.tar中就可以啦。而有些文件是属于某个包的,对这些文件,在修改之后除了需要重新计算md5值,并将它写入根分区下的md5sum.tar中以外,还需要将该值写入到该包的md5sum校验文件中。另外,因为它所在包的md5sum校验文件也被修改过,因此它所在的包的md5sum校验文件也要重新计算md5值,并写入根分区总的md5sum校验文件包中。如果要在包中增加或删除文件,过程要更复杂,除了修改md5文件,还需要修改list文件和更新list文件的md5值。这个过程不但看上去非常复杂,手动作起来也确实繁琐,好在meta-doctor都帮我们做好了。所以我们借助meta-doctor这个工具,比我们纯手工修改定制ROM还是要方便的多的。

但是对recoverytool.config,webOS.tar下的两个xml文件的修改,手工修改可能比用meta-doctor更方便灵活一些。但手工修改难免会出错,所以风险也要大一些。修改ROM是个细心的活,一定要小心再小心。

meta-doctor的功能远不止上面介绍的这么点。其实它还提供了好多的选项让你更细化的对ROM做定制,只是这些选项并没有列在Makefile头顶的列表里罢了。如果你仔细读源码,你会发现很多有趣且有用的选项。另外,如果现有的功能真的不够用,你也可以通过修改Makefile来自己添加新的选项予以扩展。下一节我们就来讲如何通过修改meta-doctor来实现WIFI激活的功能。