色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 學習筆記 > 嵌入式之Android移植學習筆記

嵌入式之Android移植學習筆記 時間:2018-08-23      來源:未知

jni:java native interface java調用c語言的接口

HAL(hardware abtract layer) 硬件抽象層

binder 虛擬設備,不是硬件,用于進程間通訊(獨立的進程通訊機制)

更為安全高效、拿一段內存進行設備通訊、相比共享內存安全、可以創建多個

一般學習過程首先研究binder

總結:binder是更為安全高效的進程間通訊機制

libraries 庫 native 本地

C/C++開發的庫,一般成為本地庫,上層開發一般是java,對于內核而言是應用層

surface Manager 界面開發、圖形開發

Media Framework 音頻框架

SQLite 數據庫、本地的庫

OpenGL|ES 圖形渲染

FreeType 字體素材

WebKit 瀏覽器的內核

SGL 2d圖形渲染

SSL 加密套接層

Libc 標準C庫

Android Runtime 安卓運行時環境 runtime 一般指運行環境

Core Libreries

java 虛擬機將代碼解析到對應的平臺

Application Framework

Activity Manager 活動窗口(界面)

Window Manager 窗口管理

Content Provider 數據共享,可使2個app共享數據

View system 界面渲染

Notification Manager 通知

Package Manager apk包的管理

Telephone Manager 打電話

Resource Manager 資源管理

Location Manager 與GPS相關,定位

XMPP Service 短信接收和發送

Application

應用程序

home等(laucher)

boot.img 是一個uboot + kernal + rootfs

①source bulid/envsetup.sh

②lunch //envsetup里面的一個函數

③extract-bsp

④make -j2

⑤pack //打包

boot.img + system.img + recovery.img = 最終產物

如何進行數據的傳輸?

①adb devices

②adb push .\文件名 /system/lib

出現系統只讀則需要重新掛載 執行 adb remount

③使用adb shell 進入到對應的安卓命令行 //安卓和電腦使用數據線連接,usb可調式確認后才可使用

④使用 adb pull /system/lib/文件名 將對應的文件獲取到當前目錄

使用 exit 退出安卓平臺

⑤使用apk 安裝

adb install *.apk //有個push過程,再進行安裝

關于linux網絡這塊問題解決

使用局域網時用靜態ip連接開發板 橋接

使用wifi時用動態ip連接網絡 自定義橋接 使用wifi網卡

使用網線動態ip連接網絡 自定義橋接 使用以太網卡

5層模型

app 應用

app framework 應用框架

libs 核心庫

HAL 硬件抽象層

kernel 內核

①source build/envsetup.sh

455-460 添加默認的編譯菜單

1506-1512 查找device和vendor目錄下名稱為vendorsetup.sh腳本并執行

查看device/softwinner/fspad-733/vendorsetup.sh

添加產品編譯

8個產品編譯選項保存在 LUNCH_MENU_CHOICES數組中

②lunch

執行build/envsetup.sh 481

488-490,打印選項菜單,讀取用戶輸入值

495-507,根據用戶輸入選項,從LUNCH_MENU_CHOICES數組菜單項內容,保存到selection變量

518-536,將產品名和編譯類型提取,產品名保存到product,編譯類型保存到variant

544-546,賦值到對應的全局變量,導出

550,設置剩余的環境變量

551,打印變量列表

③extrap-bsp

將lichee編譯出來,boot.img和modules.ko拷貝到androidL下面,為下一步打包做準備

④make

執行androidL/Makefile

執行build/core/main.mk

執行對應93行,包含build/core/config.mk

跳轉到build/core/config.mk

63-99,賦值一些列編譯系統內部的子makefile路徑,為后面直接使用,可以編譯成不同類型產物

151,包含build/core/envsetup.mk

跳到該mk下

138行,包含了build/core/product_config.mk

跳轉到該文件

189,讀取源碼樹下面所有的名稱為AndroidProducts.mk產品makefile

獲取device/softwinner/fspad-733/AndroidProducts.mk

該文件獲取device/softwinner/fspad-733/fspad_733.mk

定義軟件系統配置 app屬性 copy產品信息

150-155行,查找device和vendor目錄下面產品目錄名為BoardConfig.mk獲取文件

跳轉到mk下

獲取文件為 device/softwinner/fspad-733/BoardConfig.mk

該文件進行硬件配置

配置板子上硬件,主要是wifi和bt配置

⑤pack //由于一開始source后即可使用pack命令來進行解析

打包 boot.img+system.img+recovery.img

打包為 lichee/tools/pack/sun8iw3p1_andorid_fspad_733_card0.img

添加一個產品的時候需要在哪些文件上添加?

①device/osoftwinner/fspad-733/vendorsetup.sh 下添加產品菜單

②device/softwinner/fspad-733/AndroidProducts.mk 下添加對應產品文件名

③device/softwinner/fspad-733/fspad_733.mk 軟件添加文件

④device/softwinner/fspad-733/BoardConfig.mk 硬件添加文件

A := a A賦值為a

新建一個文件夾hello

在里面

編寫 hello.c

編寫自己的Android.mk

#current module path

①LOCAL_PATH := $(call my-dir)

#clear vars old value

②include $(CLEAR_VARS)

#module name don't need to specify a path.

③LOCAL_MODULE := hello

#specify source file

④LOCAL_SRC_FILES := hello.c \

world.c\

#build this module to executable binary file

⑤include $(BUILD_EXECUTABLE)

最后

編譯

source build/envsetup.sh

lunch 9

mmm device/softwinner/fspad-733/hello/hello.c //絕對路徑

如果在當前目錄下則為 mm 使用當前路徑來進行編譯模塊

為什么會提示對應的依賴錯誤?

No private recovery resources for TARGET_DEVICE fspad-733

make: Entering directory `/home/linux/fs733/androidL'

make: *** No rule to make target `/hello.c', needed by `out/target/product/fspad-733/obj/EXECUTABLES/hello_intermediates/hello.o'. Stop.

make: Leaving directory `/home/linux/fs733/androidL'

路徑出錯

可能是自己對應的代碼敲寫錯誤導致

adb的使用說明:

adb的使用

使用過程:

1.通過usb線將主機和平板從機連接,打開PhoenixSuit工具,必須顯示和設備已經連接上。

2.使用以下命令與平板android系統交互:

a.adb shell 進入到android的linux的命令行模式

exit 進入到命令行模式之后需要的退出

b.adb push 主機需要被推送的文件目錄 平板存放推送文件的位置

將文件推送到從機指定目錄

c.adb pull 平板中需要被拉去出來的文件的位置

從從機拉取文件到主機

d.adb install xxxx.apk 將xxxx.apk android應用程序安裝到從機上

e.adb devices 列出所有連接到主機的從機信息

tips:在敲adb命令的時候,如果提示read-only file system的時候,你就使用命令adb remount 重新掛載一下

android的文件系統就可以了。如果說還是不行,任然提示該信息,那么就要修改從機目錄屬性。

編譯完成后根據

Install: out/target/product/fspad-733/system/bin/hello

來找到對應目錄將文件拷貝到windows平臺下

打開phoenixSuit程序,連接安卓后

在含有adb.exe的文件下面的空白處點擊 shift + 鼠標右鍵 訓責phoenixSuit運行

使用adb push .\hello /system/bin (由于是執行phoenixSuit后,/system/bin直接執行)

使用adb shell進入安卓shell

hello 即可打印對應的函數

init啟動流程

①解析/init.rc

action_list 、service_list

②添加action到action_queue中

③執行action相關命令(與action的序列有關),查看是否有需要重新啟動的服務,如果有則啟動這些服務

④poll監聽3路socket

屬性設置→修改屬性

組合鍵→對應服務

服務進程退出→將標志位置為重啟與restart進行結合重啟進程

init啟動zygote

①修改進程名

②android Runtime的start方法 啟動虛擬機 vm

③調用執行zygote init的main方法

C++代碼截止

init啟動后執行system/core/init/init.c

1059 判斷ueventd 還是init

1060 如果啟動設備,解析設置uevent事件,創建設備文件

1062 若是啟動watchdogd 設置看門狗以及喂狗

1072-1081 創建一些目錄并掛在文件系統

1120 從文件中加載系統屬性默認值

1123 解析init.rc 建立服務鏈表和動作鏈表

1128-1134 創建內部action

1139 創建init動作init到動作鏈表

1152 添加early-init動作到動作鏈表

action_for_each_trigger("early-init", action_add_queue_tail);

1145-1154 創建內部action并觸發

①early_init

②wait_for_coldboot_done(內部動作)

等待冷啟動設備掃描(為每個設備創建設備文件)

③keychord_init

打開組合鍵的監聽文件

④console_init

檢測console終端是否存在,顯示logo

⑤property_service_init

打開屬性修改服務的socket

⑥signal_init

設置sigchild信號處理,回收孤兒進程資源

⑦late-init

⑧queue_property_trigger

促發rc腳本中property:屬性名= 屬性值 形式的動作

1166 主循環

①execute_one_command();

執行一個命令

②restart_processes();

掃描是否有服務需要重啟

③ 監控并處理屬性修改請求、組合按鍵啟動服務請求和檢測服務進程退出

init.rc本地服務被啟動

①ueventd 接收、解析和處理uevent,新建/刪除設備文件,固件加載

②console 終端,啟動shell程序

③adbc adb程序服務端

④service manager 服務管理程序

⑤vold(volume daemon) 完成系統cdrom,usb大量存儲,mmc卡等擴展存儲的掛載任務

⑥netd 網絡服務

⑦surfaceflinger 繪制android程序的ui,完成2d和3d的無縫融合

⑧zygote 啟動虛擬機服務

⑨media 多媒體服務

⑩bootanim 負責android播放開機啟動動畫以及背景音樂

其中關鍵

①zygote

定義 在init.zygote32.rc

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

class main

socket zygote stream 660 root system

onrestart write /sys/android_power/request_state wake

onrestart write /sys/power/state on

onrestart restart media

onrestart restart netd

可以看到主要啟動的程序 app_process

實現在frameworks/base/cmds/app_process/app_main.cpp‘

186 main函數

解析參數后

201行之后得到

227-236 將參數 runtime

246-264 將后面參數解析出來,得到結果

301-304 進程名更改nicename = zygote

307 運行類com.android.internal.os.ZygoteInit

runtime.start();

rumtime是AndroidRuntime類

通過找到androidruntime類找到調用的start成員函數

frameworks/base/core/jni/AndroidRuntime.cpp 930行

966 啟動java虛擬機

974 注冊andorid本地函數

988 找到string類

1006 將傳進來的classname com.android.internal.os.ZygoteInit

轉換為路徑com/android/internal/os/ZygoteInit

1007 找到com/android/internal/os/ZygoteInit類

1018 com/android/internal/os/ZygoteInit類的main函數進入到java

ZygoteInit類定義在目錄

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

轉到里面 main函數 644

通過644里面函數 同時AndroidRuntime那邊將參數"start-system-server"也傳進來

668行通過注冊 zygote socket服務端

671 預加載了一些資源和庫

686 調用startSystemServer函數啟動了systemserver

查看startSystemServer 在573行定義

607行 創建一個子進程來運行forkSystemServer

624調用handleSystemServerProcess實現在494行

537行 RuntimeInit.zygoteInit();

該函數定義在rameworks/base/core/java/com/android/internal/os/RuntimeInit.java 267行

查看applicationInit函數在297行定義

關鍵321行,invokeStaticMain();

其中第一個參數就是前面傳遞過來的 com.android.server.SystemServer

該句子調用了com.android.server.SystemServer類的main函數

定義在frameworks/base/services/java/com/android/server/SystemServer.java 170

運行了run函數,定義在179

255-257 啟動了好多services

其中316行,ActivityManagerService的systemReady函數,表示ActivityManagerService的ready

ActivityManagerService的定義。frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

在11373,在systemReady調用startHomeActivityLocked啟動桌面應用

bootanimation

init.rc 中

service bootanim /system/bin/bootanimation

class main

user graphic

group graphics

disabled

oneshot

找到bootanimation源碼 frameworks/base/cmds/bootanimation/bootanimation_main.cpp 39行

55行,創建開機動畫播放線程

找到BootAnimation類,打開可以看到是利用opengl渲染的。

230行,看readyToRun函數

291行~301行,判斷在/sytem/media目錄下否有bootanimation的素材壓縮包。

313行,在線程循環函數中判斷了上面判斷結果,是否有bootanimation.zip

如果有就播放,如果沒有就調用android函數。

328行,android函數定義

330,331行,可以看到定義圖片的位置。

下面opengl播放圖片。

找到圖片放的位置, find . -depth -name android-logo-mask.png

在frameworks/base/core/res/assets/images/android-logo-mask.png

所以如何定制開機啟動動畫?

1.在/data/local或/system/media目錄下添加自己的動畫bootanimation.zip文件(同時也可以添加相應的開機音樂boot.mp3),這樣在系統啟動時就會播放自己的開機動畫和播放音樂。

2.可以替換一下frameworks/base/core/res/assets/images/ 目錄下兩張圖片。

粗略啟動流程

uboot

內核

掛載根文件系統

掛載system系統 里面含有很多文件

執行第一個進程init

解析init.rc文件

執行了一些列命令,啟動了一些服務,后退化成為一個守護進程

該守護進程 ①系統屬性修改 ②重啟子進程 ③組合鍵按下啟動對應服務

其中有一個很重要的服務zygote

創建虛擬機

運行systemserver 啟動很多java服務

其中有個很重要的服務activityManager執行一個systemReady函數運行了一個界面

VFS 統一文件系統差異,為上層提供接口

HAL

統一下層硬件差異,為上層提供接口

為了保護硬件供應商的知識產權

不是所用硬件設備都有標準的linux kernel接口

為什么open在modules中,而close在device

每個device是對應不同的關閉方式,所以在device中關閉,而打開只需統一打開

hal_*.h

#include

//stub具體某一個device id號

#define LED1 1

//led模塊stub的id

#define LED_HARDWARE_MODULE_ID "led"

①定義一個led_module_t 模塊結構體

里面第一個結構體必須為struct hw_module_t 的對象

struct led_module_t {

struct hw_module_t common;

};

②定義led_device_t 設備結構體

里面第一個為struct hw_device_t 結構體

struct led_device_t {

struct hw_device_t common;

int fd; //存放調用open返回描述符

int (*led_on)(struct hw_device_t *dev); //

int (*led_off)(struct hw_device_t *dev);

};

hal_*.c

①定義一個hw_module_t 對象HAL_MODULE_INFO_SYM必須為這個對象

在對象里面對其成員進行初始化

struct hw_module_t HAL_MODULE_INFO_SYM = {

tag: HARDWARE_MODULE_TAG,

version_major: 1,

version_minor: 0,

id: LED_HARDWARE_MODULE_ID,//頭文件中含有

name: "led module",

author: "farsight",

methods: &led_module_methods,//主要是實現一些方法

};

②定義一個 hw_module_methods_t 對象led_module_methods 里面裝著一個led_open函數地址

static struct hw_module_methods_t led_module_methods = {

open: led_open,

};

③定義 led_open函數

static int led_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device)

{

char devpath[128] = "/dev/";

struct led_device_t *dev;

//函數中新建一個結構體指針指向led_device_t開辟的空間中

//1.分配描述被打開的設備device結構體

dev = (struct led_device_t *)malloc(sizeof(struct led_device_t));

if (!dev) {

LOGE("alloc device memory failed\n");

return -EFAULT;

}

memset(dev, 0, sizeof(struct led_device_t));

//對其結構體成員進行賦值

//2.填充設備結構體的成員

dev->common.tag = HARDWARE_DEVICE_TAG;.//必須為這個

dev->common.version = 0;

dev->common.module = (struct hw_module_t *)module;

dev->common.close = led_close;

dev->led_on = led_on;

dev->led_off = led_off;

strcat(devpath, name);//devpath設備文件路徑 /dev/name

//通過結構體賦值close、led_on、led_off

//3.調用系統調用open,open再通過linux內核調用到驅動代碼中的led_open函數

dev->fd = open(devpath, O_RDWR);

if (dev->fd == -1) {

free(dev);

LOGE("open device failed\n");

return -1;

}

//4.返回打開的具體設備的描述結構體指針

*device = &(dev->common);

return 0;

}

④led_on、led_off、led_close的實現

主要是調用了系統調用,通過系統調用將設備的信息傳遞給結構體

static int led_on(struct hw_device_t* device)

{

struct led_device_t *dev = (struct led_device_t *)device;

if (dev->fd != -1)

return ioctl(dev->fd, LED_ON); //調用系統調用ioctl,ioctl回去通過linux內核調用到驅動中unlocked_ioctl

else

return -1;

}

static int led_off(struct hw_device_t* device)

{

struct led_device_t *dev = (struct led_device_t *)device;

if (dev->fd != -1)

return ioctl(dev->fd, LED_OFF);

else

return -1;

}

static int led_close(struct hw_device_t* device)

{

struct led_device_t *dev = (struct led_device_t *)device;

if (dev->fd != -1) {

close(dev->fd);//調用系統調用close,close回去通過linux內核調用到驅動中led_close

free(dev);

}

return 0;

}

lib中

使用hal提供的框架接口 hw_get_module();//獲取到對應hal里模塊的結構體地址

通過訪問這個結構體的methods里的led_open即可調用到底層的open

touch可以更新對應的代碼時間戳,使編譯的時候重新編譯

整體一個流程:

①app上 通過led_open會調用coreLib庫

②庫中使用hal接口函數hw_get_module();

來通過LED_HARDWARE_MODULE_ID進行獲取到對應的模塊module,

③通過獲取模塊中的第一個成員hw_modules_t 中的mothods方法集合里面的open方法將對應的模塊傳入進入到hal中

④在hal中通過上面傳入下來的name,將器設備路徑給獲取后,通過打開設備驅動的open函數即完成獲取,并且創建一個led_dev結構體,通過結構體進行初始化,將其傳遞給在coreLib中的device對象,便于后續的操作使用,雖然傳遞過去的不是led_dev對應的結構體,但是由于hw_device_t與對應結構體的首地址一致,所以通過強轉即可獲取到led_dev對應的方法

Android硬件抽象層框架代碼在 hardware目錄

Dalvik虛擬機作用:

①Dalvik基于虛擬機,JVM基于棧,所以效率更高

②Dalvik可運行壓縮過,針對內存優化過的dex,減少文件尺寸,提高查找類的速度

③Dalvik每一個應用程序運行與一個獨立進程

android系統中,使用 make ramdisk命令 只編譯文件系統

android系統app framework層,HAL層,core Libs 代碼編譯之后在system.img

通過GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V")找到對應的方法應該

①([Ljava/lang/String;)V") ===》 [ 數組 String =》tring 類型,參數 V ===》void 返回值

②main為函數名 即可推出 void main (String [] )

init.rc包含5個部分

①import導入 ②commond命令 ③service服務 ④action行為 ⑤option選項

簡述linux內核編譯步驟

①進入lichee ./build.sh config //編譯選擇配置

②./build.sh 編譯內核和uboot

簡述android源碼的編譯步驟(以fspad-733配套androidL源碼為例)進入androidL

①source build/envsetup.sh 添加配置調試命令到shell進程

②lunch 選擇編譯的產品好

③extract-bsp 將內核生成的bImage和模塊拷貝到androidL/device/softwinner/fspad-733/下

④make -j2 編譯

androidL ===>生成 system.img(非內核部分) + ramdisk.img(rootfs) + recovery.img(恢復出廠鏡像)

lichee ===>生成 uboot.bin + uImage === > bImage

簡單介紹一下Android系統中的HAL,并說出舊HAL架構libhardware_legacy和新HAL架構libhardware的區別

①屏蔽下層硬件差異,為上層提供統一接口

②保護硬件的知識產權

③硬件設備不全都有linux kernel接口

舊的沒有經過封裝,上層可以直接操走硬件

新的通過hal層將硬件分類,一個類一個stub,通過stub再進行訪問

請介紹Android系統架構,并簡單說明每層架構的作用

①linux內核 在內核基礎上添加了android特有的驅動,binder驅動(進程間通訊)

②HAL 屏蔽下層差異,為上層提供統一接口

③核心庫 libs 一些三方庫和c/c++庫的提供,

runtime Dalvik虛擬機和對應的運行環境

④app framework 讓應用開發更為方便

⑤app 一些與用戶進行交互的程序

android源碼樹添加新產品目錄支持,必須有哪幾個文件?

①vendorsetup.sh 添加產品編譯的選項

②BoardConfig.mk 硬件方面定制

③AndroidProduct.mk 產品文件列表

④產品名.mk 定制軟件系統的配置

上一篇:c語言指針詳解,學霸課堂記錄

下一篇:C++學習總結,學霸課堂筆記

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 久久久久亚洲AV成人无码 | 亚洲AV中文无码字幕色 | 天堂69堂在线精品视频软件 | 久久久久亚洲AV成人网人人网站 | 日韩成人无码中文字幕 | 日本高清在线视频WWW色 | 亚洲国产精品无码久久青草 | 人人妻人人澡人人爽欧美二区 | 国产露脸无码A区久久 | 国产高清japanese在线播放e | 久久久久久亚洲AV无码专区 | 亚洲综合AV一区二区三区不卡 | 欧美又大又粗午夜剧场免费 | 蜜桃AV少妇久久久久久高潮不断 | 欧美大片aaaaa免费观看 | 欧美成人午夜免费影院 | 好看的欧美熟妇www在线 | 亚洲成色av网站午夜影视 | 国产人成高清在线视频99最全资源 | 九九九九视频 | 99久久亚洲精品无码毛片 | 国产熟女乱子视频正在播放 | 久久久久免费看黄A片 | 揉捏奶头高潮呻吟视频 | 中文日产无乱码av在线观 | 少妇SPA推油被扣高潮在线观看 | 国模大胆一区二区三区 | 亚洲欧美一区二区三区在线 | 日本一区二区三区精品视频在线观看 | 黄色大片免费的 | 国产精品视频一区二区三 | 中文字幕AV伊人AV无码AV狼人 | 女人高潮娇喘抽搐喷水视频 | 日木AV无码专区亚洲AV毛片 | 黑人巨摘花第一次出血 | 黑白配高清国语免费观看 | 日本二区在线播放 | 中国女人黄色一片 | 黑人女人性较视频免费视频 | 亚洲AV日韩AV无码A一区 | 精品日产一区二区三区 |