Linux dts知识

--v0.3.pdf
[ARM Linux 驱动开发] linux 设备树
函数详解
如dma
ti-processor-sdk-linux-j721s2-evm-08_06_00_10\board-support\linux-kernel\drivers\dma\ti\k3-udma.c
ret = of_dma_controller_register(dev->of_node, udma_of_xlate, ud);if (ret) {dev_err(dev, "failed to register of_dma controller\n");dma_async_device_unregister(&ud->ddev);}
调用流程
【Linux dts知识】struct dma_chan *dma_request_chan(struct device *dev, const char *name)
-》
chan = of_dma_request_slave_channel(dev->of_node, name);
-》
if (ofdma) {chan = ofdma->of_dma_xlate(&dma_spec, ofdma);} else {ret_no_channel = -EPROBE_DEFER;chan = NULL;}
初始化的地方
-》 ret = (dev->, , ud);
static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec,struct of_dma *ofdma){struct udma_dev *ud = ofdma->of_dma_data;dma_cap_mask_t mask = ud->ddev.cap_mask;struct udma_filter_param filter_param;struct dma_chan *chan;if (ud->match_data->type == DMA_TYPE_BCDMA) {if (dma_spec->args_count != 3)return NULL;filter_param.tr_trigger_type = dma_spec->args[0];filter_param.remote_thread_id = dma_spec->args[1];filter_param.asel = dma_spec->args[2];filter_param.atype = 0;} else {if (dma_spec->args_count != 1 && dma_spec->args_count != 2)return NULL;filter_param.remote_thread_id = dma_spec->args[0];filter_param.tr_trigger_type = 0;if (dma_spec->args_count == 2) {if (ud->match_data->type == DMA_TYPE_UDMA) {filter_param.atype = dma_spec->args[1];filter_param.asel = 0;} else {filter_param.atype = 0;filter_param.asel = dma_spec->args[1];}} else {filter_param.atype = 0;filter_param.asel = 0;}}chan = __dma_request_channel(&mask, udma_dma_filter_fn, &filter_param,ofdma->of_node);if (!chan) {dev_err(ud->dev, "get channel fail in %s.\n", __func__);return ERR_PTR(-EINVAL);}return chan;}
filter_param.remote_thread_id = dma_spec->args[0];
dmas = <&main_udmap 0xc640>,
0xc640代表的是remote_thread_id
其他模块的实现可以搜索或xlate关键字找到
结合设备信息集合,探究设备和驱动是如何绑定的
支持条件编译
reg 寄存器
反汇编
dtc -I dtb -O dts -o out.dts …/…/arch/arm/boot/dts/qcom/-1gb-qrd-skue.dtb
dtc -I dtb -O dts -o out.dts …/…/arch/arm/boot/dts/qcom/-1gb-mtp.dtb
dts:
@{
两个节点名字可以一样,但是里面的 不能一样
节点上的地址只是设备节点本身的地址,并不是cpu的可用地址,即
非根节点上的子节点的使用的不是cpu的地址域,为了得到一个内存映射地址,设备树必须要指定一个域转换另外一个域的方法,这里用range
range是地址转换的列表,i2c总线下的设备里,缺少range属性,表示此设备不能被此设备的父设备的其他设备访问
根节点始终描述的是 cpu的地址空间
根节点下的子节点已经使用的是 cpu的地址域,所以不需要任何直接映射
#-cells=;
#size-cells=;
@0.0{
reg=
地址有两个cell,其中一个是片选,另一个是片选基地址,即编移是,第三个是大小
必须要了解的知识:
在启动过程中传参:
R0:cp#15
R1 : ID
R2:atags or -->传到内核(lk加载dtb到内存的物理地址)
R3: ID即进程ID
pbl->sbl1->lk->-
中:
->->->
->检测DTB头部
编译
make

make -C /msm-3.18 O=…/…/out////obj//msm-3.18 ARCH=arm =arm-none--