編輯:關於Android編程
1.Device tree設備樹概述
設備樹包含DTC(device treecompiler),DTS(device treesource和DTB(device treeblob)。其對應關系如圖1-1所示:
圖1
DTS、DTC、DTB之間的關系
1.1 DTS和DTSI
.dts文件是一種ASCII文本對Device Tree的描述,放置在內核的/arch/arm/boot/dts目錄。一般而言,一個.dts文件對應一個ARM的machine。
由於一個SOC可能有多個不同的電路板,而每個電路板擁有一個 .dts。這些dts勢必會存在許多共同部分,為了減少代碼的冗余,設備樹將這些共同部分提煉保存在.dtsi文件中,供不同的dts共同使用。.dtsi的使用方法,類似於C語言的頭文件,在dts文件中需要進行include.dtsi文件。當然,dtsi本身也支持include 另一個dtsi文件。
1.2 DTC
DTC為編譯工具,它可以將.dts文件編譯成.dtb文件。DTC的源碼位於內核的scripts/dtc目錄,內核選中CONFIG_OF,編譯內核的時候,主機可執行程序DTC就會被編譯出來。即scripts/dtc/Makefile中
hostprogs-y := dtc always := $(hostprogs-y) This will tell kbuild to build lxdialogeven if not referenced in any rule.
在內核的arch/arm/boot/dts/Makefile中,若選中某種SOC,則與其對應相關的所有dtb文件都將編譯出來。在linux下,make dtbs可單獨編譯dtb。以下截取了qcom平台的一部分。
ifeq ($(CONFIG_OF),y) … #used for cleaning - not building subdir- := qcom endif qcom\Makefile ifeq ($(CONFIG_OF),y) dtb-$(CONFIG_ARCH_MSM8909) +=msm8909-sim.dtb \ msm8909-rumi.dtb\ msm8909-qrd-skua.dtb\ msm8909-qrd-skuc.dtb\ msm8909-qrd-skue.dtb\ msm8909-cdp.dtb\ msm8909-mtp.dtb\ msm8909-mtp-smb1360.dtb\ msm8909-pm8916-mtp-smb1360.dtb\ msm8909-512mb-mtp-smb1360.dtb\ msm8909-1gb-qrd-skua.dtb\ msm8909-1gb-qrd-skuc.dtb\ msm8909-1gb-qrd-skue.dtb\ msm8909-1gb-cdp.dtb\ msm8909-1gb-mtp.dtb\ msm8909-1gb-rcm.dtb\ msm8909-pm8916-1gb-rcm.dtb\ msm8909-pm8916-mtp.dtb\ msm8909-pm8916-cdp.dtb\ msm8909-qhd-cdp.dtb\ msm8909-qhd-rcm.dtb\ msm8909-pm8916-1gb-qhd-rcm.dtb\ msm8909-pm8916-qhd-rcm.dtb\ msm8208-cdp.dtb\ msm8208-mtp.dtb\ msm8208-1gb-cdp.dtb\ msm8208-1gb-mtp.dtb\ msm8208-qrd-skua.dtb\ msm8208-qrd-skuc.dtb\ msm8208-qrd-skue.dtb\ msm8208-1gb-qrd-skua.dtb\ msm8208-1gb-qrd-skuc.dtb\ msm8208-1gb-qrd-skue.dtb\ msm8208-1gb-rcm.dtb\ msm8208-qhd-cdp.dtb\ msm8208-qhd-rcm.dtb dtb-$(CONFIG_ARCH_MSM8909_PROJECTA) +=msm8909-1gb-qrd-skue-A.dtb dtb-$(CONFIG_ARCH_MSM8909_PROJECTB) +=msm8909-1gb-qrd-skue-B.dtb DTB_NAMES := $(subst$\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES)) ifneq ($(DTB_NAMES),) DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) else DTB_LIST := $(dtb-y) endif targets += dtbs targets += $(addprefix ../, $(DTB_LIST)) endif
上述.dtb都會由對應的.dts編譯出來,因為arch/arm/Makefile中含有一個dtbs編譯target項目
1.3 DTB
DTC編譯.dts生成的二進制文件(.dtb),bootloader在引導內核時,會預先讀取.dtb到內存,進而由內核解析。
1.4 Bootloader
Bootloader需要將設備樹在內存中的地址傳給內核。在ARM中通過bootm或bootz命令來進行傳遞。bootm [kernel_addr] [initrd_address] [dtb_address],其中kernel_addr為內核鏡像的地址,initrd為initrd的地址,dtb_address為dtb所在的地址。若initrd_address為空,則用“-”來代替。
2.Device tree設備樹文件的編譯生成
設備樹文件最後編譯生成dt.img
用"device/qcom/common/generate_extra_images.mk"中定義的下面規則編出"dt.img",
#---------------------------------------------------------------------- # Generate device tree image (dt.img) #---------------------------------------------------------------------- ifneq ($(strip $(TARGET_NO_KERNEL)),true) ifeq ($(strip $(BOARD_KERNEL_SEPARATED_DT)),true) ifeq ($(strip $(BUILD_TINY_ANDROID)),true) includedevice/qcom/common/dtbtool/Android.mk endif DTBTOOL :=$(HOST_OUT_EXECUTABLES)/dtbTool$(HOST_EXECUTABLE_SUFFIX) INSTALLED_DTIMAGE_TARGET :=$(PRODUCT_OUT)/dt.img possible_dtb_dirs =$(KERNEL_OUT)/arch/$(TARGET_KERNEL_ARCH)/boot/dts/$(KERNEL_OUT)/arch/arm/boot/dts/ $(KERNEL_OUT)/arch/arm/boot/ dtb_dir = $(firstword $(wildcard$(possible_dtb_dirs))) define build-dtimage-target $(call pretty,"Target dt image: $(INSTALLED_DTIMAGE_TARGET)") $(hide) $(DTBTOOL) -o $@ -s $(BOARD_KERNEL_PAGESIZE) -p$(KERNEL_OUT)/scripts/dtc/ $(dtb_dir) $(hide) chmod a+r $@ endef $(INSTALLED_DTIMAGE_TARGET): $(DTBTOOL)$(INSTALLED_KERNEL_TARGET) $(build-dtimage-target) ALL_DEFAULT_INSTALLED_MODULES +=$(INSTALLED_DTIMAGE_TARGET) ALL_MODULES.$(LOCAL_MODULE).INSTALLED +=$(INSTALLED_DTIMAGE_TARGET) endif endif
在"build/core/Makefile"中用下面語句使dt.img被編入boot.img。
INSTALLED_DTIMAGE_TARGET :=$(PRODUCT_OUT)/dt.img ifeq ($(strip$(BOARD_KERNEL_SEPARATED_DT)),true) INTERNAL_BOOTIMAGE_ARGS += --dt $(INSTALLED_DTIMAGE_TARGET) BOOTIMAGE_EXTRA_DEPS :=$(INSTALLED_DTIMAGE_TARGET) endif INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img BOARD_KERNEL_SEPARATED_DT在device/qcom/msm8909/BoardConfig.mk中定義: BOARD_KERNEL_SEPARATED_DT := true
3.Device tree設備樹文件組成
參考:msm8909+android5.1 boot.img解析
http://blog.csdn.net/loongembedded/article/details/52224099
device\qcom\common\dtbtool\dtbtool.txt
圖2
由此可知qcom增加的設備樹內防放在D)second stage (o pages)之後,dt.img=header+ device#1 entry+…+ device #z entry+其他
3.1Header
圖3
對應於bootable\bootloader\lk\platform\msm_shared\include\dev_tree.h下面的結構體
struct dt_table { uint32_tmagic; uint32_tversion; uint32_tnum_entries; };
3.2device #1 entry+…+ device #z entry
圖4
對應於bootable\bootloader\lk\platform\msm_shared\include\dev_tree.h下面的結構體
struct dt_entry { uint32_tplatform_id; uint32_tvariant_id; uint32_tboard_hw_subtype; uint32_tsoc_rev; uint32_tpmic_rev[4]; uint32_toffset; uint32_tsize; };
打開dt.img,下面只以第1個dt_entry來說明,這裡總共有0x81個。
圖5
先來看dtbtool.txt給出的相關解釋:
1) Each DTS per device will add a"qcom,msm-id" entry e.g. for msm8974-sim.dts, add qcom,msm-id =; or qcom,msm-id = ; qcom,board-id = ; qcom,pmic-id = ; x = ID for msm8974 y = ID for CDP, MTP, etc. y' = ID for subtype (assumed zero if absent) z = ID for soc revision a = pmic0 b = pmic1 c = pmic2 d = pmic3
Magic=“QCDT” Version=0x00000003 //version 3 num_entries=0x00000081表示number of DTB entries platform_id=0x000000F5//---x, uint32 (e.g. ID for MSM8909),MSM8909 = 245 variant_id=0x00000001//---y, uint32 (e.g. ID for CDP, MTP),這裡有多個值,比如1、8、F、0x10等。 board_hw_subtype=0x00000000//--- y' soc_rev=0x00000000//---z, ID for soc revision pmic_rev[0]=0x0001000D//pmic0 pmic_rev[1~3]都是0x00000000//pmic1、pmic2、pmic3,為0,表示沒有使用 offset=0x00001800 size=0x00026000 //來之msm8909.dtsi qcom,msm-id = <245 0>,//msm8909 <2580>,// MSM8209 <2650>,// APQ8009 <2750>;// MSM8609 //來之msm8909-sim.dts qcom,board-id= <16 0>;//y=16, y'=0 //來之msm8909-pm8909.dtsi qcom,pmic-id = <0x1000D 0x0 0x0 0x0>;
3.3其他部分
圖6
從圖4和圖5可知num of DTBs=0Xf5=129個,device #1 entry的offset=0x00001800,size=0x00026000,而前面128個entry占用4*10=40個字節,第129個占用4*9=36個字節(少了size),所以device #129 entry地址=12(magic+version+num_entries)+128*40+36=0x1430,
圖7
(1)0(“zero”)
DTB條目列表的結束分隔符,但這個在dt.img裡沒有找到,應該在圖7的0x1430地址處,但此地址的值卻是0x00025800,表示的是padding,是指#1 entry實際的大小,每個entry對應一個dtb文件。
(2)Padding
Variable(可變) lengthfor next DTB to start on page boundary,頁對齊(page=2048Bytes),不足補0。
(3)DTB #1
這是第1個entry的入口地址,這裡是0x00001800,再加上#1 entry的size=0x00026000,剛好是0x00027800
先給大家說下項目需求:TextView顯示一段文字,格式為:白雪公主(姓名,字數不確定)向您發來了2(消息個數,不確定)條消息這段文字中名字和數字的長度是不確定的,還要求
TabLayout的默認樣式: app:theme=@style/Widget.Design.TabLayout從系統定義的該樣式繼續深入: <style name
之前一直有猶豫過要不要寫這篇文章,畢竟去反編譯人家的程序並不是什麼值得驕傲的事情。不過單純從技術角度上來講,掌握反編譯功能確實是一項非常有用的技能,可能平常不太會用得到,
表情與鍵盤的切換輸入大部分IM都會需要到,之前自己實現了一個,還是存在些缺陷,比如說鍵盤與表情切換時出現跳閃問題,這個困擾了我些時間,不過所幸在Github(其代碼整體結