1. 程式人生 > >Android雙系統實現

Android雙系統實現

1. 前言:

刷機,似乎是安卓手機使用者的一項專利,但是,會刷機的使用者一般都是喜新厭舊的角色,

一個系統用久了,就想換到另一個系統,或者覺得沒有原來的好,或者又覺得要換回去,這樣又要重刷。

但是刷來刷去都麻煩啊,並且每次刷機也不是沒有風險的,一不小心就可能造成重要資料的丟失。

沒有解決辦法嗎?有!雙系統!甚至三系統,四系統!!

本文就是解決這個問題的,並且用本文中的方法,完全可以實現一鍵安裝,一鍵解除安裝系統的功能,把系統的安裝和解除安裝變成apk的安裝和解除安裝一樣簡單。

(說明下,下面的方法以三星i93xx系列的手機為例的)

2. 先來簡單介紹下安卓系統的啟動過程:

在手機上電時,最先執行的整合到CPU晶片上的一段rom裡的程式

這段程式負責載入nand flash或者sd卡上的載入程式,載入程式一般來講都是uboot

uboot會完成一些裝置的初始化,這裡很重要的部分就是nand flash,以便將linux核心載入讀到記憶體裡並執行。

載入的核心根據情況,有可能是boot分割槽裡的核心,也有可能是recovery分割槽裡的核心。

核心跑起來之後,首先會掛載ramdisk到"/"根目錄,然後執行/init建立第一個程序

init讀取/init.rc,進行進一步的初始化,完成如建立目錄,設定許可權,掛載data,system,cache分割槽,啟動一系列的service,包括重要的zygote程序

zygote程序又會建立system_server程序以完成進一步的初始化工作,並載入一系列的apk程序。

3. 接下來看下,一個安卓系統所需的分割槽:

一個uboot分割槽,負責引導核心

一個核心分割槽

一個system分割槽,用於存放安卓的系統程式和檔案

一個data分割槽,用於存放系統的資料,apk程式,以及apk程式的資料等等。

一個cache分割槽,一般用於升級之用,用於儲存ota升級包,升級日誌等等。

4. 再按下來看下雙系統的實現方案:

4.1 核心的引導問題

這是一個比較頭痛的問題,上面講到,核心是由uboot通過boot分割槽或者recovery分割槽載入進來的

如果還要載入其它分割槽的核心,就要考慮修改uboot的配置引數或者程式碼了

uboot的程式碼我們肯定是沒有 的,

雖然一般來講uboot的配置引數往往也是儲存在某個分割槽裡的,但一般都是加密的,所以也改不了。

所以我們只能考慮利用己有的分割槽了。

最簡單的方法就是覆蓋boot分割槽,將第二個安卓的boot.img寫到boot分割槽,

然後寫一個apk,當要啟動哪個系統時,就把哪個系統的boot.img寫到boot分割槽。

這種方式的缺點是切換麻煩,每次切換都要先啟動其中的一個系統,然後執行apk進行切換。

然後,我們把貪婪的目光瞄向了recovery分割槽。 

大家知道,recovery分割槽一般在系統升級或者恢復出廠設定的時候才會用到,所以我們考慮對recovery分割槽進行下手。

最簡單的方法是把第二個安卓系統boot.img放到recovery分割槽裡,這樣可以實現觸發進recovery來引導第二個安卓系統了。 

當然,也可以在recovery分割槽裡再放一個定製的uboot,從而實現更加靈活的載入方式,如可以顯示引導選單等等,再如從SD卡里載入核心等等。

但是這還是要有uboot的原始碼才行。

當然,在使用recovery分割槽之前,要對recovery分割槽作下備份。

使用recovery分割槽作為第二個系統的linux引導分割槽還有個好處就是一般手機都有開機進recovery的快捷鍵,

如三星的手機一般是在開機時同時按下:音量加,HOME,POWER三個按鍵就可以進recovery.

從而實現方便的系統切換。

4.2 system,data分割槽的建立問題:

解決了引導的問題,再來看下system和data分割槽的建立問題。

因為cache分割槽只在升級的時候會用到,所以兩個系統可以共用,不用再建立了。

1)重新分割槽法:

也就是為每個系統建立不同的分割槽,這種方法需要對儲存空間進行重新劃分,顯然比較麻煩,風險也比較高,可行性比較低。

2)使用虛擬磁碟的方案 

大家一定對ubuntu能夠在windows下直接安裝的方式印象十分深刻

實際上ubuntu能夠在不重新分割槽的情況下實現安裝真是利用的虛擬磁碟實現的。

相對於第一種方案,避免了重新分割槽的麻煩。

虛擬磁碟是linux下很早核心就已經支援了,是很成熟的技術了。

所以這裡虛擬磁碟是最好的選擇,並且藉助於虛擬磁碟,我們不僅可以實現雙系統,還可以實現三系統,四系統,這完全取決於儲存空間。

5. 理論講清楚了,接下來,看下具體如何幹吧。 

首先,我們要建立一個system虛擬磁碟,這裡有兩種方法:

一種是從img直接生成虛擬磁碟,另一種方法是要將一個ota升級包中的system分割槽寫到虛擬磁碟中。

第一種方法比較簡單,只要執行一條命令即可:

simg2img system.img system.disk

simg2img可以在編譯完的out/host/linux-x86/bin/目錄下找到

6.5 如果你拿到的是一個zip格式的ota升級包,內容類似圖中所示:

那麼製作system虛擬磁碟就略微有些麻煩了,看下如何製作:

需要修改壓縮包的META-INF\com\google\android目錄下的update-script指令碼

1)去除format和mount /system分割槽的指令碼

  1. format("ext4""EMMC""/dev/block/mmcblk0p9""0""/system");  
  2. mount("ext4""EMMC""/dev/block/mmcblk0p9""/system");  

2)去除寫boot.img和data分割槽的指令碼

  1. package_extract_file("boot.img""/dev/block/mmcblk0p5");  

這裡要千萬小心,一定要把boot.img的寫操作去掉

總之,去除一卻和system分割槽無關的操作,去除/system分割槽的格式化操作和掛載操作

這裡一定要小心+細心。

3)接下來將解壓出來的ota升級包重新打包成zip檔案

4)然後進入recovery進行進一步的操作(這裡recovery最好是第三方的recovery,如cm的recovery,命令比較豐富,比較好操作)

5)用usb連線手機,進入recovery後,adb會自動連線到recovery,然後依次執行如下命令:

在執行下面的指令碼之前請確認你的手機可以在shell中獲取系統許可權

將升級指令碼執行程式傳到手機的/data/local/tmp目錄,update-binary在升級包裡的META-INF\com\google\android目錄,和updater-script同一個目錄。

  1. adb push update-binary /data/local/tmp  

將修改過update-script的ota升級包傳到手機的相應目錄

  1. adb push ota.zip /data/local/tmp  

切換到root許可權

  1. adb shell  
  2. su  

建立一個800M大小的虛擬磁碟
  1. cd /data/local/tmp  
  2. dd if=/dev/zero of=system.disk bs=1024 count=819200

loop虛擬磁碟system.disk
  1. busybox losetup /dev/block/loop7 system.disk  

對虛擬磁碟進行格式化

  1. busybox mkfs.ext2 /dev/block/loop7  

掛載虛擬磁碟到/system目錄
  1. busybox mount -o loop -t ext4 /dev/block/loop7 /system  

修改update-binary為可執行

  1. chmod 777 update-binary  

開始執行update-script指令碼,把ota升級包安裝到/system目錄
  1. ./update-binary 20 ota.zip  

解除安裝system虛擬磁碟
  1. umount /system  
  2. busybox losetup -d /dev/block/loop7  


退出系統許可權

exit

退出adb shell

exit

從手機上將system.disk傳到PC:

adb pull /data/local/tmp/system.disk

這樣,一個燒餅--system虛擬磁碟就做好了:)。

7. 接下來看下如何去建立一個ext4格式的data虛擬磁碟

  1. dd if=/dev/zero of=data.disk bs=1024 count=30720
  2. busybox losetup /dev/loop0 data.disk  
  3. mkfs.ext4 -m 1 -v /dev/block/loop7  


8. 接下來看下如何去掛載虛擬磁碟

1)先要對boot.img動手術,先要對其解壓, 網路上應該有解壓的工具,但是我一般都喜歡自己寫一些小工具來完成一些簡單的任務,一來加深認識,二來也方便功能的擴充套件。

所以,這裡就用python寫了個解壓的程式:

  1. unpack.py  
  2. """ 
  3.     unsigned char magic[BOOT_MAGIC_SIZE]; 
  4.     unsigned kernel_size;  /* size in bytes */ 
  5.     unsigned kernel_addr;  /* physical load addr */ 
  6.     unsigned ramdisk_size; /* size in bytes */ 
  7.     unsigned ramdisk_addr; /* physical load addr */ 
  8.     unsigned second_size;  /* size in bytes */ 
  9.     unsigned second_addr;  /* physical load addr */ 
  10.     unsigned tags_addr;    /* physical addr for kernel tags */ 
  11.     unsigned page_size;    /* flash page size we assume */ 
  12.     unsigned unused[2];    /* future expansion: should be 0 */ 
  13.     unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ 
  14.     unsigned char cmdline[BOOT_ARGS_SIZE]; 
  15.     unsigned id[8]; /* timestamp / checksum / sha1 / etc */ 
  16. """
  17. import sys  
  18. import struct  
  19. import subprocess  
  20. BOOT_MAGIC_SIZE = 8
  21. BOOT_NAME_SIZE = 16
  22. BOOT_ARGS_SIZE = 512
  23. boot_img = None
  24. kernel_img = None
  25. ramdisk_img = None
  26. ramdisk_cpio = None
  27. ramdisk_out = None
  28. if len(sys.argv) >= 2:  
  29.     boot_img = sys.argv[1]  
  30. else:  
  31.     boot_img = 'boot.img'
  32. if len(sys.argv) >= 3:  
  33.     kernel_img = sys.argv[2]  
  34. else:  
  35.     kernel_img = 'kernel.img'
  36. if len(sys.argv) >= 4:  
  37.     ramdisk_img = sys.argv[3]  
  38. else:  
  39.     ramdisk_img = 'ramdisk.img'
  40. if len(sys.argv) >= 5:  
  41.     ramdisk_cpio = sys.argv[4]  
  42. else:  
  43.     ramdisk_cpio = 'ramdisk-m.cpio'
  44. 相關推薦

    Android系統實現

    1. 前言: 刷機,似乎是安卓手機使用者的一項專利,但是,會刷機的使用者一般都是喜新厭舊的角色, 一個系統用久了,就想換到另一個系統,或者覺得沒有原來的好,或者又覺得要換回去,這樣又要重刷。 但是刷來刷去都麻煩啊,並且每次刷機也不是沒有風

    uefi+gpt下win10/fedora系統實現方案

    博主前幾天想裝個linux系統熟悉一下,結果ubuntu16.04有個bug就是grub一直安裝失敗,聯網安裝和掛載在win10efi下等等情況都試了一下結果還是不行,linux系統那麼多何必非吊死在ubuntu上。於是果斷放棄,投入fedora的懷抱。一、所需工具裝有win

    Android系統之基本問題研究

    序:近年來Android智慧手機已成為人們生活的一部分,隨著Android手機功能的日益豐富,它正在改變不少行業的辦公模式。尤其是在警察、海關、銀行等行業,移動辦公顯得尤為迫切。如通過手機接入專有網路

    Android Sip學習(二)Android VoIP系統實現原理

      隨著我國三網融合的推進,VoIP與IPTV(Interactive Personality TV)一起成為這一龐大工程的重要標誌。而目前手機中,VoIP的解決方案並不是很多,特別是在Google公司推出的開源作業系統Android中。儘管該系統推出時間不長,憑藉強大的功能、良好的介面、廣泛的商業支援,

    Android圖形系統的分析與移植--七、緩衝framebuffer的實現

    1  實現原理在基本的FrameBuffer已經實現的基礎上,需要實現的是與Android原本模擬器所使用的goldfish FrameBuffer之間的區別。比較一下不難發現,從以下及方面著手:1.                  修改初始化FrameBuffer資訊;2

    win7下安裝Linux實現系統全攻略

    ont c51 item itl command 桌面 ted current 輸入 最近剛剛把原來32位的系統給重新安裝成64位的win7旗艦版,但又想嘗試下Linux,於是在win7下安裝了Linux實現了雙系統,是ubuntu 12.04版本的,據說現在最新的14.

    Android 擊退出程序實現(有側滑界面)

    是的 tro raw idt style tap sys .com ges 大家好,今天帶來雙擊退出程序實現方法,我知道,網上也是有許多關於雙擊退出程序實現的方法,所以,聽見當然是給大家帶來不一樣的雙擊退出的實現方法。 首先帶來的便是關於onKeyDown和onKe

    PC實現Win10/Ubuntu系統

    Ubuntu簡介 Ubuntu是一款開放原始碼的GNU/Linux作業系統,由全球化的專業開發團隊Canonical Ltd打造。該系統具有龐大的社群力量,對GNU/Linux的普及作出了巨大貢獻。Ubuntu既有面向桌面的版本,又有面向智慧手機的版本。 資料準備 Ubuntu系統

    Android 修改系統原始碼實現應用安裝白名單黑名單攔截功能

    本文原創,旨在記錄。有不對或者可改進之處,歡迎大家指出。謝謝 方法一:系統自動掃描apk安裝方式 frameworks\base\services\java\com\android\server\pm下 修改PackageManagerService下的createDataDirsLI(

    如何實現linux+windows系統啟動

    設定你的計算機根據需要啟動 Windows 10 或 Ubuntu 18.04。 儘管 Linux 是一個有著廣泛的硬體和軟體支援的作業系統,但事實上有時你仍需要使用 Windows,也許是因為有些不能在 Linux 下執行的重要軟體。但幸運地是,雙啟動 Windows 和 Linux 是很簡單的 —— 在

    Android圖片剪裁-呼叫系統實現,完美適配魅族等機型

    封裝的系統圖片剪裁使用庫-GITHUB求STAR System-Photo-Cropper Android System Photo Cropper 使用系統原生的圖片剪裁庫,完美適配魅族等機型 Step 1 First you need a sysPhotoCropper to h

    基於rv1108的系統實現方法

    背景: 公司實現一個產品的功能實現uav(無人機功能)和drv(行車記錄儀功能)。所以在產品需要實現雙系統(一個無人機系統一個行車記錄儀系統),在開機之前將開關撥到不同的位置,系統啟動時在loader階段就會去檢測開關按鍵的狀態,根據按鍵的狀態,去不同的偏移地址載入不同的k

    win7下U盤安裝Ubuntu14.04桌面版實現系統

    最近剛過新年,duang下我們學習一下win7下用U盤安裝Ubuntu雙系統吧: 一、準備資料 背景環境:win7系統 準備檔案:(下載連結:http://pan.baidu.com/s/1o6vAXfG) 1)Ubuntu系統:ubuntu-14.04.2-desktop

    Android 日誌系統(Logcat)的實現分析

    1、在Android工程的Android.mk檔案中新增如下內容:LOCAL_SHARED_LIBRARIES := liblog libutils  LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog  2、在JNI的實現程式碼檔案(.c或者.cpp)中加入包含LOG標頭檔

    Cocos2d-x 3.x 頭像選擇器,本地相簿與拍照+頭像編輯功能(Android、IOS平臺實現)

    大連遊戲行業不是太發達,最後選擇在一家應用外包公司工作,在工作和業餘學習過程中積累了一點微不住道的經驗,希望分享給熱愛遊戲的小夥伴們。 在應用開發過程中會常常有使用者上傳頭像的功能,在網上找了N多資料發現沒有人具體介紹過該用cocos2d-x實現。這篇文章就來介紹一下如何在

    Android開發:實現系統自帶截圖功能 需要獲取System許可權

    在一個service介面上,點選一個button按鈕,可以截圖 貼上程式碼: mButton.setOnClickListener(new OnClickListener(){          public void onClick(View arg0) {       

    PC 實現 Win10/Ubuntu系統(小白安裝法)

    1. Ubuntu簡介 Ubuntu是一款開放原始碼的GNU/Linux作業系統,由全球化的專業開發團隊Canonical Ltd打造。該系統具有龐大的社群力量,對GNU/Linux的普及作出了巨大貢獻。Ubuntu既有面向桌面的版本,又有面向智慧手機的版本。 2.

    最簡單的方法實現windows下裝windows+Linux系統

    開啟了這個功能後,安裝過程同上面10.04版本!一步步來就可以!就這樣Linux+Windows雙系統即完成了!簡單吧?!當然,這不算是真正意義上安裝的Ubuntu系統,使用WUBI安裝Ubuntu有如下缺點:1、一休眠或掛起就會宕機,不能從休眠或掛起狀態恢復,只能強行關機然後重啟。因為休眠和待機需要使用F

    【林學森的Android專欄】從系統實現的層面不斷剖析Android相關開發知識

    本書版本輸出到臺灣地區,衷心感謝大家的支援。《深入理解Android核心設計思想》新書已在全國各大城市書店上市。 電子書店購買地址(不斷增加中): 1. China-pub 2. 京東 3. Amazon 4. 噹噹網 5. 淘寶網 6. 比比看哪邊購書便宜

    Android屏驅動Service架構實現

    做程式設計師苦逼的地方就在於,當公司決定做什麼的時候,是不會跟你商量的,只會跟你說,xxx,這個可能需要你來實現一下。fuck,想好實現思路了嗎?(這是我司的程式設計師提出,我們來做整理完善的) Android雙屏顯示,可能會和別的雙屏機制不同,大多數情況下是