當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 學(xué)習(xí)筆記 > 嵌入式之Android移植學(xué)習(xí)筆記
嵌入式之Android移植學(xué)習(xí)筆記
時(shí)間:2018-08-23 來(lái)源:未知
jni:java native interface java調(diào)用c語(yǔ)言的接口
HAL(hardware abtract layer) 硬件抽象層
binder 虛擬設(shè)備,不是硬件,用于進(jìn)程間通訊(獨(dú)立的進(jìn)程通訊機(jī)制)
更為安全高效、拿一段內(nèi)存進(jìn)行設(shè)備通訊、相比共享內(nèi)存安全、可以創(chuàng)建多個(gè)
一般學(xué)習(xí)過(guò)程首先研究binder
總結(jié):binder是更為安全高效的進(jìn)程間通訊機(jī)制
libraries 庫(kù) native 本地
C/C++開(kāi)發(fā)的庫(kù),一般成為本地庫(kù),上層開(kāi)發(fā)一般是java,對(duì)于內(nèi)核而言是應(yīng)用層
surface Manager 界面開(kāi)發(fā)、圖形開(kāi)發(fā)
Media Framework 音頻框架
SQLite 數(shù)據(jù)庫(kù)、本地的庫(kù)
OpenGL|ES 圖形渲染
FreeType 字體素材
WebKit 瀏覽器的內(nèi)核
SGL 2d圖形渲染
SSL 加密套接層
Libc 標(biāo)準(zhǔn)C庫(kù)
Android Runtime 安卓運(yùn)行時(shí)環(huán)境 runtime 一般指運(yùn)行環(huán)境
Core Libreries
java 虛擬機(jī)將代碼解析到對(duì)應(yīng)的平臺(tái)
Application Framework
Activity Manager 活動(dòng)窗口(界面)
Window Manager 窗口管理
Content Provider 數(shù)據(jù)共享,可使2個(gè)app共享數(shù)據(jù)
View system 界面渲染
Notification Manager 通知
Package Manager apk包的管理
Telephone Manager 打電話
Resource Manager 資源管理
Location Manager 與GPS相關(guān),定位
XMPP Service 短信接收和發(fā)送
Application
應(yīng)用程序
home等(laucher)
boot.img 是一個(gè)uboot + kernal + rootfs
①source bulid/envsetup.sh
②lunch //envsetup里面的一個(gè)函數(shù)
③extract-bsp
④make -j2
⑤pack //打包
boot.img + system.img + recovery.img = 最終產(chǎn)物
如何進(jìn)行數(shù)據(jù)的傳輸?
①adb devices
②adb push .\文件名 /system/lib
出現(xiàn)系統(tǒng)只讀則需要重新掛載 執(zhí)行 adb remount
③使用adb shell 進(jìn)入到對(duì)應(yīng)的安卓命令行 //安卓和電腦使用數(shù)據(jù)線連接,usb可調(diào)式確認(rèn)后才可使用
④使用 adb pull /system/lib/文件名 將對(duì)應(yīng)的文件獲取到當(dāng)前目錄
使用 exit 退出安卓平臺(tái)
⑤使用apk 安裝
adb install *.apk //有個(gè)push過(guò)程,再進(jìn)行安裝
關(guān)于linux網(wǎng)絡(luò)這塊問(wèn)題解決
使用局域網(wǎng)時(shí)用靜態(tài)ip連接開(kāi)發(fā)板 橋接
使用wifi時(shí)用動(dòng)態(tài)ip連接網(wǎng)絡(luò) 自定義橋接 使用wifi網(wǎng)卡
使用網(wǎng)線動(dòng)態(tài)ip連接網(wǎng)絡(luò) 自定義橋接 使用以太網(wǎng)卡
5層模型
app 應(yīng)用
app framework 應(yīng)用框架
libs 核心庫(kù)
HAL 硬件抽象層
kernel 內(nèi)核
①source build/envsetup.sh
455-460 添加默認(rèn)的編譯菜單
1506-1512 查找device和vendor目錄下名稱為vendorsetup.sh腳本并執(zhí)行
查看device/softwinner/fspad-733/vendorsetup.sh
添加產(chǎn)品編譯
8個(gè)產(chǎn)品編譯選項(xiàng)保存在 LUNCH_MENU_CHOICES數(shù)組中
②lunch
執(zhí)行build/envsetup.sh 481
488-490,打印選項(xiàng)菜單,讀取用戶輸入值
495-507,根據(jù)用戶輸入選項(xiàng),從LUNCH_MENU_CHOICES數(shù)組菜單項(xiàng)內(nèi)容,保存到selection變量
518-536,將產(chǎn)品名和編譯類型提取,產(chǎn)品名保存到product,編譯類型保存到variant
544-546,賦值到對(duì)應(yīng)的全局變量,導(dǎo)出
550,設(shè)置剩余的環(huán)境變量
551,打印變量列表
③extrap-bsp
將lichee編譯出來(lái),boot.img和modules.ko拷貝到androidL下面,為下一步打包做準(zhǔn)備
④make
執(zhí)行androidL/Makefile
執(zhí)行build/core/main.mk
執(zhí)行對(duì)應(yīng)93行,包含build/core/config.mk
跳轉(zhuǎn)到build/core/config.mk
63-99,賦值一些列編譯系統(tǒng)內(nèi)部的子makefile路徑,為后面直接使用,可以編譯成不同類型產(chǎn)物
151,包含build/core/envsetup.mk
跳到該mk下
138行,包含了build/core/product_config.mk
跳轉(zhuǎn)到該文件
189,讀取源碼樹(shù)下面所有的名稱為AndroidProducts.mk產(chǎn)品makefile
獲取device/softwinner/fspad-733/AndroidProducts.mk
該文件獲取device/softwinner/fspad-733/fspad_733.mk
定義軟件系統(tǒng)配置 app屬性 copy產(chǎn)品信息
150-155行,查找device和vendor目錄下面產(chǎn)品目錄名為BoardConfig.mk獲取文件
跳轉(zhuǎn)到mk下
獲取文件為 device/softwinner/fspad-733/BoardConfig.mk
該文件進(jìn)行硬件配置
配置板子上硬件,主要是wifi和bt配置
⑤pack //由于一開(kāi)始source后即可使用pack命令來(lái)進(jìn)行解析
打包 boot.img+system.img+recovery.img
打包為 lichee/tools/pack/sun8iw3p1_andorid_fspad_733_card0.img
添加一個(gè)產(chǎn)品的時(shí)候需要在哪些文件上添加?
①device/osoftwinner/fspad-733/vendorsetup.sh 下添加產(chǎn)品菜單
②device/softwinner/fspad-733/AndroidProducts.mk 下添加對(duì)應(yīng)產(chǎn)品文件名
③device/softwinner/fspad-733/fspad_733.mk 軟件添加文件
④device/softwinner/fspad-733/BoardConfig.mk 硬件添加文件
A := a A賦值為a
新建一個(gè)文件夾hello
在里面
編寫(xiě) hello.c
編寫(xiě)自己的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 //絕對(duì)路徑
如果在當(dāng)前目錄下則為 mm 使用當(dāng)前路徑來(lái)進(jìn)行編譯模塊
為什么會(huì)提示對(duì)應(yīng)的依賴錯(cuò)誤?
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'
路徑出錯(cuò)
可能是自己對(duì)應(yīng)的代碼敲寫(xiě)錯(cuò)誤導(dǎo)致
adb的使用說(shuō)明:
adb的使用
使用過(guò)程:
1.通過(guò)usb線將主機(jī)和平板從機(jī)連接,打開(kāi)PhoenixSuit工具,必須顯示和設(shè)備已經(jīng)連接上。
2.使用以下命令與平板android系統(tǒng)交互:
a.adb shell 進(jìn)入到android的linux的命令行模式
exit 進(jìn)入到命令行模式之后需要的退出
b.adb push 主機(jī)需要被推送的文件目錄 平板存放推送文件的位置
將文件推送到從機(jī)指定目錄
c.adb pull 平板中需要被拉去出來(lái)的文件的位置
從從機(jī)拉取文件到主機(jī)
d.adb install xxxx.apk 將xxxx.apk android應(yīng)用程序安裝到從機(jī)上
e.adb devices 列出所有連接到主機(jī)的從機(jī)信息
tips:在敲adb命令的時(shí)候,如果提示read-only file system的時(shí)候,你就使用命令adb remount 重新掛載一下
android的文件系統(tǒng)就可以了。如果說(shuō)還是不行,任然提示該信息,那么就要修改從機(jī)目錄屬性。
編譯完成后根據(jù)
Install: out/target/product/fspad-733/system/bin/hello
來(lái)找到對(duì)應(yīng)目錄將文件拷貝到windows平臺(tái)下
打開(kāi)phoenixSuit程序,連接安卓后
在含有adb.exe的文件下面的空白處點(diǎn)擊 shift + 鼠標(biāo)右鍵 訓(xùn)責(zé)phoenixSuit運(yùn)行
使用adb push .\hello /system/bin (由于是執(zhí)行phoenixSuit后,/system/bin直接執(zhí)行)
使用adb shell進(jìn)入安卓shell
hello 即可打印對(duì)應(yīng)的函數(shù)
init啟動(dòng)流程
①解析/init.rc
action_list 、service_list
②添加action到action_queue中
③執(zhí)行action相關(guān)命令(與action的序列有關(guān)),查看是否有需要重新啟動(dòng)的服務(wù),如果有則啟動(dòng)這些服務(wù)
④poll監(jiān)聽(tīng)3路socket
屬性設(shè)置→修改屬性
組合鍵→對(duì)應(yīng)服務(wù)
服務(wù)進(jìn)程退出→將標(biāo)志位置為重啟與restart進(jìn)行結(jié)合重啟進(jìn)程
init啟動(dòng)zygote
①修改進(jìn)程名
②android Runtime的start方法 啟動(dòng)虛擬機(jī) vm
③調(diào)用執(zhí)行zygote init的main方法
C++代碼截止
init啟動(dòng)后執(zhí)行system/core/init/init.c
1059 判斷ueventd 還是init
1060 如果啟動(dòng)設(shè)備,解析設(shè)置uevent事件,創(chuàng)建設(shè)備文件
1062 若是啟動(dòng)watchdogd 設(shè)置看門狗以及喂狗
1072-1081 創(chuàng)建一些目錄并掛在文件系統(tǒng)
1120 從文件中加載系統(tǒng)屬性默認(rèn)值
1123 解析init.rc 建立服務(wù)鏈表和動(dòng)作鏈表
1128-1134 創(chuàng)建內(nèi)部action
1139 創(chuàng)建init動(dòng)作init到動(dòng)作鏈表
1152 添加early-init動(dòng)作到動(dòng)作鏈表
action_for_each_trigger("early-init", action_add_queue_tail);
1145-1154 創(chuàng)建內(nèi)部action并觸發(fā)
①early_init
②wait_for_coldboot_done(內(nèi)部動(dòng)作)
等待冷啟動(dòng)設(shè)備掃描(為每個(gè)設(shè)備創(chuàng)建設(shè)備文件)
③keychord_init
打開(kāi)組合鍵的監(jiān)聽(tīng)文件
④console_init
檢測(cè)console終端是否存在,顯示logo
⑤property_service_init
打開(kāi)屬性修改服務(wù)的socket
⑥signal_init
設(shè)置sigchild信號(hào)處理,回收孤兒進(jìn)程資源
⑦late-init
⑧queue_property_trigger
促發(fā)rc腳本中property:屬性名= 屬性值 形式的動(dòng)作
1166 主循環(huán)
①execute_one_command();
執(zhí)行一個(gè)命令
②restart_processes();
掃描是否有服務(wù)需要重啟
③ 監(jiān)控并處理屬性修改請(qǐng)求、組合按鍵啟動(dòng)服務(wù)請(qǐng)求和檢測(cè)服務(wù)進(jìn)程退出
init.rc本地服務(wù)被啟動(dòng)
①ueventd 接收、解析和處理uevent,新建/刪除設(shè)備文件,固件加載
②console 終端,啟動(dòng)shell程序
③adbc adb程序服務(wù)端
④service manager 服務(wù)管理程序
⑤vold(volume daemon) 完成系統(tǒng)cdrom,usb大量存儲(chǔ),mmc卡等擴(kuò)展存儲(chǔ)的掛載任務(wù)
⑥netd 網(wǎng)絡(luò)服務(wù)
⑦surfaceflinger 繪制android程序的ui,完成2d和3d的無(wú)縫融合
⑧zygote 啟動(dòng)虛擬機(jī)服務(wù)
⑨media 多媒體服務(wù)
⑩bootanim 負(fù)責(zé)android播放開(kāi)機(jī)啟動(dòng)動(dòng)畫(huà)以及背景音樂(lè)
其中關(guān)鍵
①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
可以看到主要啟動(dòng)的程序 app_process
實(shí)現(xiàn)在frameworks/base/cmds/app_process/app_main.cpp‘
186 main函數(shù)
解析參數(shù)后
201行之后得到
227-236 將參數(shù) runtime
246-264 將后面參數(shù)解析出來(lái),得到結(jié)果
301-304 進(jìn)程名更改nicename = zygote
307 運(yùn)行類com.android.internal.os.ZygoteInit
runtime.start();
rumtime是AndroidRuntime類
通過(guò)找到androidruntime類找到調(diào)用的start成員函數(shù)
frameworks/base/core/jni/AndroidRuntime.cpp 930行
966 啟動(dòng)java虛擬機(jī)
974 注冊(cè)andorid本地函數(shù)
988 找到string類
1006 將傳進(jìn)來(lái)的classname com.android.internal.os.ZygoteInit
轉(zhuǎn)換為路徑com/android/internal/os/ZygoteInit
1007 找到com/android/internal/os/ZygoteInit類
1018 com/android/internal/os/ZygoteInit類的main函數(shù)進(jìn)入到j(luò)ava
ZygoteInit類定義在目錄
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
轉(zhuǎn)到里面 main函數(shù) 644
通過(guò)644里面函數(shù) 同時(shí)AndroidRuntime那邊將參數(shù)"start-system-server"也傳進(jìn)來(lái)
668行通過(guò)注冊(cè) zygote socket服務(wù)端
671 預(yù)加載了一些資源和庫(kù)
686 調(diào)用startSystemServer函數(shù)啟動(dòng)了systemserver
查看startSystemServer 在573行定義
607行 創(chuàng)建一個(gè)子進(jìn)程來(lái)運(yùn)行forkSystemServer
624調(diào)用handleSystemServerProcess實(shí)現(xiàn)在494行
537行 RuntimeInit.zygoteInit();
該函數(shù)定義在rameworks/base/core/java/com/android/internal/os/RuntimeInit.java 267行
查看applicationInit函數(shù)在297行定義
關(guān)鍵321行,invokeStaticMain();
其中第一個(gè)參數(shù)就是前面?zhèn)鬟f過(guò)來(lái)的 com.android.server.SystemServer
該句子調(diào)用了com.android.server.SystemServer類的main函數(shù)
定義在frameworks/base/services/java/com/android/server/SystemServer.java 170
運(yùn)行了run函數(shù),定義在179
255-257 啟動(dòng)了好多services
其中316行,ActivityManagerService的systemReady函數(shù),表示ActivityManagerService的ready
ActivityManagerService的定義。frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
在11373,在systemReady調(diào)用startHomeActivityLocked啟動(dòng)桌面應(yīng)用
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行,創(chuàng)建開(kāi)機(jī)動(dòng)畫(huà)播放線程
找到BootAnimation類,打開(kāi)可以看到是利用opengl渲染的。
230行,看readyToRun函數(shù)
291行~301行,判斷在/sytem/media目錄下否有bootanimation的素材壓縮包。
313行,在線程循環(huán)函數(shù)中判斷了上面判斷結(jié)果,是否有bootanimation.zip
如果有就播放,如果沒(méi)有就調(diào)用android函數(shù)。
328行,android函數(shù)定義
330,331行,可以看到定義圖片的位置。
下面opengl播放圖片。
找到圖片放的位置, find . -depth -name android-logo-mask.png
在frameworks/base/core/res/assets/images/android-logo-mask.png
所以如何定制開(kāi)機(jī)啟動(dòng)動(dòng)畫(huà)?
1.在/data/local或/system/media目錄下添加自己的動(dòng)畫(huà)bootanimation.zip文件(同時(shí)也可以添加相應(yīng)的開(kāi)機(jī)音樂(lè)boot.mp3),這樣在系統(tǒng)啟動(dòng)時(shí)就會(huì)播放自己的開(kāi)機(jī)動(dòng)畫(huà)和播放音樂(lè)。
2.可以替換一下frameworks/base/core/res/assets/images/ 目錄下兩張圖片。
粗略啟動(dòng)流程
uboot
內(nèi)核
掛載根文件系統(tǒng)
掛載system系統(tǒng) 里面含有很多文件
執(zhí)行第一個(gè)進(jìn)程init
解析init.rc文件
執(zhí)行了一些列命令,啟動(dòng)了一些服務(wù),后退化成為一個(gè)守護(hù)進(jìn)程
該守護(hù)進(jìn)程 ①系統(tǒng)屬性修改 ②重啟子進(jìn)程 ③組合鍵按下啟動(dòng)對(duì)應(yīng)服務(wù)
其中有一個(gè)很重要的服務(wù)zygote
創(chuàng)建虛擬機(jī)
運(yùn)行systemserver 啟動(dòng)很多java服務(wù)
其中有個(gè)很重要的服務(wù)activityManager執(zhí)行一個(gè)systemReady函數(shù)運(yùn)行了一個(gè)界面
VFS 統(tǒng)一文件系統(tǒng)差異,為上層提供接口
HAL
統(tǒng)一下層硬件差異,為上層提供接口
為了保護(hù)硬件供應(yīng)商的知識(shí)產(chǎn)權(quán)
不是所用硬件設(shè)備都有標(biāo)準(zhǔn)的linux kernel接口
為什么open在modules中,而close在device
每個(gè)device是對(duì)應(yīng)不同的關(guān)閉方式,所以在device中關(guān)閉,而打開(kāi)只需統(tǒng)一打開(kāi)
hal_*.h
#include
//stub具體某一個(gè)device id號(hào)
#define LED1 1
//led模塊stub的id
#define LED_HARDWARE_MODULE_ID "led"
①定義一個(gè)led_module_t 模塊結(jié)構(gòu)體
里面第一個(gè)結(jié)構(gòu)體必須為struct hw_module_t 的對(duì)象
struct led_module_t {
struct hw_module_t common;
};
②定義led_device_t 設(shè)備結(jié)構(gòu)體
里面第一個(gè)為struct hw_device_t 結(jié)構(gòu)體
struct led_device_t {
struct hw_device_t common;
int fd; //存放調(diào)用open返回描述符
int (*led_on)(struct hw_device_t *dev); //
int (*led_off)(struct hw_device_t *dev);
};
hal_*.c
①定義一個(gè)hw_module_t 對(duì)象HAL_MODULE_INFO_SYM必須為這個(gè)對(duì)象
在對(duì)象里面對(duì)其成員進(jìn)行初始化
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,//主要是實(shí)現(xiàn)一些方法
};
②定義一個(gè) hw_module_methods_t 對(duì)象led_module_methods 里面裝著一個(gè)led_open函數(shù)地址
static struct hw_module_methods_t led_module_methods = {
open: led_open,
};
③定義 led_open函數(shù)
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;
//函數(shù)中新建一個(gè)結(jié)構(gòu)體指針指向led_device_t開(kāi)辟的空間中
//1.分配描述被打開(kāi)的設(shè)備device結(jié)構(gòu)體
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));
//對(duì)其結(jié)構(gòu)體成員進(jìn)行賦值
//2.填充設(shè)備結(jié)構(gòu)體的成員
dev->common.tag = HARDWARE_DEVICE_TAG;.//必須為這個(gè)
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設(shè)備文件路徑 /dev/name
//通過(guò)結(jié)構(gòu)體賦值close、led_on、led_off
//3.調(diào)用系統(tǒng)調(diào)用open,open再通過(guò)linux內(nèi)核調(diào)用到驅(qū)動(dòng)代碼中的led_open函數(shù)
dev->fd = open(devpath, O_RDWR);
if (dev->fd == -1) {
free(dev);
LOGE("open device failed\n");
return -1;
}
//4.返回打開(kāi)的具體設(shè)備的描述結(jié)構(gòu)體指針
*device = &(dev->common);
return 0;
}
④led_on、led_off、led_close的實(shí)現(xiàn)
主要是調(diào)用了系統(tǒng)調(diào)用,通過(guò)系統(tǒng)調(diào)用將設(shè)備的信息傳遞給結(jié)構(gòu)體
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); //調(diào)用系統(tǒng)調(diào)用ioctl,ioctl回去通過(guò)linux內(nèi)核調(diào)用到驅(qū)動(dòng)中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);//調(diào)用系統(tǒng)調(diào)用close,close回去通過(guò)linux內(nèi)核調(diào)用到驅(qū)動(dòng)中l(wèi)ed_close
free(dev);
}
return 0;
}
lib中
使用hal提供的框架接口 hw_get_module();//獲取到對(duì)應(yīng)hal里模塊的結(jié)構(gòu)體地址
通過(guò)訪問(wèn)這個(gè)結(jié)構(gòu)體的methods里的led_open即可調(diào)用到底層的open
touch可以更新對(duì)應(yīng)的代碼時(shí)間戳,使編譯的時(shí)候重新編譯
整體一個(gè)流程:
①app上 通過(guò)led_open會(huì)調(diào)用coreLib庫(kù)
②庫(kù)中使用hal接口函數(shù)hw_get_module();
來(lái)通過(guò)LED_HARDWARE_MODULE_ID進(jìn)行獲取到對(duì)應(yīng)的模塊module,
③通過(guò)獲取模塊中的第一個(gè)成員hw_modules_t 中的mothods方法集合里面的open方法將對(duì)應(yīng)的模塊傳入進(jìn)入到hal中
④在hal中通過(guò)上面?zhèn)魅胂聛?lái)的name,將器設(shè)備路徑給獲取后,通過(guò)打開(kāi)設(shè)備驅(qū)動(dòng)的open函數(shù)即完成獲取,并且創(chuàng)建一個(gè)led_dev結(jié)構(gòu)體,通過(guò)結(jié)構(gòu)體進(jìn)行初始化,將其傳遞給在coreLib中的device對(duì)象,便于后續(xù)的操作使用,雖然傳遞過(guò)去的不是led_dev對(duì)應(yīng)的結(jié)構(gòu)體,但是由于hw_device_t與對(duì)應(yīng)結(jié)構(gòu)體的首地址一致,所以通過(guò)強(qiáng)轉(zhuǎn)即可獲取到led_dev對(duì)應(yīng)的方法
Android硬件抽象層框架代碼在 hardware目錄
Dalvik虛擬機(jī)作用:
①Dalvik基于虛擬機(jī),JVM基于棧,所以效率更高
②Dalvik可運(yùn)行壓縮過(guò),針對(duì)內(nèi)存優(yōu)化過(guò)的dex,減少文件尺寸,提高查找類的速度
③Dalvik每一個(gè)應(yīng)用程序運(yùn)行與一個(gè)獨(dú)立進(jìn)程
android系統(tǒng)中,使用 make ramdisk命令 只編譯文件系統(tǒng)
android系統(tǒng)app framework層,HAL層,core Libs 代碼編譯之后在system.img
通過(guò)GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V")找到對(duì)應(yīng)的方法應(yīng)該
①([Ljava/lang/String;)V") ===》 [ 數(shù)組 String =》tring 類型,參數(shù) V ===》void 返回值
②main為函數(shù)名 即可推出 void main (String [] )
init.rc包含5個(gè)部分
①import導(dǎo)入 ②commond命令 ③service服務(wù) ④action行為 ⑤option選項(xiàng)
簡(jiǎn)述linux內(nèi)核編譯步驟
①進(jìn)入lichee ./build.sh config //編譯選擇配置
②./build.sh 編譯內(nèi)核和uboot
簡(jiǎn)述android源碼的編譯步驟(以fspad-733配套androidL源碼為例)進(jìn)入androidL
①source build/envsetup.sh 添加配置調(diào)試命令到shell進(jìn)程
②lunch 選擇編譯的產(chǎn)品好
③extract-bsp 將內(nèi)核生成的bImage和模塊拷貝到androidL/device/softwinner/fspad-733/下
④make -j2 編譯
androidL ===>生成 system.img(非內(nèi)核部分) + ramdisk.img(rootfs) + recovery.img(恢復(fù)出廠鏡像)
lichee ===>生成 uboot.bin + uImage === > bImage
簡(jiǎn)單介紹一下Android系統(tǒng)中的HAL,并說(shuō)出舊HAL架構(gòu)libhardware_legacy和新HAL架構(gòu)libhardware的區(qū)別
①屏蔽下層硬件差異,為上層提供統(tǒng)一接口
②保護(hù)硬件的知識(shí)產(chǎn)權(quán)
③硬件設(shè)備不全都有l(wèi)inux kernel接口
舊的沒(méi)有經(jīng)過(guò)封裝,上層可以直接操走硬件
新的通過(guò)hal層將硬件分類,一個(gè)類一個(gè)stub,通過(guò)stub再進(jìn)行訪問(wèn)
請(qǐng)介紹Android系統(tǒng)架構(gòu),并簡(jiǎn)單說(shuō)明每層架構(gòu)的作用
①linux內(nèi)核 在內(nèi)核基礎(chǔ)上添加了android特有的驅(qū)動(dòng),binder驅(qū)動(dòng)(進(jìn)程間通訊)
②HAL 屏蔽下層差異,為上層提供統(tǒng)一接口
③核心庫(kù) libs 一些三方庫(kù)和c/c++庫(kù)的提供,
runtime Dalvik虛擬機(jī)和對(duì)應(yīng)的運(yùn)行環(huán)境
④app framework 讓?xiě)?yīng)用開(kāi)發(fā)更為方便
⑤app 一些與用戶進(jìn)行交互的程序
android源碼樹(shù)添加新產(chǎn)品目錄支持,必須有哪幾個(gè)文件?
①vendorsetup.sh 添加產(chǎn)品編譯的選項(xiàng)
②BoardConfig.mk 硬件方面定制
③AndroidProduct.mk 產(chǎn)品文件列表
④產(chǎn)品名.mk 定制軟件系統(tǒng)的配置
華清遠(yuǎn)見(jiàn)90+項(xiàng)目獲批!教育部2021最新協(xié)同育人項(xiàng)目名
華清遠(yuǎn)見(jiàn)榮獲2021騰訊教育“年度口碑影響力職業(yè)教育品
華清遠(yuǎn)見(jiàn)受邀參加2021年武漢民辦高校信息學(xué)科合作聯(lián)盟
溫暖同行共創(chuàng)佳績(jī) 2019華清遠(yuǎn)見(jiàn)北京總部年會(huì)大曝光
助力高校AI人工智能學(xué)科建設(shè) 華清遠(yuǎn)見(jiàn)人工智能師資班
華清遠(yuǎn)見(jiàn)受邀參加四川省物聯(lián)網(wǎng)年會(huì),榮獲優(yōu)秀企業(yè)專家
