吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Firefly-RK3128主板雙系統(tǒng)啟動方案

firefly ? 來源:firefly ? 作者:firefly ? 2019-11-29 08:50 ? 次閱讀
雙系統(tǒng)啟動的設(shè)計(jì)和實(shí)現(xiàn)
前言

本文討論如何利用安卓系統(tǒng)自身的啟動特性,加進(jìn) Linux 系統(tǒng)的啟動支持,并實(shí)現(xiàn)雙系統(tǒng)的切換。 要達(dá)到這一點(diǎn),有必要先了解一下安卓系統(tǒng)的啟動流程。

安卓系統(tǒng)的啟動流程

安卓系統(tǒng)的啟動模式有兩種:正常模式和急救(recovery)模式。急救模式,其內(nèi)核和根文件系統(tǒng)均獨(dú)立于正常模式,功能簡單,一般很少更新,用作系統(tǒng)修復(fù)和維護(hù)。也就是說,安卓系統(tǒng)本身就是支持雙啟動的。安卓系統(tǒng)的啟動流程是:

1 U-Boot 初始化 1.1 U-Boot 讀取 CPU 寄存器,如果有 recovery 標(biāo)志,則跳轉(zhuǎn)到 3 1.2 U-Boot 讀取 misc 分區(qū),如果含有 recovery 命令,則跳轉(zhuǎn)到 3 1.3 正常啟動模式,跳轉(zhuǎn)到 2 2 正常啟動模式 2.1 加載 boot 分區(qū) 2.1.1 如果 boot 分區(qū)含有內(nèi)核和 initramfs, 則分別加載到內(nèi)存特定位置,跳轉(zhuǎn)到 2.3 (略過 kernel 分區(qū)處理) 2.1.2 如果 boot 分區(qū)僅含有 initramfs, 則加載到內(nèi)存特定位置。 2.2 加載 kernel 分區(qū)到內(nèi)存特定位置。 2.3 跳轉(zhuǎn)到 4 3 急救模式 3.1 讀出 recovery 分區(qū)內(nèi)含的內(nèi)核 和 initramfs, 分別加載到內(nèi)存特定位置,跳轉(zhuǎn)到 4 4 初始化內(nèi)核啟動參數(shù),將執(zhí)行權(quán)移交內(nèi)核。

注意,initramfs 是固化了的小型根文件系統(tǒng),內(nèi)核啟動后會將其解壓至內(nèi)存中,并執(zhí)行其中的 init 程序進(jìn)行初始化。也就是說,initramfs 是第一個獲得執(zhí)行權(quán)的根文件系統(tǒng),負(fù)責(zé)掛載真正的根文件系統(tǒng)(可以在各種各樣的存儲設(shè)備中,如 U盤、TF 卡、USB 硬盤、NAND 或 eMMC 閃存等)。

雙啟動系統(tǒng)的設(shè)計(jì)

分析安卓系統(tǒng)的啟動流程,一個比較簡單的雙啟動方案就是:

  • 加入 Linux 系統(tǒng)的根文件系統(tǒng)分區(qū)。
  • 替換 recovery 分區(qū)成 Linux 系統(tǒng)的內(nèi)核和 initramfs。
  • 改變 misc 分區(qū)的內(nèi)容,就可設(shè)定開機(jī)啟動的操作系統(tǒng)
  • 在 Linux 系統(tǒng)內(nèi)實(shí)現(xiàn)安卓急救系統(tǒng)的部分功能。

如何進(jìn)入 Linux 呢? 因?yàn)槲覀儗?Linux 放在 recovery 分區(qū),因此,問題等價于如何進(jìn)入安卓的急救模式。以下有幾種方式:

  • 拔掉 USB 線,按住開發(fā)板的recovery鍵開機(jī)(無論是初次上電、重啟或按reset鍵開機(jī)都可以)。這是臨時性的切換,下次開機(jī)不按,還是會進(jìn)入 Linux 。
  • 在安卓系統(tǒng)的設(shè)置里選擇恢復(fù)出廠設(shè)置。實(shí)際上,恢復(fù)出廠設(shè)備這個功能已被閹割了,重啟后會進(jìn)入 Linux。
  • 在安卓系統(tǒng)的關(guān)機(jī)菜單(點(diǎn)底部工具欄的關(guān)機(jī)按鈕進(jìn)入)增加了一項(xiàng)切換系統(tǒng)的選擇。當(dāng)然,它是檢測linuxroot分區(qū)才會出現(xiàn),也就是說單系統(tǒng)是不會出現(xiàn)的。
  • SDK 里的rkst/Image/misc.img刷進(jìn)到misc分區(qū)。

2~4 項(xiàng)都是通過寫 misc 分區(qū),達(dá)到切換到 recovery,這里也即是 Linux 的目的。

雙啟動系統(tǒng)的實(shí)現(xiàn)
分區(qū)

我們先來看看純安卓的存儲分區(qū)情況。分區(qū)信息在 parameter 文件里的CMDLINE行:

FIRMWARE_VER:4.4.2 MACHINE_MODEL:rk30sdk MACHINE_ID:007 MANUFACTURER:RK30SDK MAGIC: 0x5041524B ATAG: 0x60000800 MACHINE: 3066 CHECK_MASK: 0x80 PWR_HLD: 0,0,A,0,1 #KERNEL_IMG: 0x62008000 #FDT_NAME: rk-kernel.dtb #RECOVER_KEY: 1,1,0,20,0 CMDLINE:console=ttyFIQ0 androidboot.hardware=rk30board androidboot.console=ttyFIQ0 board.ap_has_alsa=0 init=/init initrd=0x62000000,0x00800000 mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(misc),0x00008000@0x00006000(resource),0x00008000@0x0000e000(kernel),0x00010000@0x00016000(boot),0x00010000@0x00026000(recovery),0x0001a000@0x00036000(backup),0x00040000@0x00050000(cache),0x00002000@0x00090000(kpanic),0x00180000@0x00092000(system),0x00002000@0x00212000(metadata),0x00200000@0x00214000(userdata),0x00020000@0x00414000(radical_update),-@0x00434000(user)

CMDLINE是傳遞到內(nèi)核的命令行,參數(shù)mtdparts就含有分區(qū)信息,其格式是:

0x00002000@0x00002000(uboot) 大小 偏移 分區(qū)名稱 單位是 512 字節(jié)(即傳統(tǒng)磁盤的扇區(qū)大?。?。

轉(zhuǎn)換成表格比較直觀些:

  • uboot :是用來存放第二階段(stage two) U-Boot,如果開發(fā)板用的是 eMMC 分區(qū),其 U-Boot 就不需要分階段。
  • misc :非常有用的一個分區(qū),下面會介紹到,用來控制啟動模式的。
  • resource :存放內(nèi)核的開機(jī)圖片和設(shè)備樹(Device Tree)信息。
  • kernel :存放安卓的內(nèi)核
  • boot : 存放安卓的正常系統(tǒng)啟動的初始內(nèi)存文件系統(tǒng)(initramfs)。注意,如果在 OTA 方式下,boot分區(qū)跟recovery分區(qū)一樣,含有內(nèi)核和初始內(nèi)存文件系統(tǒng),此時 kernel 分區(qū)不作使用。
  • recovery : 存放安卓急救模式所使用到的內(nèi)核和初始內(nèi)存文件系統(tǒng)。
  • backup : RK 設(shè)計(jì)的用來存放備份固件的分區(qū), FireNow 系統(tǒng)開發(fā)板沒有用到。
  • cache : 安卓的緩存分區(qū)
  • kpanic : 安卓的 kernel panic 分區(qū)(?)
  • system : 安卓的系統(tǒng)分區(qū)(掛載于 /system
  • metadata : RK 的元數(shù)據(jù)分區(qū),使用情況不詳
  • userdata : 安卓的數(shù)據(jù)分區(qū)(掛載于 /data
  • radical_update : RK 的升級分區(qū),使用情況不詳
  • user : 安卓的內(nèi)部存儲分區(qū)(掛載于/mnt/sdcard

我們需要增加一個名為 ‘linuxroot’ 的新分區(qū),用來存放 Linux 的根文件系統(tǒng)。為了使分區(qū)保持兼容,我們選擇了替換 radical_update 分區(qū),容量給夠 3G :

這樣,修改后的 parameter 文件,其 CMDLINE 更改為:

CMDLINE:console=ttyFIQ0 androidboot.hardware=rk30board androidboot.console=ttyFIQ0 board.ap_has_alsa=0 root=/dev/block/mtd/by-name/linuxroot rw rootfstype=ext4 init=/sbin/init initrd=0x62000000,0x00800000 mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(misc),0x00008000@0x00006000(resource),0x00008000@0x0000e000(kernel),0x00010000@0x00016000(boot),0x00010000@0x00026000(recovery),0x0001a000@0x00036000(backup),0x00040000@0x00050000(cache),0x00002000@0x00090000(kpanic),0x00180000@0x00092000(system),0x00002000@0x00212000(metadata),0x00200000@0x00214000(userdata),0x00620000@0x00414000(linuxroot),-@0x00a34000(user)
misc 分區(qū)的格式

改變 misc 分區(qū)的內(nèi)容,實(shí)現(xiàn)設(shè)定開機(jī)啟動的操作系統(tǒng),就必須了解 misc 分區(qū)的格式。 misc.img 是初次燒寫固件時寫到 misc 分區(qū)的映像,用 hexdump 命令可以方便地查看其內(nèi)容:

$ hexdump -C rkst/Image/misc.img 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00004000 62 6f 6f 74 2d 72 65 63 6f 76 65 72 79 00 00 00 |boot-recovery...| 00004010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00004040 72 65 63 6f 76 65 72 79 0a 2d 2d 77 69 70 65 5f |recovery.--wipe_| 00004050 61 6c 6c 00 00 00 00 00 00 00 00 00 00 00 00 00 |all.............| 00004060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 0000c000

可見,前 16K (0x4000) 字節(jié)都是 0,然后是一個 “boot-recovery” 命令,后面又跟著 “recovery”, “–wipe_all” 這些動作和參數(shù),因此初次升級固件,系統(tǒng)會進(jìn)入 recovery 模式,格式化所需的分區(qū),之后才重啟進(jìn)入安卓系統(tǒng)。將 misc 分區(qū)清空,系統(tǒng)啟動時就會加載 boot 和 kernel 分區(qū),從而進(jìn)入 Android;而往 misc 分區(qū)寫入 “boot-recovery” 命令,系統(tǒng)啟動時就會加載 recovery 分區(qū),從而進(jìn)入 Linux 系統(tǒng)。開發(fā)時,可以用燒寫工具燒寫 misc 分區(qū),從而控制進(jìn)入哪個系統(tǒng)。

保留安卓急救系統(tǒng)

將安卓系統(tǒng)本來的 recovery 分區(qū)替換成 Linux 系統(tǒng)的內(nèi)核和 initramfs,從而實(shí)現(xiàn)雙系統(tǒng)的啟動,這很簡單直觀,卻去掉了安卓急救系統(tǒng)。安卓的急救系統(tǒng)可以做多項(xiàng)系統(tǒng)維護(hù)工作,比較重要。某些安卓急救系統(tǒng)的功能,例如恢復(fù)出廠設(shè)置等,雖然可以在 Linux 系統(tǒng)自己加進(jìn)相應(yīng)的命令去處理,但顯得煩瑣而且容易出錯;另一些功能,如 OTA 升級,不是無法替代,就是成本太高,需要移植相關(guān)模塊。安卓急救系統(tǒng)需要保留,但 recovery 分區(qū)又被替換掉,該怎樣去實(shí)現(xiàn)呢?方法可以有多種,例如修改 U-Boot, 增加另一分區(qū)的引導(dǎo)。我們的目標(biāo)是系統(tǒng)的修改保持在最低限度內(nèi),從而降低復(fù)雜性?,F(xiàn)在采用的方法,是保留 recovery 分區(qū)為 Linux 系統(tǒng)的內(nèi)核和 initramfs 不變,將安卓系統(tǒng)的急救系統(tǒng)(即原 recovery 分區(qū)里的安卓系統(tǒng)的內(nèi)核和 initramfs)里的 initramfs 放在 backup 分區(qū)里(該分區(qū)一般沒有用上),然后修改 Linux 系統(tǒng)的 initramfs 里的初始化流程:

1. 判斷 misc 分區(qū)是否有特殊的標(biāo)志內(nèi)容“firefly-linux”,如果沒有,則轉(zhuǎn) 6。 2. 判斷 backup 分區(qū)是否含有安卓急救系統(tǒng)的 initramfs,如果沒有,則轉(zhuǎn) 6。 3. 提取 backup 分區(qū)的 initramfs,解壓至 /root 目錄中。 4. 將 /proc, /sys, /dev 等重要的系統(tǒng)目錄移到 /root 中 (mount –n –o move)。 5. 執(zhí)行 exec chroot /root /init 命令,將 /root 目錄切換成新的根目錄,并執(zhí)行里面的 init 程序,從而引導(dǎo)安卓系統(tǒng)本身的急救系統(tǒng)。操作完成。 6. 走原有流程,正常加載 Linux 系統(tǒng)。操作完成。

采用這樣的修改,用 Linux 系統(tǒng)的 initramfs 有選擇地去加載安卓的急救系統(tǒng),便可以達(dá)到要求。Linux 系統(tǒng)的 initramfs 的 init程序是 shell 腳本,修改和調(diào)試起來非常方便安卓系統(tǒng)的急救程序無需任何修改。剩下要做的,就要修改安卓系統(tǒng)的切換系統(tǒng)菜單項(xiàng),將入切換到 Linux 系統(tǒng)的特殊標(biāo)志內(nèi)容“firefly-linux”寫到 misc 分區(qū)即可。如此修改,可以最大程序上兼容原有系統(tǒng):

實(shí)現(xiàn)見以下提交: https://github.com/TeeFirefly/initrd/commit/24035459bbb5d84e4408e0901e488d88d5014af0

如何從 Linux 切換回 Android

很簡單,寫個腳本 /usr/local/bin/b2android.sh 將 misc 分區(qū)清空,然后重啟即可:

sudo dd if=/dev/zero of=/dev/block/mtd/by-name/misc bs=16k count=3 sudo reboot
如何從 Android 切換回 Linux

相關(guān)的提交為:

  • https://bitbucket.org/T-Firefly/firenow-lollipop/commits/c3f07c18e3da2359877722910fea2973a58683f4
  • https://bitbucket.org/T-Firefly/firenow-lollipop/commits/94b43d7e9c4636fa7c20f9c9316c4514ad9d12bb
  • https://bitbucket.org/T-Firefly/firenow-lollipop/commits/be90bd3d29cf7c50956df3091189db0d117909e4

主要的切換腳本為 device/rockchip/common/boot-linux.sh

#!/system/bin/sh out=/dev/block/rknand_misc pad() { busybox dd if=/dev/zero bs=$1 count=1 } echo_pad() { echo -n "$1" | busybox dd bs=$2 conv=sync; } { pad 16k echo_pad boot-recovery 8k echo_pad firefly-linux 8k pad 16k } > $out

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式主板
    +關(guān)注

    關(guān)注

    7

    文章

    6086

    瀏覽量

    35614
  • 安卓
    +關(guān)注

    關(guān)注

    5

    文章

    2136

    瀏覽量

    57601
  • Firefly
    +關(guān)注

    關(guān)注

    2

    文章

    538

    瀏覽量

    7129
收藏 人收藏

    評論

    相關(guān)推薦

    Firefly-RK3288雙系統(tǒng)啟動的設(shè)計(jì)和實(shí)現(xiàn)

    1、Firefly-RK3288 雙系統(tǒng)啟動的設(shè)計(jì)和實(shí)現(xiàn)如何在安卓系統(tǒng)里加入 Linux 系統(tǒng),實(shí)現(xiàn)雙系統(tǒng)的共存和切換呢?安卓有所謂的急救(
    發(fā)表于 08-05 15:55

    Firefly-RK3128開發(fā)板上手教程(上)

    1、Firefly-RK3128開發(fā)板入手指南配件Firefly-RK3128 的標(biāo)準(zhǔn)套裝包含以下配件:Core-3128J 核心板一塊Firefly-RK3128 基板一塊WiFi
    發(fā)表于 08-12 17:32

    Firefly-RK3128開發(fā)板上手教程(下)

    1、如何將主機(jī)上的固件文件通過雙公頭USB數(shù)據(jù)線燒錄到開發(fā)板的閃存中準(zhǔn)備工作Firefly-RK3128 開發(fā)板固件主機(jī)良好的 Micro USB OTG 線固件文件一般有兩種:單個統(tǒng)一固件
    發(fā)表于 08-12 17:51

    Firefly-RK3128 MIPI DSI使用步驟說明

    screen-type屬性:顯示屏類型,Firefly-RK3128只支持單通道MIPI屏,配置成SCREEN_MIPI即可。lvds-format屬性:無關(guān)選項(xiàng)。out-face屬性:配置顏色,可為OUT_P888
    發(fā)表于 08-22 17:12

    firefly RK3128開發(fā)板介紹

    Firefly-RK3128 采用Cortex-A7架構(gòu)四核1.3GHz處理器,集成Mali-400MP2 GPU, 擁有優(yōu)秀的運(yùn)算與圖形處理能力;板載千兆以太網(wǎng)口、2.4GHz Wi-Fi和藍(lán)牙4.0
    的頭像 發(fā)表于 11-14 11:27 ?4661次閱讀
    <b class='flag-5'>firefly</b> <b class='flag-5'>RK3128</b>開發(fā)板介紹

    Firefly-RK3128主板PWM輸出介紹

    Firefly-RK3128 開發(fā)板上有 4 路 PWM 輸出,分別為 PWM0 ~ PWM3
    的頭像 發(fā)表于 11-28 16:56 ?2450次閱讀
    <b class='flag-5'>Firefly-RK3128</b><b class='flag-5'>主板</b>PWM輸出介紹

    Firefly-RK3128主板LED子系統(tǒng)介紹

    Firefly-RK3128 開發(fā)板上有 2 個 LED 燈
    的頭像 發(fā)表于 11-28 17:01 ?2791次閱讀
    <b class='flag-5'>Firefly-RK3128</b><b class='flag-5'>主板</b>LED子<b class='flag-5'>系統(tǒng)</b>介紹

    Firefly-RK3128主板I2C控制器

    Firefly-RK3128 開發(fā)板上有 4 個片上 I2C 控制器。本文主要描述如何在該開發(fā)板上配置 I2C。
    的頭像 發(fā)表于 11-29 08:47 ?1565次閱讀
    <b class='flag-5'>Firefly-RK3128</b><b class='flag-5'>主板</b>I2C控制器

    Firefly-RK3128開發(fā)板攝像頭的介紹

    Firefly-RK3128 開發(fā)板上有 CIF 接口,支持 CIF 攝像頭。
    的頭像 發(fā)表于 11-28 16:48 ?3857次閱讀
    <b class='flag-5'>Firefly-RK3128</b>開發(fā)板攝像頭的介紹

    Firefly-RK3128主板ADC簡介

    Firefly-RK3128 開發(fā)板有一個 3 通道(0/1/2)、10 比特精度的 SAR ADC (Successive Approximation Register,逐次逼近寄存器),
    的頭像 發(fā)表于 11-28 17:17 ?3589次閱讀
    <b class='flag-5'>Firefly-RK3128</b><b class='flag-5'>主板</b>ADC簡介

    Firefly-RK3128主板接口定義介紹

    Firefly-RK3128 開發(fā)板提供了豐富的接口,主要包括:HDMI、音頻數(shù)字光纖、以太網(wǎng)、電源接口、復(fù)位按鍵、電源鍵、音頻輸入輸出、硅麥、串口調(diào)試接口、紅外接收、OTG接口、TF卡槽、USB Host1~4、
    的頭像 發(fā)表于 11-29 08:45 ?3548次閱讀
    <b class='flag-5'>Firefly-RK3128</b><b class='flag-5'>主板</b>接口定義介紹

    FireflyRK3128主板外殼介紹

    外殼 Firefly-RK3128 CAD圖 核心板 底板 Firefly-RK3128 外殼亞克力CAD圖
    的頭像 發(fā)表于 11-29 09:19 ?1297次閱讀
    FireflyRK<b class='flag-5'>3128</b><b class='flag-5'>主板</b>外殼介紹

    Firefly-RK3128主板啟動模式簡介

    Firefly-RK3128 有靈活的啟動方式。
    的頭像 發(fā)表于 11-29 09:27 ?5428次閱讀

    Firefly-RK3128主板串口調(diào)試

    Firefly-RK3128 開發(fā)板的調(diào)試串口與 TF 卡接口有信號引腳復(fù)用,因此無法同時使用
    的頭像 發(fā)表于 11-29 09:47 ?3631次閱讀
    <b class='flag-5'>Firefly-RK3128</b><b class='flag-5'>主板</b>串口調(diào)試

    linux雙系統(tǒng)啟動項(xiàng)設(shè)置

    在使用雙系統(tǒng)的時候,我們需要設(shè)置啟動項(xiàng)來選擇要啟動的操作系統(tǒng)。在Linux系統(tǒng)中,設(shè)置雙系統(tǒng)啟動
    的頭像 發(fā)表于 11-28 15:05 ?1700次閱讀
    名人线上娱乐城| 百家乐麻关于博彩投注| 大发在线扑克| 百家乐官网论坛bocaila| 炸金花棋牌游戏| 百家乐官网影院| bet365体育投注| 百家乐冯耕耘打法| 博士娱乐| 澳门百家乐实战视频| 百家乐官网如何玩法| 百家乐赌场在线娱乐| 百家乐官网赢钱lv| 圣保罗百家乐的玩法技巧和规则 | 威尼斯人娱乐城百家乐| 银河百家乐官网的玩法技巧和规则| 皇冠足球现金网| 百家乐赌博机假在哪里| 赌百家乐官网的心得体会| 大发888娱乐城送钱| 运城百家乐官网蓝盾| 澳盈88娱乐城| 百家乐龙虎台布多少钱| 百家乐官网太阳城 | 百家乐官网怎么玩能赢钱| 新太阳城娱乐城| 免费百家乐规律| 百家乐官网透视用设备| 大发888娱乐城大发888大发网| 百家乐官网网开服表| 宁城县| 全讯网信息| 最好的百家乐论坛| 百家乐官网翻天qvod| 大发888官方6222| 百家乐分析仪博彩正网| 百家乐官网游戏开发软件| 大发888官方 hplsj| 澳门百家乐的赢钱不倒翁| 网络百家乐官网大转轮| 武定县|