ARM 的 resource 管理, 请赐教
本文是原「蜗窝讨论区」的历史存档(2016-07-08),来自版块「Linux kernel技术问答」,共 11 帖。讨论区已停止服务,此处仅供查阅。
谁对 resouce管理比较清楚,请赐教! 有相关的文章也欢迎分享!
- resource 在哪里定义, 特别是引入 Device Tree 以后, resource的定义是否由Device Tree定义。
- resource 是怎么管理的?根据设备管理(申请设备的时候访问该设备的resource)还是board(芯片自带) 管理?
;)
Q: First, source的定义在哪? A: include/linux/ioport.h / * Resources are tree-like, allowing * nesting etc.. / struct resource { resource_size_t start; resource_size_t end; const char name; unsigned long flags; struct resource parent, sibling, child; }; Q:Second,resource的种类主要有哪些? A: / * IO resources have these defined flags. /
define IORESOURCE_BITS 0x000000ff / Bus-specific bits /
define IORESOURCE_TYPE_BITS 0x00001f00 / Resource type /
define IORESOURCE_IO 0x00000100 / PCI/ISA I/O ports /
define IORESOURCE_MEM 0x00000200 //................................................frequently, 访问设备就是访问那片mem
define IORESOURCE_REG 0x00000300 / Register offsets /
define IORESOURCE_IRQ 0x00000400//.................................................so do it,peripheral用的难免需要个中断
define IORESOURCE_DMA 0x00000800
define IORESOURCE_BUS 0x00001000
Q:引入device tree以后,resource在哪定义? A:以前是定义静态数组的方式 but now,是定义在dts文件里的, for instant,
pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>;//对mem的描述 interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>; //对IRQ的描述 #gpio-cells = <2>; gpio-controller; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioAB_clk>; };
[== C++ ==]
Q:引入device tree以后,resource在哪定义?
A:以前是定义静态数组的方式
but now,是定义在dts文件里的,
for instant,
pioA: gpio@fffff400 {
compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
reg = <0xfffff400 0x200>;//对mem的描述
interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>; //对IRQ的描述
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&pioAB_clk>;
};
Q:怎么管理的?
A:
随便找出一个platform driver的probe函数,一般都会有类似的语句
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
a.走进去,看源码
/**
-
platform_get_resource - get a resource for a device
-
@dev: platform device
-
@type: resource type
-
@num: resource index
*/
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
{
int i;
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i];
if (type == resource_type(r) && num-- == 0)
return r;
}
return NULL;
}
DESC:只是一个for循环查找,比较resource type
b.so 在哪初始化的呢?猜,应该是在初始化的platform device的时候初始化的吧
c.在哪里初始化的呢?走起,看源码。
看这里:arch/arm/kernel/setup.c
static int __init customize_machine(void)
{
/*
* customizes platform devices, or adds new ones
* On DT based machines, we fall back to populating the
* machine from the device tree, if no callback is provided,
* otherwise we would always need an init_machine callback.
*/
//当然如果定义了init_machine 首先执行这个实现,一般实现里也会实现下面的of_platform_populate
//其实,真相就在这个函数里
if (machine_desc->init_machine)
machine_desc->init_machine(;
#ifdef CONFIG_OF
else //如果config_of后,可以走到else ,看到了of_platform_populate
of_platform_populate(NULL, of_default_bus_match_table,
NULL, NULL);
#endif
return 0;
}
arch_initcall(customize_machine);
还有这里:init/main.c
arch_initcall 定义的函数如何执行,需要到 do_basic_setup->do_initcalls里执行
at last,真相 /drivers/of/platforms.c of_platform_populate->of_platform_bus_create->of_platform_device_create_pdata->of_device_alloc
[== C++ ==]
struct platform_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent)
{
... ...
/* count the io and irq resources */
while (of_address_to_resource(np, num_reg, &temp_res) == 0)
num_reg++;
num_irq = of_irq_count(np);
... ...
dev->num_resources = num_reg + num_irq;
dev->resource = res;
for (i = 0; i < num_reg; i++, res++) {
rc = of_address_to_resource(np, i, res);
WARN_ON(rc);
}
if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
pr_debug("not all legacy IRQ resources mapped for %s\n",
np->name);
}
... ...
return dev;
}
EXPORT_SYMBOL(of_device_alloc);
解释的真清晰啊,赞!
相互学习
谢谢, 很详细! 受教了
另外, 还有一个比较具体的小问题困扰, 不知道有没有大神知道的。
关于device tree 的编译问题。
dtsi 里面已 label 的形式补充dts里面的note item 和value。 例如: A.dts 定义了 note1, B.dtsi 对 note1 进行补充
A.dts: { /{ .... note1{ item1 = <string>; }
}
}
B.dtsi: note1{ item2 = <string>; item3 = <srting>; }
现在的问题是, 我有没有办法在完全不修改 A.dts 的情况下(只修改B.dtsi) 把 item1 这个项从 note1 里面删除。
也就是note的合并有没有办法做替换 而不是做与操作。
dtsi并不对dts补充,相反,dts会覆盖dtsi中的相同内容。 你这种情况,noway~ 另外,你这个需求,本身也是不合理的。应该遵循这样的原则: dtsi抽象共性,dts抽象差异,因此要改也是改dts。
