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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Android 与其他基于 Linux 的系统有何不同?

發(fā)布時間:2024/3/12 linux 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 与其他基于 Linux 的系统有何不同? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 概述
  • Linux Kernel
  • AOSP
  • 安卓構建系統(tǒng)
  • rootfs 組織和分區(qū)布局
  • 安卓 C 庫
  • 為什么 Android 不使用 BusyBox?
  • 安卓初始化系統(tǒng)
  • 安卓守護進程
  • 安卓日志系統(tǒng)
  • 硬件訪問和 Android HAL
  • Android 框架和系統(tǒng)服務
  • 安卓應用
  • Android 是不是 Linux 發(fā)行版?

原文:https://embeddedbits.org/what-differs-android-from-other-linux-based-systems/

?如果您是嵌入式 Linux 開發(fā)人員但從未使用過嵌入式 Android,那么本文適合您。如果您開發(fā)或維護 Linux 發(fā)行版,并且我想開始開發(fā) Android 發(fā)行版,那么本文適合您。如果您是一名 Android 應用程序開發(fā)人員并想了解一些 Android(內(nèi)部)的工作原理,本文也適合您。如果你只是好奇,這篇文章也適合你!😃

?我們將從構建系統(tǒng)到分區(qū)布局,從 rootfs 的內(nèi)容到操作系統(tǒng)組件的架構,從 IPC/RPC 機制到硬件訪問如何工作的不同角度來比較 GNU/Linux 系統(tǒng)和 Android。

概述

?如果您查看任何嵌入式 Linux 系統(tǒng)的架構,您總會發(fā)現(xiàn)相同的主要組件:

  • 一個或多個引導加載程序用于引導、配置硬件和引導 Linux 內(nèi)核。
  • Linux 內(nèi)核。
  • 包含庫和應用程序的根文件系統(tǒng) (rootfs)。

  • ?如果現(xiàn)在您查看基于 Android 的系統(tǒng)的相同圖表,會有什么區(qū)別?

  • 引導程序就在那里。Android 不需要任何特殊的引導加載程序,盡管人們通常會添加對fastboot 的支持,這是谷歌為用戶和開發(fā)人員創(chuàng)建的協(xié)議,用于與基于 Android 的系統(tǒng)上的引導加載程序進行交互。
  • Linux 內(nèi)核也在那里,但有“一些”變化。稍后再談。
  • 根文件系統(tǒng)也在那里。但它真的不一樣!沒有什么像來自 Debian 的典型根文件系統(tǒng)或來自 Buildroot 或 OpenEmbedded 的定制 rootfs。
  • 從上圖我們可以看出,Android 用戶空間組件清楚地分為三個主要層:

  • Native:這是所有本機 (C/C++) 應用程序和庫所在的位置。之所以稱為Native,是因為它在 ART 虛擬機之外運行。本機層主要用于將 Linux 內(nèi)核接口抽象到框架層。
  • Framework:這是實現(xiàn)所有操作系統(tǒng)服務的地方(主要是在 Java 中)。對操作系統(tǒng)資源的訪問通過稱為系統(tǒng)服務的組件(遠程)公開,使用稱為 Binder 的 IPC/RPC 機制。API 將抽象應用程序?qū)@些系統(tǒng)服務的訪問。
  • Application:通常用Java或Kotlin編寫,他們只是看到暴露的操作系統(tǒng)API。
  • 在詳細研究 Android 用戶空間組件之前,讓我們先談談內(nèi)核。

    Linux Kernel

    ?要運行基于 Android 的系統(tǒng),我們需要在 Linux 內(nèi)核中啟用一些額外的“功能”。如果我嘗試討論大多數(shù)功能,這篇文章會太長,但我可以評論一些:

    • Binder:這是Android中使用的IPC(Inter-Process Communication)和RPC(Remote Procedure Call)機制。您可以與 DBUS 做一個粗略的比較,但 DBUS 在用戶空間中運行,而 Binder 是一種更快、更輕的基于內(nèi)核的實現(xiàn)。
    • Ashmem:Android 中的默認共享內(nèi)存分配器(Google 不喜歡 POSIX SHM)。
    • 低內(nèi)存殺手:建立在內(nèi)核OOM(內(nèi)存不足)殺手之上的邏輯,與守護進程(lmkd)結合,有助于在低內(nèi)存情況下管理系統(tǒng)。
      大多數(shù)這些特性已經(jīng)在主線內(nèi)核中可用,但如果你想要“Androidisms”的完整列表,你可以克隆谷歌的內(nèi)核通用存儲庫并搜索以“ANDROID:”開頭的提交:
    $ git clone https://android.googlesource.com/kernel/common kernel-common $ git checkout remotes/origin/android11-5.4 $ git log --oneline | grep "ANDROID:" | less 5427f8b72fc0 ANDROID: GKI: update xiaomi symbol list ecb88922f521 ANDROID: GKI: update Vivo symbol list 32b242337266 ANDROID: sysrq: add vendor hook for sysrq crash information 42e516f6b23b ANDROID: ABI: update allowed list for galaxy de198b0f2d39 ANDROID: GKI: update Vivo symbol list$ git log --oneline | grep "ANDROID:" | wc -l 1157

    ?盡管 Linux 內(nèi)核中有這些(以及其他一些)主要變化,Android 在用戶空間組件及其架構(所謂的 Android 平臺)方面確實與 GNU/Linux 系統(tǒng)不同,Android 平臺的源代碼是在名為AOSP(Android 開源項目)的項目中提供。

    AOSP

    AOSP 由數(shù)百個存儲庫(特別是 Android 11 中的 780 個)組成,您可以在https://android.googlesource.com/ 中查看所有這些存儲庫。

    ?源代碼是用已知的工具管理的,比如repo和git,它是巨大的!Android 11 是 100GB 的源代碼加上一次構建后的 115GB。因此,您確實需要大量磁盤空間來處理 Android 源代碼。

    克隆最新的 AOSP 源代碼就像運行以下兩個命令一樣簡單(可以在repo init 中使用-b來克隆特定的Android 發(fā)布標記或分支):

    $ repo init -u https://android.googlesource.com/platform/manifest $ repo sync

    幾個小時后,您的機器中將擁有 Android 源代碼:

    $ ls Android.bp dalvik libcore read-snapshot.txt art developers libnativehelper sdk bionic development Makefile system bootable device out test bootstrap.bash external packages toolchain build frameworks pdk tools compatibility hardware platform_testing cts kernel prebuilts

    作為一個開源項目,有多個討論組與社區(qū)和開發(fā)者進行交流,任何人都可以通過Gerrit 代碼審查工具為項目做出貢獻。

    絕大多數(shù)軟件組件在 Apache 和 BSD 許可下,一些軟件組件在 GPL/LGPL 許可下,一些谷歌應用程序是閉源的(例如谷歌播放、Gmail、谷歌地圖、YouTube 等)。這些應用程序在名為Google 移動服務(GMS)的軟件包中提供,要獲取它們,您需要通過Android 兼容性計劃(ACP)對設備進行認證。

    當我們下載 AOSP 源代碼時,與其他嵌入式 Linux 開發(fā)方法相比,我們可以看到一些差異。

    與現(xiàn)成的發(fā)行版(例如 Debian)不同,您可以輕松下載完整的源代碼并從頭開始構建發(fā)行版(例如,如果您想創(chuàng)建一個自定義的 Debian 系統(tǒng),您通常從預編譯的包中完成) )。

    與構建系統(tǒng)方法(例如 Buildroot、OpenEmbedded)相比,在 Android 中,我們似乎有一個使用repo sync命令下載的“大應用程序” 。當然這不是真的。我們在那里有數(shù)以千計的項目和存儲庫,它們最終將組成操作系統(tǒng)映像。而將所有內(nèi)容放在一起的責任在于 Android 構建系統(tǒng)…

    安卓構建系統(tǒng)

    ?在以前的 Android 版本中,構建系統(tǒng)完全基于 makefile,其中編譯每個軟件組件的指令在Android.mk文件中定義。下面是在 Android 中構建“Hello World”C 應用程序的Android.mk文件示例:

    LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)LOCAL_SRC_FILES = helloworld.c LOCAL_MODULE = helloworld LOCAL_MODULE_TAGS = optionalinclude $(BUILD_EXECUTABLE)

    ?基于 Makefile 的構建系統(tǒng)有幾個缺點,包括增量構建的性能低下,并且在最新版本的 Android 中被Soong 構建系統(tǒng)取代。

    ?在 Soong 構建系統(tǒng)中,編譯軟件組件的規(guī)則在 Blueprint 文件 ( Android.bp )中定義,其語法類似于 JSON。以下是在 Android 中構建“Hello World”C 應用程序的相同示例,但使用的是藍圖文件:

    cc_binary {name: "helloworld",srcs: ["helloworld.c"],tags: ["optional"], }

    ?藍圖文件由名為Blueprint的工具處理,該工具生成.ninja文件,其中包含編譯 Android 軟件組件的所有規(guī)則。然后.ninja文件由名為Ninja的工具處理,該工具將編譯所有軟件組件并生成 Android 圖像(稍后將詳細介紹圖像)。

    ?在撰寫本文時,并非所有 makefile ( Android.mk ) 都轉(zhuǎn)換為藍圖文件 ( Android.bp )。為此,有一個名為kati的工具,負責將Android.mk文件轉(zhuǎn)換為.ninja文件。隨著時間的推移,所有Android.mk文件應該會逐漸轉(zhuǎn)換為Android.bp,不再需要在 Android 構建系統(tǒng)中使用 kati 工具。

    下圖是Android構建過程的總結:

    ?構建Android非常簡單。您可以使用三個簡單的命令來完成此操作:一個用于獲取初始化環(huán)境的腳本,第二個用于選擇目標設備 ( product-variant ),最后一個用于開始構建。以下命令將為模擬器構建 Android:

    $ source build/envsetup.sh $ lunch aosp_x86_64-eng $ make

    幾個小時后,我們在out/target/product/ 中得到了圖像:

    $ cd out/target/product/generic_x86_64/ && ls *.img cache.img super_empty.img vbmeta.img dtb.img super.img vendor_boot-debug.img encryptionkey.img system.img vendor_boot.img ramdisk-debug.img system-qemu.img vendor.img ramdisk.img userdata.img vendor-qemu.img ramdisk-qemu.img userdata-qemu.img

    現(xiàn)在,所有這些圖像是什么?Android 中的 rootfs 是如何組織的?

    rootfs 組織和分區(qū)布局

    Linux 系統(tǒng)上的 rootfs 組織(大部分)是標準化的,基本上由兩個標準定義:Filesystem Hierarchy Standard和Linux Standard Base。

    Linux 發(fā)行版試圖符合這些標準,使應用程序易于移植,并在用戶和開發(fā)人員需要使用不同的 Linux 系統(tǒng)時簡化他們的生活。

    但正如您所料,Android 是個例外!

    這是 Android 系統(tǒng)(Android 11,為 QEMU 構建)的根分區(qū)列表。請問/sbin、/usr、/lib等Linux系統(tǒng)常用目錄在哪里?

    # ls / acct d etc mnt sdcard apex data init odm storage bin data_mirror init.environ.rc oem sys bugreports debug_ramdisk linkerconfig proc system cache default.prop lost+found product system_ext config dev metadata res vendor

    他們不在!在Android中,操作系統(tǒng)組件(應用程序、庫)位于/system目錄(系統(tǒng)分區(qū)的掛載點),用戶數(shù)據(jù)/配置(包括運行時安裝的應用程序)位于/data目錄(系統(tǒng)分區(qū)的掛載點)。數(shù)據(jù)分區(qū))。還有許多其他分區(qū),如緩存(下載的文件和臨時數(shù)據(jù))、供應商(來自 SoC 制造商的特定文件)和 odm(來自設備制造商的特定文件)。

    這是 Android 11 上分區(qū)布局的基本概述(可能因制造商/設備而異):

    與典型的嵌入式 Linux 系統(tǒng)非常不同,對吧?

    那么現(xiàn)在,我們?yōu)槭裁床挥懻撘幌挛募到y(tǒng)的內(nèi)容呢?因為它們也有很大的不同。讓我們從 C 庫開始。

    安卓 C 庫

    基于 Linux 內(nèi)核的操作系統(tǒng)的主要組件之一是 C 庫。

    C 庫實現(xiàn)了操作系統(tǒng)的 API,為應用程序提供了通過系統(tǒng)調(diào)用訪問內(nèi)核服務的接口。

    有幾個 C 庫可用于 Linux 系統(tǒng),包括 glibc、uclibc-ng 和 musl。但是 Android 有自己的 C 庫:Bionic!

    我可以想象至少有三個原因可能促使 Google 實現(xiàn)自己的 C 庫:許可、速度和大小。實現(xiàn)非常簡單,輕量級,并在 BSD 許可下發(fā)布。

    需要提及的一件重要事情是它沒有完整的 POSIX 支持,這使得為 Android 構建本機 Linux 應用程序變得更加困難。

    例如,請參閱下面來自BusyBox 中 libbb/missing_syscalls.c的代碼片段。該定義的(機器人)#如果因為一些仿生功能不遵循POSIX標準是必需的。

    #if defined(ANDROID) || defined(__ANDROID__) /*# include <linux/timex.h> - for struct timex, but may collide with <time.h> */ # include <sys/syscall.h> pid_t getsid(pid_t pid) {return syscall(__NR_getsid, pid); }int sethostname(const char *name, size_t len) {return syscall(__NR_sethostname, name, len); }struct timex; int adjtimex(struct timex *buf) {return syscall(__NR_adjtimex, buf); }int pivot_root(const char *new_root, const char *put_old) {return syscall(__NR_pivot_root, new_root, put_old); }

    說到 BusyBox……

    為什么 Android 不使用 BusyBox?

    在嵌入式 Linux 設備上使用 BusyBox 是很常見的。

    Busybox 提供(重新)實現(xiàn)常用工具和應用程序,例如初始化程序、shell 和一些用于操作和配置系統(tǒng)的實用程序。

    但是默認情況下,Android 不附帶 BusyBox!

    Android 使用另外兩個(概念上相似的)實現(xiàn),稱為Toolbox和Toybox,它們都是在 BSD 許可下發(fā)布的。Toolbox 是 Google 實現(xiàn)的工具,Toybox 是社區(qū)實現(xiàn)的工具(由 Rob Landley 發(fā)起,BusyBox ex-maintainer)。

    并且因為這些工具有一些限制,所以在 Android 設備上安裝 BusyBox 是很常見的,尤其是在開發(fā)過程中。一個動機是在命令行中有一個好的文本編輯器 ( vi ) 可用。

    現(xiàn)在,基于 Linux 的操作系統(tǒng)的一個重要部分是 init 系統(tǒng)。初始化在 Android 中是如何工作的?

    安卓初始化系統(tǒng)

    簡而言之,init 應用程序在掛載 rootfs 后立即由內(nèi)核執(zhí)行,負責系統(tǒng)初始化和管理。

    Linux 系統(tǒng)的 init 進程有多種實現(xiàn)方式,包括 sysvinit、systemd 和 upstart。正如您可能已經(jīng)預料到的,Android 有自己的初始化系統(tǒng)!

    Android init 進程有 3 個主要職責:

  • 初始化和配置操作系統(tǒng)執(zhí)行環(huán)境(導出環(huán)境變量、創(chuàng)建和設置文件和目錄的權限、創(chuàng)建鏈接、掛載文件系統(tǒng)、設置 selinux 等)。
  • 啟動和監(jiān)視守護進程。
  • 管理系統(tǒng)屬性。
  • init 進程的行為定義在一個配置文件中(默認為/etc/init/hw/init.rc),它與我們習慣的任何 init 配置文件都有很大的不同。以下是來自默認 Android init.rc文件的片段:

    import /init.environ.rc import /system/etc/init/hw/init.usb.rc import /init.${ro.hardware}.rc import /vendor/etc/init/hw/init.${ro.hardware}.rc import /system/etc/init/hw/init.usb.configfs.rc import /system/etc/init/hw/init.${ro.zygote}.rc# Cgroups are mounted right before early-init using list from /etc/cgroups.json on early-init# Disable sysrq from keyboardwrite /proc/sys/kernel/sysrq 0# Android doesn't need kernel module autoloading, and it causes SELinux# denials. So disable it by setting modprobe to the empty string. Note: to# explicitly set a sysctl to an empty string, a trailing newline is needed.write /proc/sys/kernel/modprobe \n...on initsysclktz 0# Mix device-specific information into the entropy poolcopy /proc/cmdline /dev/urandomcopy /system/etc/prop.default /dev/urandomsymlink /proc/self/fd/0 /dev/stdinsymlink /proc/self/fd/1 /dev/stdoutsymlink /proc/self/fd/2 /dev/stderr...# Mount filesystems and start core system services. on late-inittrigger early-fs# Mount fstab in init.{$device}.rc by mount_all command. Optional parameter# '--early' can be specified to skip entries with 'latemount'.# /system and /vendor must be mounted by the end of the fs stage,# while /data is optional.trigger fson property:ro.debuggable=1# Give writes to anyone for the trace folder on debug builds.# The folder is used to store method traces.chmod 0773 /data/misc/trace# Give reads to anyone for the window trace folder on debug builds.chmod 0775 /data/misc/wmtraceservice ueventd /system/bin/ueventdclass corecriticalseclabel u:r:ueventd:s0shutdown criticalservice console /system/bin/shclass coreconsoledisableduser shellgroup shell log readprocseclabel u:r:shell:s0setenv HOSTNAME console...

    它確實非常不同。您有動作聲明(例如在 init 上)和服務聲明(例如服務控制臺 /system/bin/sh)。當一個動作在啟動時被觸發(fā)時,假設是early-init,在該觸發(fā)器中聲明的命令將被執(zhí)行。

    這里有很多細節(jié),但我們在這篇文章中沒有太多空間來討論它(我們實際上可以寫一篇完整的文章)?,F(xiàn)在,讓我們關注這個難題的一個重要部分,守護進程!

    安卓守護進程

    守護進程是在后臺運行并負責管理某些系統(tǒng)功能的進程。它們中的大多數(shù)在啟動時由 init 進程執(zhí)行,并且通常只要系統(tǒng)正常運行,它們就會在后臺運行。

    守護進程通常用于控制和集中訪問系統(tǒng)資源,在 Android 上,許多守護進程是 Android 框架(Java 代碼)和系統(tǒng)資源(網(wǎng)絡、存儲、能源、無線電、日志記錄等)之間的接口。一些例子:

    • ueventd:負責管理硬件設備的連接(設備熱插拔)。它相當于 GNU/Linux 系統(tǒng)上的 udev 或 mdev。
    • vold:(卷守護進程)負責監(jiān)控來自存儲設備的事件。
    • rild:(無線電接口層守護進程)管理與調(diào)制解調(diào)器芯片的通信(語音和數(shù)據(jù))。
    • netd:(網(wǎng)絡管理服務守護進程)負責管理網(wǎng)絡連接(藍牙、Wi-Fi、USB 等)。它相當于 GNU/Linux 系統(tǒng)上的 NetworkManager 或 connman。
    • installd:(安裝守護進程)負責管理 Android 應用程序(* .apk)及其相關資源的安裝。
    • lmkd:(低內(nèi)存殺手守護進程)負責管理內(nèi)核低內(nèi)存殺手接口。

    這是在 Android 11 上運行的守護進程的(大部分)完整列表:

    # ps -A USER PID PPID VSZ RSS WCHAN ADDR S NAME root 1 0 10782796 9696 do_epoll_+ 0 S init root 122 1 10761204 7376 do_sys_po+ 0 S ueventd logd 145 1 10764228 7932 __x64_sys+ 0 S logd lmkd 146 1 10756496 2456 do_epoll_+ 0 S lmkd system 147 1 10759476 5016 do_epoll_+ 0 S servicemanager system 148 1 10761244 6488 do_epoll_+ 0 S hwservicemanager system 149 1 10759572 4028 do_epoll_+ 0 S vndservicemanager root 153 1 10770096 8732 binder_th+ 0 S vold tombstoned 250 1 10755388 2128 do_epoll_+ 0 S tombstoned statsd 266 1 10766140 4572 do_epoll_+ 0 S statsd root 267 1 10781776 9532 binder_th+ 0 S netd credstore 306 1 10764440 7296 binder_th+ 0 S credstore gpu_service 307 1 10762672 6804 binder_th+ 0 S gpuservice system 308 1 10873496 31972 do_epoll_+ 0 S surfaceflinger root 316 1 10756876 2656 do_sys_po+ 0 S netmgr root 318 1 10758880 3072 do_sys_po+ 0 S wifi_forwarder wifi 320 1 10759960 5464 do_select 0 S hostapd_nohidl logd 326 1 10756544 3160 __skb_wai+ 0 S logcat root 352 1 10773084 6376 0 0 S adbd nobody 354 1 10757496 3164 do_sys_po+ 0 S traced_probes nobody 355 1 10757632 3464 do_sys_po+ 0 S traced cameraserver 356 1 58984 17240 binder_th+ 0 S cameraserver drm 357 1 25952 6512 binder_th+ 0 S drmserver incidentd 359 1 10761968 4992 do_epoll_+ 0 S incidentd root 360 1 10765704 6452 binder_th+ 0 S installd iorapd 361 1 10775424 9536 futex_wai+ 0 S iorapd keystore 362 1 10764916 7404 binder_th+ 0 S keystore root 366 1 10765596 5648 binder_th+ 0 S storaged ...

    你有沒有意識到幾乎所有的守護進程都是 Android 特有的?是的,他們確實是。Android 是一個操作系統(tǒng),幾乎所有的用戶空間組件都是從頭開始構建的!

    特別值得一提的是日志記錄在 Android 上的工作原理,因為它不使用像 journald 或 rsyslog 這樣的常見日志記錄 Linux 守護進程。所以現(xiàn)在讓我們來談談這個。

    安卓日志系統(tǒng)

    在 Android 中,日志守護進程 ( logd ) 負責管理所有操作系統(tǒng)日志,從應用程序到框架和本機應用程序。

    對日志的訪問是通過/dev/socket/ 中導出的套接字完成的:

    # ls /dev/socket/logd* /dev/socket/logd /dev/socket/logdr /dev/socket/logdw

    要讀取或?qū)懭肴罩?#xff0c;無需直接訪問這些套接字。為此,應用程序可以使用liblog庫。而在終端中,用戶可以使用log命令寫入日志,并使用logcat工具讀取日志:

    # logcat ... 10-14 13:36:51.722 771 934 D SmsNumberUtils: enter filterDestAddr. destAddr="[BajqU4K5_YhSYbs-7QUn0dOwcmI]" 10-14 13:36:51.723 771 934 D SmsNumberUtils: destAddr is not formatted. 10-14 13:36:51.723 771 934 D SmsNumberUtils: leave filterDestAddr, new destAddr="[BajqU4K5_YhSYbs-7QUn0dOwcmI]" 10-14 13:36:57.054 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service: 10-14 13:36:57.054 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument 10-14 13:36:57.324 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: 10-14 13:36:57.325 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe ... 10-14 14:37:45.408 494 1324 D WifiNl80211Manager: Scan result ready event 10-14 14:37:45.408 494 1324 D WifiNative: Scan result ready event 10-14 14:37:59.109 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service: 10-14 14:37:59.109 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument 10-14 14:37:59.574 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: 10-14 14:37:59.575 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe 10-14 14:38:00.003 642 642 D KeyguardClockSwitch: Updating clock: 2?38 10-14 14:38:59.127 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service: 10-14 14:38:59.127 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument 10-14 14:38:59.585 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: 10-14 14:38:59.585 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe 10-14 14:39:00.003 642 642 D KeyguardClockSwitch: Updating clock: 2?39 10-14 14:39:59.142 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service: 10-14 14:39:59.142 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument 10-14 14:39:59.634 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: 10-14 14:39:59.634 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe 10-14 14:40:00.006 642 642 D KeyguardClockSwitch: Updating clock: 2?40 ...

    經(jīng)過幾年的 Android 工作,我可以說 Android 日志系統(tǒng)相當不錯,在平臺上開發(fā)時非常有用。

    談到開發(fā),在將 Android 移植到嵌入式設備時,編寫與硬件對話的代碼是該過程的重要組成部分。那么為什么我們現(xiàn)在不討論硬件訪問在 Android 中是如何工作的呢?

    硬件訪問和 Android HAL

    在嵌入式 Linux 系統(tǒng)上,對硬件設備的訪問通常通過/dev或/sys 中的條目暴露給應用程序。但是在 Android 上,我們依靠一個稱為HAL(硬件抽象層)的附加層來抽象對硬件設備的訪問。

    主要思想是將系統(tǒng)服務(稍后會詳細介紹)與 Linux 內(nèi)核公開的接口解耦,因此如果內(nèi)核接口發(fā)生變化,您只需更換 HAL,系統(tǒng)服務將繼續(xù)工作。大多數(shù) HAL 基本上是作為獨立進程運行的服務,該進程公開通過 Binder 使用的接口(以稱為HIDL的語言聲明)。Android 中大多數(shù)支持的硬件設備都有 HAL 定義和實現(xiàn),如顯示器、相機、音頻、傳感器等。

    但是要完全理解上圖,就得說說Android框架和系統(tǒng)服務。

    Android 框架和系統(tǒng)服務

    因此,Android 框架是所有 Java(以及現(xiàn)在的 Kotlin)代碼所在的地方。我們在那里有向應用程序公開的系統(tǒng)服務和 API。

    尤其是系統(tǒng)服務,是Android操作系統(tǒng)中非常重要的一部分。它們基本上是公開接口(通過 Binder)以供其他系統(tǒng)服務和應用程序(通過 API)使用的對象。

    在 Android 終端上,您可以使用以下命令列出系統(tǒng)服務:

    # service list Found 184 services: 0 DockObserver: [] 1 SurfaceFlinger: [android.ui.ISurfaceComposer] 2 accessibility: [android.view.accessibility.IAccessibilityManager] 3 account: [android.accounts.IAccountManager] 4 activity: [android.app.IActivityManager] 5 activity_task: [android.app.IActivityTaskManager] 6 adb: [android.debug.IAdbManager] 7 alarm: [android.app.IAlarmManager] 8 android.hardware.identity.IIdentityCredentialStore/default: [android.hardware.identity.IIdentityCredentialStore] 9 android.hardware.light.ILights/default: [android.hardware.light.ILights] 10 android.hardware.power.IPower/default: [android.hardware.power.IPower] 11 android.hardware.rebootescrow.IRebootEscrow/default: [android.hardware.rebootescrow.IRebootEscrow] 12 android.hardware.vibrator.IVibrator/default: [android.hardware.vibrator.IVibrator] 13 android.security.identity: [android.security.identity.ICredentialStoreFactory] 14 android.security.keystore: [android.security.keystore.IKeystoreService] 15 android.service.gatekeeper.IGateKeeperService: [android.service.gatekeeper.IGateKeeperService] 16 app_binding: [] 17 app_integrity: [android.content.integrity.IAppIntegrityManager] 18 appops: [com.android.internal.app.IAppOpsService] 19 appwidget: [com.android.internal.appwidget.IAppWidgetService] 20 audio: [android.media.IAudioService] 21 auth: [android.hardware.biometrics.IAuthService] ...

    假設您正在編寫一個 Android 應用程序來讀取傳感器。這是將要發(fā)生的事情:

  • 應用程序?qū)?Android API (SensorManager) 調(diào)用方法以從傳感器請求數(shù)據(jù)。
  • API (SensorManager) 將向系統(tǒng)服務(在本例中為 SensorService)發(fā)送消息(通過 Binder)。
  • 系統(tǒng)服務負責管理對其控制的資源的訪問。在此示例中,SensorService 管理對傳感器的訪問。它會做的第一件事是檢查權限:應用程序是否有權訪問傳感器?如果沒有,它將向應用程序返回一個異常。如果訪問被授予,它會通過 Binder 向 HAL(傳感器 HAL)發(fā)送消息以請求來自傳感器的數(shù)據(jù)。
  • 傳感器 HAL 將讀取傳感器,可能通過內(nèi)核 IIO 驅(qū)動程序公開的文件,并將數(shù)據(jù)返回到系統(tǒng)服務 (SensorService)。
  • 系統(tǒng)服務(SensorService)將傳感器數(shù)據(jù)返回給應用程序。
  • 這是另一個解釋這些組件如何相互通信的圖表:

    現(xiàn)在您看到 Android 與典型 Linux 系統(tǒng)的真正區(qū)別了嗎?

    我們?nèi)匀恍枰務搼贸绦颉?/p>

    安卓應用

    在嵌入式設備上使用 Android 的優(yōu)勢之一是定義明確的 API 集,這大大簡化了開發(fā)并顯著提高了生產(chǎn)力。

    在 Android 中,應用程序是使用 Google SDK 用 Ja??va 或 Kotlin 編寫的,并打包在擴展名為.apk 的文件中,其中包含應用程序使用的編譯代碼、數(shù)據(jù)和資源。

    Android 應用程序基本上由 4 類組件組成:活動、服務、廣播接收器和內(nèi)容提供器。一個應用程序可以包含一個或多個組件,一件好事是組件可以被重用并通過一種稱為意圖的機制相互通信。

    最后,即使我們想使用Android但不關心操作系統(tǒng)內(nèi)部架構,我們?nèi)匀恍枰獙W習Android范式,這與通常的Linux應用程序開發(fā)有很大不同,比如說在Qt或GTK。

    讓我們現(xiàn)在結束?

    Android 是不是 Linux 發(fā)行版?

    我們可以在這篇文章中看到,Android 確實與典型的 GNU/Linux 系統(tǒng)不同,從我們管理源代碼和構建系統(tǒng)的方式到文件系統(tǒng)的組織和組件,以及所有組件通過 IPC 進行通信的模塊化架構/RPC。

    我們可以清楚地看到的唯一相似之處是 Linux 內(nèi)核的用法。在 Android 中,幾乎所有其他東西都不同。

    那么 Android 是 Linux 發(fā)行版嗎?

    這取決于您如何“分類”Linux 發(fā)行版。如果Linux發(fā)行版是任何使用Linux內(nèi)核的系統(tǒng),那么我們大概可以說Android是Linux發(fā)行版。如果 Linux 發(fā)行版是一個遵循相同標準并共享一些公共組件的系統(tǒng),例如 GNU 項目提供的那些,那么 Android 絕對不是 Linux 發(fā)行版。

    值得一提的是,隨著時間的推移,Android 正在不斷發(fā)展。Google 面臨的主要挑戰(zhàn)之一是軟件更新。他們無法更新任何設備,因為它不在他們的控制之下。

    Apple 制造 SoC、設備本身(當然!)和軟件,幾乎控制著供應鏈的每個方面。因此,他們可以根據(jù)需要(隨時)更新現(xiàn)場的所有設備。

    現(xiàn)在谷歌沒有這個能力。除了 Pixel 設備,他們對三星或小米等其他公司制造的設備沒有太多控制權。

    但他們想要這種控制。這就是為什么他們創(chuàng)建項目來改善這種情況,例如Project Trebble、Generic System Images和Generic Kernel Image。

    我們在本文中看到的許多建筑設計都來自這些項目,而且可能還會有更多。是不是更好,只有用戶和市場會告訴你。

    總結

    以上是生活随笔為你收集整理的Android 与其他基于 Linux 的系统有何不同?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。