最近跟研究了Device Tree這東西 , 挺有意思的 , 有時間來寫系列文章(哈) , 目前暫先簡單筆記一下心得 ^^
==========================================================================
在Linux 2.6以前 , 很多ARM base開發版上的Device Driver都用Hard Code方式直接寫到Kernel裡 ,
所以Linux Kernel漸漸地像個胖子 , 又肥又腫.
2011年後 , Device Tree採用 , 許多ARM base開發版上的Device Driver可以透過Device Tree傳遞給Linux Kernel ,
增加可移植性與幫Linux Kernel減肥 ~
DTS (device tree source)
.dts採ASCII格式 , 非常人性化 , 適合直接閱讀
DTC (device tree compiler)
將.dts編譯為.dtb的工具
DTB (device Tree Blob)
給Linux Kernel看的machine code.
make dtbs可生成.dtb檔
Bootloader將帶起Kernel的過程 , 需要將.dtb放到memory , 並在bootcmd裡面宣告.dtb位址讓Kernel知道
==========================================================================
What I say in next is very important .....(抄襲某電影 XD)
有了Device Tree這個東東後 :
(1) 不需要在Kernel裡註冊Platform Device, 宣告IO resource, IRQ, GPIO Pins
這些資料直接宣告在dts裡面 , 然後利用dtc編譯成dtb , Kernel會自己解析超展開~~
(2) Platform Driver裡要增加MODULE_DEVICE_TABLE
下面是一個簡單的範例
static const struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", .data = (void *)ARM_SMMU_V1 }, { .compatible = "arm,smmu-v2", .data = (void *)ARM_SMMU_V2 }, { .compatible = "arm,mmu-400", .data = (void *)ARM_SMMU_V1 }, { .compatible = "arm,mmu-401", .data = (void *)ARM_SMMU_V1 }, { .compatible = "arm,mmu-500", .data = (void *)ARM_SMMU_V2 }, { }, }; MODULE_DEVICE_TABLE(of, arm_smmu_of_match); static int arm_smmu_device_dt_probe(struct platform_device *pdev) { const struct of_device_id *of_id; of_id = of_match_node(arm_smmu_of_match, dev->of_node); smmu->version = (enum arm_smmu_arch_version)of_id->data; ... if (smmu->version > ARM_SMMU_V1) { ... } } static struct platform_driver arm_smmu_driver = { .driver = { .name = "arm-smmu", .of_match_table = of_match_ptr(arm_smmu_of_match), }, .probe = arm_smmu_device_dt_probe, .remove = arm_smmu_device_remove, };
留言列表